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_genhd.c
Go to the documentation of this file.
1
/*
2
* Author(s)......: Holger Smolinski <
[email protected]
>
3
* Horst Hummel <
[email protected]
>
4
* Carsten Otte <
[email protected]
>
5
* Martin Schwidefsky <
[email protected]
>
6
* Bugreports.to..: <
[email protected]
>
7
* Copyright IBM Corp. 1999, 2001
8
*
9
* gendisk related functions for the dasd driver.
10
*
11
*/
12
13
#define KMSG_COMPONENT "dasd"
14
15
#include <
linux/interrupt.h
>
16
#include <linux/fs.h>
17
#include <
linux/blkpg.h
>
18
19
#include <asm/uaccess.h>
20
21
/* This is ugly... */
22
#define PRINTK_HEADER "dasd_gendisk:"
23
24
#include "
dasd_int.h
"
25
26
/*
27
* Allocate and register gendisk structure for device.
28
*/
29
int
dasd_gendisk_alloc
(
struct
dasd_block
*
block
)
30
{
31
struct
gendisk *gdp;
32
struct
dasd_device
*
base
;
33
int
len
;
34
35
/* Make sure the minor for this device exists. */
36
base = block->
base
;
37
if
(base->
devindex
>=
DASD_PER_MAJOR
)
38
return
-
EBUSY
;
39
40
gdp =
alloc_disk
(1 <<
DASD_PARTN_BITS
);
41
if
(!gdp)
42
return
-
ENOMEM
;
43
44
/* Initialize gendisk structure. */
45
gdp->major =
DASD_MAJOR
;
46
gdp->first_minor = base->
devindex
<<
DASD_PARTN_BITS
;
47
gdp->fops = &
dasd_device_operations
;
48
gdp->driverfs_dev = &base->
cdev
->dev;
49
50
/*
51
* Set device name.
52
* dasda - dasdz : 26 devices
53
* dasdaa - dasdzz : 676 devices, added up = 702
54
* dasdaaa - dasdzzz : 17576 devices, added up = 18278
55
* dasdaaaa - dasdzzzz : 456976 devices, added up = 475252
56
*/
57
len =
sprintf
(gdp->disk_name,
"dasd"
);
58
if
(base->
devindex
> 25) {
59
if
(base->
devindex
> 701) {
60
if
(base->
devindex
> 18277)
61
len +=
sprintf
(gdp->disk_name + len,
"%c"
,
62
'a'
+(((base->
devindex
-18278)
63
/17576)%26));
64
len +=
sprintf
(gdp->disk_name + len,
"%c"
,
65
'a'
+(((base->
devindex
-702)/676)%26));
66
}
67
len +=
sprintf
(gdp->disk_name + len,
"%c"
,
68
'a'
+(((base->
devindex
-26)/26)%26));
69
}
70
len +=
sprintf
(gdp->disk_name + len,
"%c"
,
'a'
+(base->
devindex
%26));
71
72
if
(base->
features
&
DASD_FEATURE_READONLY
||
73
test_bit
(
DASD_FLAG_DEVICE_RO
, &base->
flags
))
74
set_disk_ro
(gdp, 1);
75
dasd_add_link_to_gendisk
(gdp, base);
76
gdp->queue = block->
request_queue
;
77
block->
gdp
= gdp;
78
set_capacity(block->
gdp
, 0);
79
add_disk
(block->
gdp
);
80
return
0;
81
}
82
83
/*
84
* Unregister and free gendisk structure for device.
85
*/
86
void
dasd_gendisk_free
(
struct
dasd_block
*
block
)
87
{
88
if
(block->
gdp
) {
89
del_gendisk
(block->
gdp
);
90
block->
gdp
->queue =
NULL
;
91
block->
gdp
->private_data =
NULL
;
92
put_disk
(block->
gdp
);
93
block->
gdp
=
NULL
;
94
}
95
}
96
97
/*
98
* Trigger a partition detection.
99
*/
100
int
dasd_scan_partitions
(
struct
dasd_block
*
block
)
101
{
102
struct
block_device
*bdev;
103
104
bdev =
bdget_disk
(block->
gdp
, 0);
105
if
(!bdev ||
blkdev_get
(bdev,
FMODE_READ
,
NULL
) < 0)
106
return
-
ENODEV
;
107
/*
108
* See fs/partition/check.c:register_disk,rescan_partitions
109
* Can't call rescan_partitions directly. Use ioctl.
110
*/
111
ioctl_by_bdev
(bdev,
BLKRRPART
, 0);
112
/*
113
* Since the matching blkdev_put call to the blkdev_get in
114
* this function is not called before dasd_destroy_partitions
115
* the offline open_count limit needs to be increased from
116
* 0 to 1. This is done by setting device->bdev (see
117
* dasd_generic_set_offline). As long as the partition
118
* detection is running no offline should be allowed. That
119
* is why the assignment to device->bdev is done AFTER
120
* the BLKRRPART ioctl.
121
*/
122
block->
bdev
= bdev;
123
return
0;
124
}
125
126
/*
127
* Remove all inodes in the system for a device, delete the
128
* partitions and make device unusable by setting its size to zero.
129
*/
130
void
dasd_destroy_partitions
(
struct
dasd_block
*
block
)
131
{
132
/* The two structs have 168/176 byte on 31/64 bit. */
133
struct
blkpg_partition
bpart;
134
struct
blkpg_ioctl_arg
barg;
135
struct
block_device
*bdev;
136
137
/*
138
* Get the bdev pointer from the device structure and clear
139
* device->bdev to lower the offline open_count limit again.
140
*/
141
bdev = block->
bdev
;
142
block->
bdev
=
NULL
;
143
144
/*
145
* See fs/partition/check.c:delete_partition
146
* Can't call delete_partitions directly. Use ioctl.
147
* The ioctl also does locking and invalidation.
148
*/
149
memset
(&bpart, 0,
sizeof
(
struct
blkpg_partition
));
150
memset
(&barg, 0,
sizeof
(
struct
blkpg_ioctl_arg
));
151
barg.
data
= (
void
__force
__user
*) &bpart;
152
barg.
op
=
BLKPG_DEL_PARTITION
;
153
for
(bpart.
pno
= block->
gdp
->minors - 1; bpart.
pno
> 0; bpart.
pno
--)
154
ioctl_by_bdev
(bdev,
BLKPG
, (
unsigned
long
) &barg);
155
156
invalidate_partition
(block->
gdp
, 0);
157
/* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
158
blkdev_put
(bdev,
FMODE_READ
);
159
set_capacity(block->
gdp
, 0);
160
}
161
162
int
dasd_gendisk_init
(
void
)
163
{
164
int
rc
;
165
166
/* Register to static dasd major 94 */
167
rc =
register_blkdev
(
DASD_MAJOR
,
"dasd"
);
168
if
(rc != 0) {
169
pr_warning
(
"Registering the device driver with major number "
170
"%d failed\n"
,
DASD_MAJOR
);
171
return
rc
;
172
}
173
return
0;
174
}
175
176
void
dasd_gendisk_exit
(
void
)
177
{
178
unregister_blkdev
(
DASD_MAJOR
,
"dasd"
);
179
}
Generated on Thu Jan 10 2013 14:17:14 for Linux Kernel by
1.8.2