OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [s390/] [block/] [dasd_int.h] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 * Bugreports.to..: <Linux390@de.ibm.com>
6
 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7
 *
8
 * $Revision: 1.1.1.1 $
9
 *
10
 * History of changes (starts July 2000)
11
 * 02/01/01 added dynamic registration of ioctls
12
 */
13
 
14
#ifndef DASD_INT_H
15
#define DASD_INT_H
16
 
17
#include <asm/dasd.h>
18
 
19
#define CONFIG_DASD_DYNAMIC
20
 
21
typedef int(*dasd_ioctl_fn_t) (void *inp, int no, long args);
22
int dasd_ioctl_no_register(struct module *, int no, dasd_ioctl_fn_t handler);
23
int dasd_ioctl_no_unregister(struct module *, int no, dasd_ioctl_fn_t handler);
24
 
25
#define DASD_NAME "dasd"
26
#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
27
 
28
 
29
#define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
30
#define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
31
 
32
#define DASD_STATE_DEL   -1     /* "unknown" */
33
#define DASD_STATE_NEW    0     /* memory for dasd_device_t and lowmem ccw/idals allocated */  
34
#define DASD_STATE_BOXED  1     /* boxed dasd could not be analysed "plugged" */
35
#define DASD_STATE_KNOWN  2     /* major_info/devinfo/discipline/devfs-'device'/gendisk - "detected" */
36
#define DASD_STATE_ACCEPT 3     /* irq requested - "accepted" */
37
#define DASD_STATE_INIT   4     /* init_cqr started - "busy" */
38
#define DASD_STATE_READY  5     /* init finished  - "fenced(plugged)" */
39
#define DASD_STATE_ONLINE 6     /* unplugged "active" */
40
 
41
#define DASD_HOTPLUG_EVENT_ADD        0
42
#define DASD_HOTPLUG_EVENT_REMOVE     1
43
#define DASD_HOTPLUG_EVENT_PARTCHK    2
44
#define DASD_HOTPLUG_EVENT_PARTREMOVE 3
45
 
46
#define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
47
#define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
48
#define DASD_FORMAT_INTENS_INVALIDATE    0x04
49
#define DASD_FORMAT_INTENS_CDL 0x08
50
#ifdef __KERNEL__
51
#include <linux/module.h>
52
#include <linux/version.h>
53
#include <linux/major.h>
54
#include <linux/wait.h>
55
#include <linux/blk.h> 
56
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
57
#include <linux/blkdev.h> 
58
#include <linux/devfs_fs_kernel.h>
59
#endif
60
#include <linux/genhd.h>
61
#include <linux/hdreg.h>
62
#include <linux/compatmac.h>
63
 
64
#include <asm/ccwcache.h>
65
#include <asm/irq.h>
66
#include <asm/s390dyn.h>
67
#include <asm/todclk.h>
68
#include <asm/debug.h>
69
 
70
/********************************************************************************
71
 * SECTION: Kernel Version Compatibility section
72
 ********************************************************************************/
73
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
74
typedef struct request *request_queue_t;
75
#define block_device_operations file_operations
76
#define __setup(x,y) struct dasd_device_t
77
#define devfs_register_blkdev(major,name,ops) register_blkdev(major,name,ops)
78
#define register_disk(dd,dev,partn,ops,size) \
79
do { \
80
        dd->sizes[MINOR(dev)] = size >> 1; \
81
        resetup_one_dev(dd,MINOR(dev)>>DASD_PARTN_BITS); \
82
} while(0)
83
#define init_waitqueue_head(x) do { *x = NULL; } while(0)
84
#define blk_cleanup_queue(x) do {} while(0)
85
#define blk_init_queue(x...) do {} while(0)
86
#define blk_queue_headactive(x...) do {} while(0)
87
#define blk_queue_make_request(x) do {} while(0)
88
#define list_empty(x) (0)
89
#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
90
do { \
91
        blk_dev[d_major].request_fn = d_request_fn; \
92
        blk_dev[d_major].queue = d_queue_fn; \
93
        blk_dev[d_major].current_request = d_current; \
94
} while(0)
95
#define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) \
96
        major:D_MAJOR, \
97
        major_name:D_NAME, \
98
        minor_shift:D_PARTN_BITS, \
99
        max_p:1 << D_PARTN_BITS, \
100
        max_nr:D_PER_MAJOR, \
101
        nr_real:D_PER_MAJOR,
102
static inline struct request *
103
dasd_next_request( request_queue_t *queue )
104
{
105
    return *queue;
106
}
107
static inline void
108
dasd_dequeue_request( request_queue_t * q, struct request *req )
109
{
110
        *q = req->next;
111
        req->next = NULL;
112
}
113
 
114
#else
115
#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
116
do { \
117
        blk_dev[d_major].queue = d_queue_fn; \
118
} while(0)
119
#define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) \
120
        major:D_MAJOR, \
121
        major_name:D_NAME, \
122
        minor_shift:D_PARTN_BITS, \
123
        max_p:1 << D_PARTN_BITS, \
124
        nr_real:D_PER_MAJOR, \
125
        fops:&dasd_device_operations,
126
static inline struct request *
127
dasd_next_request( request_queue_t *queue )
128
{
129
        return blkdev_entry_next_request(&queue->queue_head);
130
}
131
static inline void
132
dasd_dequeue_request( request_queue_t * q, struct request *req )
133
{
134
        blkdev_dequeue_request (req);
135
}
136
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) */
137
 
138
/********************************************************************************
139
 * SECTION: Type definitions
140
 ********************************************************************************/
141
 
142
typedef struct dasd_devreg_t {
143
        devreg_t devreg; /* the devreg itself */
144
        /* build a linked list of devregs, needed for cleanup */
145
        struct list_head list;
146
} dasd_devreg_t;
147
 
148
typedef struct {
149
        struct list_head list;
150
        struct module *owner;
151
        int no;
152
        dasd_ioctl_fn_t handler;
153
} dasd_ioctl_list_t;
154
 
155
typedef enum {
156
        dasd_era_fatal = -1,    /* no chance to recover              */
157
        dasd_era_none = 0,       /* don't recover, everything alright */
158
        dasd_era_msg = 1,       /* don't recover, just report...     */
159
        dasd_era_recover = 2    /* recovery action recommended       */
160
} dasd_era_t;
161
 
162
/* BIT DEFINITIONS FOR SENSE DATA */
163
#define DASD_SENSE_BIT_0 0x80
164
#define DASD_SENSE_BIT_1 0x40
165
#define DASD_SENSE_BIT_2 0x20
166
#define DASD_SENSE_BIT_3 0x10
167
 
168
/*
169
 * struct dasd_sizes_t
170
 * represents all data needed to access dasd with properly set up sectors
171
 */
172
typedef
173
struct dasd_sizes_t {
174
        unsigned long blocks; /* size of volume in blocks */
175
        unsigned int bp_block; /* bytes per block */
176
        unsigned int s2b_shift; /* log2 (bp_block/512) */
177
        unsigned int pt_block; /* from which block to read the partn table */
178
} dasd_sizes_t;
179
 
180
/*
181
 * struct dasd_chanq_t
182
 * represents a queue of channel programs related to a single device
183
 */
184
typedef
185
struct dasd_chanq_t {
186
        ccw_req_t *head;
187
        ccw_req_t *tail;
188
} dasd_chanq_t;
189
 
190
/*
191
 * struct dasd_lowmem_t
192
 * represents a queue of pages for lowmem request
193
 */
194
typedef struct {
195
        struct list_head list;
196
} dasd_lowmem_t;
197
 
198
#define DASD_LOWMEM_PAGES 2     /* # of lowmem pages per device (min 2) */
199
 
200
/********************************************************************************
201
 * SECTION: MACROS
202
 ********************************************************************************/
203
 
204
/*
205
 * CHECK_THEN_SET
206
 *
207
 * Change 'where' value from 'from' to 'to'.
208
 ' BUG if the 'from' value doesn't match.
209
 */
210
#define check_then_set(where,from,to) \
211
do { \
212
        if ((*(where)) != (from) ) { \
213
                printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \
214
                BUG(); \
215
        } \
216
        (*(where)) = (to); \
217
} while(0)
218
 
219
 
220
/********************************************************************************
221
 * SECION: MACROs for klogd and s390 debug feature (dbf)
222
 ********************************************************************************/
223
 
224
#define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \
225
do { \
226
        if (d_device->debug_area != NULL) \
227
                debug_sprintf_event(d_device->debug_area, \
228
                                    d_level, \
229
                                    d_str "\n", \
230
                                    d_data); \
231
} while(0)
232
 
233
#define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \
234
do { \
235
        if (d_device->debug_area != NULL) \
236
                debug_sprintf_exception(d_device->debug_area, \
237
                                        d_level, \
238
                                        d_str "\n", \
239
                                        d_data); \
240
} while(0)
241
 
242
#define DBF_EVENT(d_level, d_str, d_data...)\
243
do { \
244
        if (dasd_debug_area != NULL) \
245
                debug_sprintf_event(dasd_debug_area, \
246
                                    d_level,\
247
                                    d_str "\n", \
248
                                    d_data); \
249
} while(0)
250
 
251
#define DBF_EXC(d_level, d_str, d_data...)\
252
do { \
253
        if (dasd_debug_area != NULL) \
254
                debug_sprintf_exception(dasd_debug_area, \
255
                                        d_level,\
256
                                        d_str "\n", \
257
                                        d_data); \
258
} while(0)
259
 
260
/* definition of dbf debug levels */
261
#define DBF_EMERG       0        /* system is unusable           */
262
#define DBF_ALERT       1       /* action must be taken immediately     */
263
#define DBF_CRIT        2       /* critical conditions          */
264
#define DBF_ERR         3       /* error conditions                     */
265
#define DBF_WARNING     4       /* warning conditions           */
266
#define DBF_NOTICE      5       /* normal but significant condition     */
267
#define DBF_INFO        6       /* informational                        */
268
#define DBF_DEBUG       6       /* debug-level messages         */
269
 
270
/* messages to be written via klogd and dbf */
271
#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
272
do { \
273
        int d_devno = d_device->devinfo.devno; \
274
        int d_irq = d_device->devinfo.irq; \
275
        char *d_name = d_device->name; \
276
        int d_major = MAJOR(d_device->kdev); \
277
        int d_minor = MINOR(d_device->kdev); \
278
\
279
        printk(d_loglevel PRINTK_HEADER \
280
               " /dev/%-7s(%3d:%3d),%04x@%02x: " \
281
               d_string "\n", \
282
               d_name, \
283
               d_major, \
284
               d_minor, \
285
               d_devno, \
286
               d_irq, \
287
               d_args); \
288
\
289
        DBF_DEV_EVENT(DBF_ALERT, \
290
                      d_device, \
291
                      d_string, \
292
                      d_args); \
293
} while(0)
294
 
295
/* general messages to be written via klogd and dbf */
296
#define MESSAGE(d_loglevel,d_string,d_args...)\
297
do { \
298
        printk(d_loglevel PRINTK_HEADER \
299
               " " d_string "\n", \
300
               d_args); \
301
\
302
        DBF_EVENT(DBF_ALERT, \
303
                  d_string, \
304
                  d_args); \
305
} while(0)
306
 
307
/* general messages to be written via klogd only */
308
#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\
309
do { \
310
        printk(d_loglevel PRINTK_HEADER \
311
               " " d_string "\n", \
312
               d_args); \
313
} while(0)
314
 
315
struct dasd_device_t;
316
struct request;
317
 
318
/********************************************************************************
319
 * SECTION: signatures for the functions of dasd_discipline_t
320
 * make typecasts much easier
321
 ********************************************************************************/
322
 
323
typedef int    (*dasd_ck_id_fn_t)              (s390_dev_info_t *);
324
typedef int    (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *);
325
typedef int    (*dasd_fill_geometry_fn_t)      (struct dasd_device_t *,
326
                                                struct hd_geometry *);
327
typedef int    (*dasd_do_analysis_fn_t)        (struct dasd_device_t *);
328
typedef int    (*dasd_io_starter_fn_t)         (ccw_req_t *);
329
typedef int    (*dasd_io_stopper_fn_t)         (ccw_req_t *);
330
typedef int    (*dasd_info_fn_t)               (struct dasd_device_t *,
331
                                                dasd_information2_t *);
332
typedef int    (*dasd_use_count_fn_t)          (int);
333
typedef int    (*dasd_get_attrib_fn_t)         (struct dasd_device_t *,
334
                                                struct attrib_data_t *);
335
typedef int    (*dasd_set_attrib_fn_t)         (struct dasd_device_t *,
336
                                                struct attrib_data_t *);
337
typedef void   (*dasd_int_handler_fn_t)        (int irq, void *,
338
                                                struct pt_regs *);
339
typedef void   (*dasd_dump_sense_fn_t)         (struct dasd_device_t *,
340
                                                ccw_req_t *);
341
typedef ccw_req_t *(*dasd_format_fn_t)         (struct dasd_device_t *,
342
                                                struct format_data_t *);
343
typedef ccw_req_t *(*dasd_init_analysis_fn_t ) (struct dasd_device_t *);
344
typedef ccw_req_t *(*dasd_cp_builder_fn_t)     (struct dasd_device_t *,
345
                                                struct request *);
346
typedef ccw_req_t *(*dasd_reserve_fn_t)        (struct dasd_device_t *);
347
typedef ccw_req_t *(*dasd_release_fn_t)        (struct dasd_device_t *);
348
typedef ccw_req_t *(*dasd_steal_lock_fn_t)     (struct dasd_device_t *);
349
typedef ccw_req_t *(*dasd_merge_cp_fn_t)       (struct dasd_device_t *);
350
typedef ccw_req_t *(*dasd_erp_action_fn_t)     (ccw_req_t * cqr);
351
typedef ccw_req_t *(*dasd_erp_postaction_fn_t) (ccw_req_t * cqr);
352
typedef ccw_req_t *(*dasd_read_stats_fn_t)     (struct dasd_device_t *);
353
 
354
typedef dasd_rssd_perf_stats_t * (*dasd_ret_stats_fn_t)     (ccw_req_t *);
355
typedef dasd_era_t               (*dasd_error_examine_fn_t) (ccw_req_t *,
356
                                                             devstat_t * stat);
357
typedef dasd_erp_action_fn_t     (*dasd_error_analyse_fn_t) (ccw_req_t *);
358
typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t)   (ccw_req_t *);
359
 
360
/*
361
 * the dasd_discipline_t is
362
 * sth like a table of virtual functions, if you think of dasd_eckd
363
 * inheriting dasd...
364
 * no, currently we are not planning to reimplement the driver in C++
365
 */
366
typedef struct dasd_discipline_t {
367
        struct module *owner;
368
        char ebcname[8]; /* a name used for tagging and printks */
369
        char name[8];           /* a name used for tagging and printks */
370
        int max_blocks; /* maximum number of blocks to be chained */
371
        dasd_ck_id_fn_t              id_check;              /* check sense data */
372
        dasd_ck_characteristics_fn_t check_characteristics; /* check the characteristics */
373
        dasd_init_analysis_fn_t      init_analysis;         /* start the analysis of the volume */
374
        dasd_do_analysis_fn_t        do_analysis;           /* complete the analysis of the volume */
375
        dasd_fill_geometry_fn_t      fill_geometry;         /* set up hd_geometry */
376
        dasd_io_starter_fn_t         start_IO;
377
        dasd_io_stopper_fn_t         term_IO;
378
        dasd_format_fn_t             format_device;         /* format the device */
379
        dasd_error_examine_fn_t      examine_error;
380
        dasd_error_analyse_fn_t      erp_action;
381
        dasd_erp_analyse_fn_t        erp_postaction;
382
        dasd_cp_builder_fn_t         build_cp_from_req;
383
        dasd_dump_sense_fn_t         dump_sense;
384
        dasd_int_handler_fn_t        int_handler;
385
        dasd_reserve_fn_t            reserve;
386
        dasd_release_fn_t            release;
387
        dasd_steal_lock_fn_t         steal_lock;
388
        dasd_merge_cp_fn_t           merge_cp;
389
        dasd_info_fn_t               fill_info;
390
        dasd_read_stats_fn_t         read_stats;
391
        dasd_ret_stats_fn_t          ret_stats;             /* return performance statistics */
392
        dasd_get_attrib_fn_t         get_attrib;            /* get attributes (cache operations */
393
        dasd_set_attrib_fn_t         set_attrib;            /* set attributes (cache operations */
394
        struct list_head list;  /* used for list of disciplines */
395
} dasd_discipline_t;
396
 
397
/* dasd_range_t are used for ordering the DASD devices */
398
typedef struct dasd_range_t {
399
        unsigned int from;      /* first DASD in range */
400
        unsigned int to;        /* last DASD in range */
401
        char discipline[4];     /* placeholder to force discipline */
402
        int features;
403
        struct list_head list;  /* next one in linked list */
404
} dasd_range_t;
405
 
406
 
407
 
408
#define DASD_MAJOR_INFO_REGISTERED 1
409
#define DASD_MAJOR_INFO_IS_STATIC 2
410
 
411
typedef struct major_info_t {
412
        struct list_head list;
413
        struct dasd_device_t **dasd_device;
414
        int flags;
415
        struct gendisk gendisk; /* actually contains the major number */
416
} __attribute__ ((packed)) major_info_t;
417
 
418
typedef struct dasd_device_t {
419
        s390_dev_info_t devinfo;
420
        dasd_discipline_t *discipline;
421
        int level;
422
        atomic_t open_count;
423
        kdev_t kdev;
424
        major_info_t *major_info;
425
        struct dasd_chanq_t queue;
426
        wait_queue_head_t wait_q;
427
        request_queue_t *request_queue;
428
        struct timer_list timer;             /* used for start_IO */
429
        struct timer_list late_timer;        /* to get late devices online */
430
        struct timer_list blocking_timer;    /* used for ERP */
431
        devstat_t dev_status; /* needed ONLY!! for request_irq */
432
        dasd_sizes_t sizes;
433
        char name[16]; /* The name of the device in /dev */
434
        char *private;  /* to be used by the discipline internally */
435
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
436
        devfs_handle_t devfs_entry;
437
#endif /* LINUX_IS_24 */
438
        struct tq_struct bh_tq;
439
        atomic_t bh_scheduled;
440
        debug_info_t *debug_area;
441
        dasd_profile_info_t profile;
442
        ccw_req_t *init_cqr;
443
        atomic_t plugged;
444
        int stopped;                         /* device (do_IO) was stopped */
445
        struct list_head lowmem_pool;
446
}  dasd_device_t;
447
 
448
/* reasons why device (do_IO) was stopped */
449
#define DASD_STOPPED_NOT_ACC 1         /* not accessible */
450
#define DASD_STOPPED_PENDING 2         /* long busy */
451
 
452
 
453
int  dasd_init               (void);
454
void dasd_discipline_add     (dasd_discipline_t *);
455
void dasd_discipline_del     (dasd_discipline_t *);
456
int  dasd_start_IO           (ccw_req_t *);
457
int  dasd_term_IO            (ccw_req_t *);
458
void dasd_int_handler        (int , void *, struct pt_regs *);
459
void dasd_free_request       (ccw_req_t *, dasd_device_t *);
460
int  dasd_oper_handler       (int irq, devreg_t * devreg);
461
void dasd_schedule_bh        (dasd_device_t *);
462
void dasd_schedule_bh_timed  (unsigned long);
463
int  dasd_sleep_on_req       (ccw_req_t*);
464
int  dasd_set_normalized_cda (ccw1_t * cp, unsigned long address,
465
                              ccw_req_t* request,
466
                              dasd_device_t* device );
467
ccw_req_t *     dasd_default_erp_action     (ccw_req_t *);
468
ccw_req_t *     dasd_default_erp_postaction (ccw_req_t *);
469
inline void     dasd_chanq_deq              (dasd_chanq_t *, ccw_req_t *);
470
inline void     dasd_chanq_enq              (dasd_chanq_t *, ccw_req_t *);
471
inline void     dasd_chanq_enq_head         (dasd_chanq_t *, ccw_req_t *);
472
ccw_req_t *     dasd_alloc_request          (char *, int, int, dasd_device_t *);
473
dasd_device_t * dasd_device_from_kdev       (kdev_t kdev);
474
 
475
extern debug_info_t *dasd_debug_area;
476
extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *);
477
extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp,
478
                                unsigned int no, unsigned long data);
479
 
480
#endif /* __KERNEL__ */
481
 
482
#endif                          /* DASD_H */
483
 
484
/*
485
 * Overrides for Emacs so that we follow Linus's tabbing style.
486
 * Emacs will notice this stuff at the end of the file and automatically
487
 * adjust the settings for this buffer only.  This must remain at the end
488
 * of the file.
489
 * ---------------------------------------------------------------------------
490
 * Local variables:
491
 * c-indent-level: 4
492
 * c-brace-imaginary-offset: 0
493
 * c-brace-offset: -4
494
 * c-argdecl-indent: 4
495
 * c-label-offset: -4
496
 * c-continued-statement-offset: 4
497
 * c-continued-brace-offset: 0
498
 * indent-tabs-mode: nil
499
 * tab-width: 8
500
 * End:
501
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.