linux/drivers/s390/block/dasd_int.h
<<
>>
Prefs
   1/*
   2 * File...........: linux/drivers/s390/block/dasd_int.h
   3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
   4 *                  Horst Hummel <Horst.Hummel@de.ibm.com>
   5 *                  Martin Schwidefsky <schwidefsky@de.ibm.com>
   6 * Bugreports.to..: <Linux390@de.ibm.com>
   7 * Copyright IBM Corp. 1999, 2009
   8 */
   9
  10#ifndef DASD_INT_H
  11#define DASD_INT_H
  12
  13#ifdef __KERNEL__
  14
  15/* we keep old device allocation scheme; IOW, minors are still in 0..255 */
  16#define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS))
  17#define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
  18
  19/*
  20 * States a dasd device can have:
  21 *   new: the dasd_device structure is allocated.
  22 *   known: the discipline for the device is identified.
  23 *   basic: the device can do basic i/o.
  24 *   unfmt: the device could not be analyzed (format is unknown).
  25 *   ready: partition detection is done and the device is can do block io.
  26 *   online: the device accepts requests from the block device queue.
  27 *
  28 * Things to do for startup state transitions:
  29 *   new -> known: find discipline for the device and create devfs entries.
  30 *   known -> basic: request irq line for the device.
  31 *   basic -> ready: do the initial analysis, e.g. format detection,
  32 *                   do block device setup and detect partitions.
  33 *   ready -> online: schedule the device tasklet.
  34 * Things to do for shutdown state transitions:
  35 *   online -> ready: just set the new device state.
  36 *   ready -> basic: flush requests from the block device layer, clear
  37 *                   partition information and reset format information.
  38 *   basic -> known: terminate all requests and free irq.
  39 *   known -> new: remove devfs entries and forget discipline.
  40 */
  41
  42#define DASD_STATE_NEW    0
  43#define DASD_STATE_KNOWN  1
  44#define DASD_STATE_BASIC  2
  45#define DASD_STATE_UNFMT  3
  46#define DASD_STATE_READY  4
  47#define DASD_STATE_ONLINE 5
  48
  49#include <linux/module.h>
  50#include <linux/wait.h>
  51#include <linux/blkdev.h>
  52#include <linux/genhd.h>
  53#include <linux/hdreg.h>
  54#include <linux/interrupt.h>
  55#include <linux/log2.h>
  56#include <asm/ccwdev.h>
  57#include <linux/workqueue.h>
  58#include <asm/debug.h>
  59#include <asm/dasd.h>
  60#include <asm/idals.h>
  61
  62/* DASD discipline magic */
  63#define DASD_ECKD_MAGIC 0xC5C3D2C4
  64#define DASD_DIAG_MAGIC 0xC4C9C1C7
  65#define DASD_FBA_MAGIC 0xC6C2C140
  66
  67/*
  68 * SECTION: Type definitions
  69 */
  70struct dasd_device;
  71struct dasd_block;
  72
  73/* BIT DEFINITIONS FOR SENSE DATA */
  74#define DASD_SENSE_BIT_0 0x80
  75#define DASD_SENSE_BIT_1 0x40
  76#define DASD_SENSE_BIT_2 0x20
  77#define DASD_SENSE_BIT_3 0x10
  78
  79/* BIT DEFINITIONS FOR SIM SENSE */
  80#define DASD_SIM_SENSE 0x0F
  81#define DASD_SIM_MSG_TO_OP 0x03
  82#define DASD_SIM_LOG 0x0C
  83
  84/*
  85 * SECTION: MACROs for klogd and s390 debug feature (dbf)
  86 */
  87#define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \
  88do { \
  89        debug_sprintf_event(d_device->debug_area, \
  90                            d_level, \
  91                            d_str "\n", \
  92                            d_data); \
  93} while(0)
  94
  95#define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \
  96do { \
  97        debug_sprintf_exception(d_device->debug_area, \
  98                                d_level, \
  99                                d_str "\n", \
 100                                d_data); \
 101} while(0)
 102
 103#define DBF_EVENT(d_level, d_str, d_data...)\
 104do { \
 105        debug_sprintf_event(dasd_debug_area, \
 106                            d_level,\
 107                            d_str "\n", \
 108                            d_data); \
 109} while(0)
 110
 111#define DBF_EXC(d_level, d_str, d_data...)\
 112do { \
 113        debug_sprintf_exception(dasd_debug_area, \
 114                                d_level,\
 115                                d_str "\n", \
 116                                d_data); \
 117} while(0)
 118
 119/* limit size for an errorstring */
 120#define ERRORLENGTH 30
 121
 122/* definition of dbf debug levels */
 123#define DBF_EMERG       0       /* system is unusable                   */
 124#define DBF_ALERT       1       /* action must be taken immediately     */
 125#define DBF_CRIT        2       /* critical conditions                  */
 126#define DBF_ERR         3       /* error conditions                     */
 127#define DBF_WARNING     4       /* warning conditions                   */
 128#define DBF_NOTICE      5       /* normal but significant condition     */
 129#define DBF_INFO        6       /* informational                        */
 130#define DBF_DEBUG       6       /* debug-level messages                 */
 131
 132/* messages to be written via klogd and dbf */
 133#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
 134do { \
 135        printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
 136               dev_name(&d_device->cdev->dev), d_args); \
 137        DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \
 138} while(0)
 139
 140#define MESSAGE(d_loglevel,d_string,d_args...)\
 141do { \
 142        printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
 143        DBF_EVENT(DBF_ALERT, d_string, d_args); \
 144} while(0)
 145
 146/* messages to be written via klogd only */
 147#define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\
 148do { \
 149        printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
 150               dev_name(&d_device->cdev->dev), d_args); \
 151} while(0)
 152
 153#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\
 154do { \
 155        printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
 156} while(0)
 157
 158struct dasd_ccw_req {
 159        unsigned int magic;             /* Eye catcher */
 160        struct list_head devlist;       /* for dasd_device request queue */
 161        struct list_head blocklist;     /* for dasd_block request queue */
 162
 163        /* Where to execute what... */
 164        struct dasd_block *block;       /* the originating block device */
 165        struct dasd_device *memdev;     /* the device used to allocate this */
 166        struct dasd_device *startdev;   /* device the request is started on */
 167        void *cpaddr;                   /* address of ccw or tcw */
 168        unsigned char cpmode;           /* 0 = cmd mode, 1 = itcw */
 169        char status;                    /* status of this request */
 170        short retries;                  /* A retry counter */
 171        unsigned long flags;            /* flags of this request */
 172
 173        /* ... and how */
 174        unsigned long starttime;        /* jiffies time of request start */
 175        int expires;                    /* expiration period in jiffies */
 176        char lpm;                       /* logical path mask */
 177        void *data;                     /* pointer to data area */
 178
 179        /* these are important for recovering erroneous requests          */
 180        int intrc;                      /* internal error, e.g. from start_IO */
 181        struct irb irb;                 /* device status in case of an error */
 182        struct dasd_ccw_req *refers;    /* ERP-chain queueing. */
 183        void *function;                 /* originating ERP action */
 184
 185        /* these are for statistics only */
 186        unsigned long long buildclk;    /* TOD-clock of request generation */
 187        unsigned long long startclk;    /* TOD-clock of request start */
 188        unsigned long long stopclk;     /* TOD-clock of request interrupt */
 189        unsigned long long endclk;      /* TOD-clock of request termination */
 190
 191        /* Callback that is called after reaching final status. */
 192        void (*callback)(struct dasd_ccw_req *, void *data);
 193        void *callback_data;
 194};
 195
 196/*
 197 * dasd_ccw_req -> status can be:
 198 */
 199#define DASD_CQR_FILLED         0x00    /* request is ready to be processed */
 200#define DASD_CQR_DONE           0x01    /* request is completed successfully */
 201#define DASD_CQR_NEED_ERP       0x02    /* request needs recovery action */
 202#define DASD_CQR_IN_ERP         0x03    /* request is in recovery */
 203#define DASD_CQR_FAILED         0x04    /* request is finally failed */
 204#define DASD_CQR_TERMINATED     0x05    /* request was stopped by driver */
 205
 206#define DASD_CQR_QUEUED         0x80    /* request is queued to be processed */
 207#define DASD_CQR_IN_IO          0x81    /* request is currently in IO */
 208#define DASD_CQR_ERROR          0x82    /* request is completed with error */
 209#define DASD_CQR_CLEAR_PENDING  0x83    /* request is clear pending */
 210#define DASD_CQR_CLEARED        0x84    /* request was cleared */
 211#define DASD_CQR_SUCCESS        0x85    /* request was successful */
 212
 213
 214/* per dasd_ccw_req flags */
 215#define DASD_CQR_FLAGS_USE_ERP   0      /* use ERP for this request */
 216#define DASD_CQR_FLAGS_FAILFAST  1      /* FAILFAST */
 217
 218/* Signature for error recovery functions. */
 219typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
 220
 221/*
 222 * the struct dasd_discipline is
 223 * sth like a table of virtual functions, if you think of dasd_eckd
 224 * inheriting dasd...
 225 * no, currently we are not planning to reimplement the driver in C++
 226 */
 227struct dasd_discipline {
 228        struct module *owner;
 229        char ebcname[8];        /* a name used for tagging and printks */
 230        char name[8];           /* a name used for tagging and printks */
 231        int max_blocks;         /* maximum number of blocks to be chained */
 232
 233        struct list_head list;  /* used for list of disciplines */
 234
 235        /*
 236         * Device recognition functions. check_device is used to verify
 237         * the sense data and the information returned by read device
 238         * characteristics. It returns 0 if the discipline can be used
 239         * for the device in question. uncheck_device is called during
 240         * device shutdown to deregister a device from its discipline.
 241         */
 242        int (*check_device) (struct dasd_device *);
 243        void (*uncheck_device) (struct dasd_device *);
 244
 245        /*
 246         * do_analysis is used in the step from device state "basic" to
 247         * state "accept". It returns 0 if the device can be made ready,
 248         * it returns -EMEDIUMTYPE if the device can't be made ready or
 249         * -EAGAIN if do_analysis started a ccw that needs to complete
 250         * before the analysis may be repeated.
 251         */
 252        int (*do_analysis) (struct dasd_block *);
 253
 254        /*
 255         * Last things to do when a device is set online, and first things
 256         * when it is set offline.
 257         */
 258        int (*ready_to_online) (struct dasd_device *);
 259        int (*online_to_ready) (struct dasd_device *);
 260
 261        /*
 262         * Device operation functions. build_cp creates a ccw chain for
 263         * a block device request, start_io starts the request and
 264         * term_IO cancels it (e.g. in case of a timeout). format_device
 265         * returns a ccw chain to be used to format the device.
 266         * handle_terminated_request allows to examine a cqr and prepare
 267         * it for retry.
 268         */
 269        struct dasd_ccw_req *(*build_cp) (struct dasd_device *,
 270                                          struct dasd_block *,
 271                                          struct request *);
 272        int (*start_IO) (struct dasd_ccw_req *);
 273        int (*term_IO) (struct dasd_ccw_req *);
 274        void (*handle_terminated_request) (struct dasd_ccw_req *);
 275        struct dasd_ccw_req *(*format_device) (struct dasd_device *,
 276                                               struct format_data_t *);
 277        int (*free_cp) (struct dasd_ccw_req *, struct request *);
 278
 279        /*
 280         * Error recovery functions. examine_error() returns a value that
 281         * indicates what to do for an error condition. If examine_error()
 282         * returns 'dasd_era_recover' erp_action() is called to create a
 283         * special error recovery ccw. erp_postaction() is called after
 284         * an error recovery ccw has finished its execution. dump_sense
 285         * is called for every error condition to print the sense data
 286         * to the console.
 287         */
 288        dasd_erp_fn_t(*erp_action) (struct dasd_ccw_req *);
 289        dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
 290        void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
 291                            struct irb *);
 292        void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);
 293
 294        void (*handle_unsolicited_interrupt) (struct dasd_device *,
 295                                              struct irb *);
 296
 297        /* i/o control functions. */
 298        int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
 299        int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
 300        int (*ioctl) (struct dasd_block *, unsigned int, void __user *);
 301
 302        /* suspend/resume functions */
 303        int (*freeze) (struct dasd_device *);
 304        int (*restore) (struct dasd_device *);
 305};
 306
 307extern struct dasd_discipline *dasd_diag_discipline_pointer;
 308
 309/*
 310 * Unique identifier for dasd device.
 311 */
 312#define UA_NOT_CONFIGURED  0x00
 313#define UA_BASE_DEVICE     0x01
 314#define UA_BASE_PAV_ALIAS  0x02
 315#define UA_HYPER_PAV_ALIAS 0x03
 316
 317struct dasd_uid {
 318        __u8 type;
 319        char vendor[4];
 320        char serial[15];
 321        __u16 ssid;
 322        __u8 real_unit_addr;
 323        __u8 base_unit_addr;
 324        char vduit[33];
 325};
 326
 327/*
 328 * Notification numbers for extended error reporting notifications:
 329 * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's
 330 * eer pointer) is freed. The error reporting module needs to do all necessary
 331 * cleanup steps.
 332 * The DASD_EER_TRIGGER notification sends the actual error reports (triggers).
 333 */
 334#define DASD_EER_DISABLE 0
 335#define DASD_EER_TRIGGER 1
 336
 337/* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */
 338#define DASD_EER_FATALERROR  1
 339#define DASD_EER_NOPATH      2
 340#define DASD_EER_STATECHANGE 3
 341#define DASD_EER_PPRCSUSPEND 4
 342
 343struct dasd_device {
 344        /* Block device stuff. */
 345        struct dasd_block *block;
 346
 347        unsigned int devindex;
 348        unsigned long flags;       /* per device flags */
 349        unsigned short features;   /* copy of devmap-features (read-only!) */
 350
 351        /* extended error reporting stuff (eer) */
 352        struct dasd_ccw_req *eer_cqr;
 353
 354        /* Device discipline stuff. */
 355        struct dasd_discipline *discipline;
 356        struct dasd_discipline *base_discipline;
 357        char *private;
 358
 359        /* Device state and target state. */
 360        int state, target;
 361        int stopped;            /* device (ccw_device_start) was stopped */
 362
 363        /* reference count. */
 364        atomic_t ref_count;
 365
 366        /* ccw queue and memory for static ccw/erp buffers. */
 367        struct list_head ccw_queue;
 368        spinlock_t mem_lock;
 369        void *ccw_mem;
 370        void *erp_mem;
 371        struct list_head ccw_chunks;
 372        struct list_head erp_chunks;
 373
 374        atomic_t tasklet_scheduled;
 375        struct tasklet_struct tasklet;
 376        struct work_struct kick_work;
 377        struct work_struct restore_device;
 378        struct timer_list timer;
 379
 380        debug_info_t *debug_area;
 381
 382        struct ccw_device *cdev;
 383
 384        /* hook for alias management */
 385        struct list_head alias_list;
 386};
 387
 388struct dasd_block {
 389        /* Block device stuff. */
 390        struct gendisk *gdp;
 391        struct request_queue *request_queue;
 392        spinlock_t request_queue_lock;
 393        struct block_device *bdev;
 394        atomic_t open_count;
 395
 396        unsigned long long blocks; /* size of volume in blocks */
 397        unsigned int bp_block;     /* bytes per block */
 398        unsigned int s2b_shift;    /* log2 (bp_block/512) */
 399
 400        struct dasd_device *base;
 401        struct list_head ccw_queue;
 402        spinlock_t queue_lock;
 403
 404        atomic_t tasklet_scheduled;
 405        struct tasklet_struct tasklet;
 406        struct timer_list timer;
 407
 408#ifdef CONFIG_DASD_PROFILE
 409        struct dasd_profile_info_t profile;
 410#endif
 411};
 412
 413
 414
 415/* reasons why device (ccw_device_start) was stopped */
 416#define DASD_STOPPED_NOT_ACC 1         /* not accessible */
 417#define DASD_STOPPED_QUIESCE 2         /* Quiesced */
 418#define DASD_STOPPED_PENDING 4         /* long busy */
 419#define DASD_STOPPED_DC_WAIT 8         /* disconnected, wait */
 420#define DASD_STOPPED_SU      16        /* summary unit check handling */
 421#define DASD_STOPPED_PM      32        /* pm state transition */
 422#define DASD_UNRESUMED_PM    64        /* pm resume failed state */
 423
 424/* per device flags */
 425#define DASD_FLAG_OFFLINE       3       /* device is in offline processing */
 426#define DASD_FLAG_EER_SNSS      4       /* A SNSS is required */
 427#define DASD_FLAG_EER_IN_USE    5       /* A SNSS request is running */
 428
 429void dasd_put_device_wake(struct dasd_device *);
 430
 431/*
 432 * Reference count inliners
 433 */
 434static inline void
 435dasd_get_device(struct dasd_device *device)
 436{
 437        atomic_inc(&device->ref_count);
 438}
 439
 440static inline void
 441dasd_put_device(struct dasd_device *device)
 442{
 443        if (atomic_dec_return(&device->ref_count) == 0)
 444                dasd_put_device_wake(device);
 445}
 446
 447/*
 448 * The static memory in ccw_mem and erp_mem is managed by a sorted
 449 * list of free memory chunks.
 450 */
 451struct dasd_mchunk
 452{
 453        struct list_head list;
 454        unsigned long size;
 455} __attribute__ ((aligned(8)));
 456
 457static inline void
 458dasd_init_chunklist(struct list_head *chunk_list, void *mem,
 459                    unsigned long size)
 460{
 461        struct dasd_mchunk *chunk;
 462
 463        INIT_LIST_HEAD(chunk_list);
 464        chunk = (struct dasd_mchunk *) mem;
 465        chunk->size = size - sizeof(struct dasd_mchunk);
 466        list_add(&chunk->list, chunk_list);
 467}
 468
 469static inline void *
 470dasd_alloc_chunk(struct list_head *chunk_list, unsigned long size)
 471{
 472        struct dasd_mchunk *chunk, *tmp;
 473
 474        size = (size + 7L) & -8L;
 475        list_for_each_entry(chunk, chunk_list, list) {
 476                if (chunk->size < size)
 477                        continue;
 478                if (chunk->size > size + sizeof(struct dasd_mchunk)) {
 479                        char *endaddr = (char *) (chunk + 1) + chunk->size;
 480                        tmp = (struct dasd_mchunk *) (endaddr - size) - 1;
 481                        tmp->size = size;
 482                        chunk->size -= size + sizeof(struct dasd_mchunk);
 483                        chunk = tmp;
 484                } else
 485                        list_del(&chunk->list);
 486                return (void *) (chunk + 1);
 487        }
 488        return NULL;
 489}
 490
 491static inline void
 492dasd_free_chunk(struct list_head *chunk_list, void *mem)
 493{
 494        struct dasd_mchunk *chunk, *tmp;
 495        struct list_head *p, *left;
 496
 497        chunk = (struct dasd_mchunk *)
 498                ((char *) mem - sizeof(struct dasd_mchunk));
 499        /* Find out the left neighbour in chunk_list. */
 500        left = chunk_list;
 501        list_for_each(p, chunk_list) {
 502                if (list_entry(p, struct dasd_mchunk, list) > chunk)
 503                        break;
 504                left = p;
 505        }
 506        /* Try to merge with right neighbour = next element from left. */
 507        if (left->next != chunk_list) {
 508                tmp = list_entry(left->next, struct dasd_mchunk, list);
 509                if ((char *) (chunk + 1) + chunk->size == (char *) tmp) {
 510                        list_del(&tmp->list);
 511                        chunk->size += tmp->size + sizeof(struct dasd_mchunk);
 512                }
 513        }
 514        /* Try to merge with left neighbour. */
 515        if (left != chunk_list) {
 516                tmp = list_entry(left, struct dasd_mchunk, list);
 517                if ((char *) (tmp + 1) + tmp->size == (char *) chunk) {
 518                        tmp->size += chunk->size + sizeof(struct dasd_mchunk);
 519                        return;
 520                }
 521        }
 522        __list_add(&chunk->list, left, left->next);
 523}
 524
 525/*
 526 * Check if bsize is in { 512, 1024, 2048, 4096 }
 527 */
 528static inline int
 529dasd_check_blocksize(int bsize)
 530{
 531        if (bsize < 512 || bsize > 4096 || !is_power_of_2(bsize))
 532                return -EMEDIUMTYPE;
 533        return 0;
 534}
 535
 536/* externals in dasd.c */
 537#define DASD_PROFILE_ON  1
 538#define DASD_PROFILE_OFF 0
 539
 540extern debug_info_t *dasd_debug_area;
 541extern struct dasd_profile_info_t dasd_global_profile;
 542extern unsigned int dasd_profile_level;
 543extern const struct block_device_operations dasd_device_operations;
 544
 545extern struct kmem_cache *dasd_page_cache;
 546
 547struct dasd_ccw_req *
 548dasd_kmalloc_request(int , int, int, struct dasd_device *);
 549struct dasd_ccw_req *
 550dasd_smalloc_request(int , int, int, struct dasd_device *);
 551void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *);
 552void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *);
 553
 554static inline int
 555dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device)
 556{
 557        return set_normalized_cda(ccw, cda);
 558}
 559
 560struct dasd_device *dasd_alloc_device(void);
 561void dasd_free_device(struct dasd_device *);
 562
 563struct dasd_block *dasd_alloc_block(void);
 564void dasd_free_block(struct dasd_block *);
 565
 566void dasd_enable_device(struct dasd_device *);
 567void dasd_set_target_state(struct dasd_device *, int);
 568void dasd_kick_device(struct dasd_device *);
 569void dasd_restore_device(struct dasd_device *);
 570
 571void dasd_add_request_head(struct dasd_ccw_req *);
 572void dasd_add_request_tail(struct dasd_ccw_req *);
 573int  dasd_start_IO(struct dasd_ccw_req *);
 574int  dasd_term_IO(struct dasd_ccw_req *);
 575void dasd_schedule_device_bh(struct dasd_device *);
 576void dasd_schedule_block_bh(struct dasd_block *);
 577int  dasd_sleep_on(struct dasd_ccw_req *);
 578int  dasd_sleep_on_immediatly(struct dasd_ccw_req *);
 579int  dasd_sleep_on_interruptible(struct dasd_ccw_req *);
 580void dasd_device_set_timer(struct dasd_device *, int);
 581void dasd_device_clear_timer(struct dasd_device *);
 582void dasd_block_set_timer(struct dasd_block *, int);
 583void dasd_block_clear_timer(struct dasd_block *);
 584int  dasd_cancel_req(struct dasd_ccw_req *);
 585int dasd_flush_device_queue(struct dasd_device *);
 586int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *);
 587void dasd_generic_remove (struct ccw_device *cdev);
 588int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
 589int dasd_generic_set_offline (struct ccw_device *cdev);
 590int dasd_generic_notify(struct ccw_device *, int);
 591void dasd_generic_handle_state_change(struct dasd_device *);
 592int dasd_generic_pm_freeze(struct ccw_device *);
 593int dasd_generic_restore_device(struct ccw_device *);
 594
 595int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
 596char *dasd_get_sense(struct irb *);
 597
 598/* externals in dasd_devmap.c */
 599extern int dasd_max_devindex;
 600extern int dasd_probeonly;
 601extern int dasd_autodetect;
 602extern int dasd_nopav;
 603extern int dasd_nofcx;
 604
 605int dasd_devmap_init(void);
 606void dasd_devmap_exit(void);
 607
 608struct dasd_device *dasd_create_device(struct ccw_device *);
 609void dasd_delete_device(struct dasd_device *);
 610
 611int dasd_get_uid(struct ccw_device *, struct dasd_uid *);
 612int dasd_set_uid(struct ccw_device *, struct dasd_uid *);
 613int dasd_get_feature(struct ccw_device *, int);
 614int dasd_set_feature(struct ccw_device *, int, int);
 615
 616int dasd_add_sysfs_files(struct ccw_device *);
 617void dasd_remove_sysfs_files(struct ccw_device *);
 618
 619struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
 620struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
 621struct dasd_device *dasd_device_from_devindex(int);
 622
 623int dasd_parse(void);
 624int dasd_busid_known(const char *);
 625
 626/* externals in dasd_gendisk.c */
 627int  dasd_gendisk_init(void);
 628void dasd_gendisk_exit(void);
 629int dasd_gendisk_alloc(struct dasd_block *);
 630void dasd_gendisk_free(struct dasd_block *);
 631int dasd_scan_partitions(struct dasd_block *);
 632void dasd_destroy_partitions(struct dasd_block *);
 633
 634/* externals in dasd_ioctl.c */
 635int  dasd_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long);
 636
 637/* externals in dasd_proc.c */
 638int dasd_proc_init(void);
 639void dasd_proc_exit(void);
 640
 641/* externals in dasd_erp.c */
 642struct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *);
 643struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *);
 644struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
 645                                            struct dasd_device *);
 646void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
 647void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
 648void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
 649
 650/* externals in dasd_3990_erp.c */
 651struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
 652void dasd_3990_erp_handle_sim(struct dasd_device *, char *);
 653
 654/* externals in dasd_eer.c */
 655#ifdef CONFIG_DASD_EER
 656int dasd_eer_init(void);
 657void dasd_eer_exit(void);
 658int dasd_eer_enable(struct dasd_device *);
 659void dasd_eer_disable(struct dasd_device *);
 660void dasd_eer_write(struct dasd_device *, struct dasd_ccw_req *cqr,
 661                    unsigned int id);
 662void dasd_eer_snss(struct dasd_device *);
 663
 664static inline int dasd_eer_enabled(struct dasd_device *device)
 665{
 666        return device->eer_cqr != NULL;
 667}
 668#else
 669#define dasd_eer_init()         (0)
 670#define dasd_eer_exit()         do { } while (0)
 671#define dasd_eer_enable(d)      (0)
 672#define dasd_eer_disable(d)     do { } while (0)
 673#define dasd_eer_write(d,c,i)   do { } while (0)
 674#define dasd_eer_snss(d)        do { } while (0)
 675#define dasd_eer_enabled(d)     (0)
 676#endif  /* CONFIG_DASD_ERR */
 677
 678#endif                          /* __KERNEL__ */
 679
 680#endif                          /* DASD_H */
 681