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