2 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
3 * Volker Sameske <sameske@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com>
5 * Copyright IBM Corp. 1999, 2012
8 #include <linux/buffer_head.h>
9 #include <linux/hdreg.h>
10 #include <linux/slab.h>
12 #include <asm/ebcdic.h>
13 #include <asm/uaccess.h>
21 struct vtoc_volume_label_cdl vol
;
22 struct vtoc_volume_label_ldl lnx
;
23 struct vtoc_cms_label cms
;
27 * compute the block number from a
28 * cyl-cyl-head-head structure
30 static sector_t
cchh2blk(struct vtoc_cchh
*ptr
, struct hd_geometry
*geo
)
35 /* decode cylinder and heads for large volumes */
36 cyl
= ptr
->hh
& 0xFFF0;
39 head
= ptr
->hh
& 0x000F;
40 return cyl
* geo
->heads
* geo
->sectors
+
45 * compute the block number from a
46 * cyl-cyl-head-head-block structure
48 static sector_t
cchhb2blk(struct vtoc_cchhb
*ptr
, struct hd_geometry
*geo
)
53 /* decode cylinder and heads for large volumes */
54 cyl
= ptr
->hh
& 0xFFF0;
57 head
= ptr
->hh
& 0x000F;
58 return cyl
* geo
->heads
* geo
->sectors
+
63 static int find_label(struct parsed_partitions
*state
,
64 dasd_information2_t
*info
,
65 struct hd_geometry
*geo
,
75 unsigned char temp
[5];
79 /* There a three places where we may find a valid label:
80 * - on an ECKD disk it's block 2
81 * - on an FBA disk it's block 1
82 * - on an CMS formatted FBA disk it is sector 1, even if the block size
83 * is larger than 512 bytes (possible if the DIAG discipline is used)
84 * If we have a valid info structure, then we know exactly which case we
85 * have, otherwise we just search through all possebilities.
88 if ((info
->cu_type
== 0x6310 && info
->dev_type
== 0x9336) ||
89 (info
->cu_type
== 0x3880 && info
->dev_type
== 0x3370))
90 testsect
[0] = info
->label_block
;
92 testsect
[0] = info
->label_block
* (blocksize
>> 9);
96 testsect
[1] = (blocksize
>> 9);
97 testsect
[2] = 2 * (blocksize
>> 9);
100 for (i
= 0; i
< testcount
; ++i
) {
101 data
= read_part_sector(state
, testsect
[i
], §
);
104 memcpy(label
, data
, sizeof(*label
));
105 memcpy(temp
, data
, 4);
108 put_dev_sector(sect
);
109 if (!strcmp(temp
, "VOL1") ||
110 !strcmp(temp
, "LNX1") ||
111 !strcmp(temp
, "CMS1")) {
112 if (!strcmp(temp
, "VOL1")) {
113 strncpy(type
, label
->vol
.vollbl
, 4);
114 strncpy(name
, label
->vol
.volid
, 6);
116 strncpy(type
, label
->lnx
.vollbl
, 4);
117 strncpy(name
, label
->lnx
.volid
, 6);
121 *labelsect
= testsect
[i
];
127 memset(label
, 0, sizeof(*label
));
132 static int find_vol1_partitions(struct parsed_partitions
*state
,
133 struct hd_geometry
*geo
,
136 union label_t
*label
)
144 struct vtoc_format1_label f1
;
147 snprintf(tmp
, sizeof(tmp
), "VOL1/%8s:", name
);
148 strlcat(state
->pp_buf
, tmp
, PAGE_SIZE
);
150 * get start of VTOC from the disk label and then search for format1
153 secperblk
= blocksize
>> 9;
154 blk
= cchhb2blk(&label
->vol
.vtoc
, geo
) + 1;
156 data
= read_part_sector(state
, blk
* secperblk
, §
);
157 while (data
!= NULL
) {
158 memcpy(&f1
, data
, sizeof(struct vtoc_format1_label
));
159 put_dev_sector(sect
);
160 /* skip FMT4 / FMT5 / FMT7 labels */
161 if (f1
.DS1FMTID
== _ascebc
['4']
162 || f1
.DS1FMTID
== _ascebc
['5']
163 || f1
.DS1FMTID
== _ascebc
['7']
164 || f1
.DS1FMTID
== _ascebc
['9']) {
166 data
= read_part_sector(state
, blk
* secperblk
, §
);
169 /* only FMT1 and 8 labels valid at this point */
170 if (f1
.DS1FMTID
!= _ascebc
['1'] &&
171 f1
.DS1FMTID
!= _ascebc
['8'])
173 /* OK, we got valid partition data */
174 offset
= cchh2blk(&f1
.DS1EXT1
.llimit
, geo
);
175 size
= cchh2blk(&f1
.DS1EXT1
.ulimit
, geo
) -
176 offset
+ geo
->sectors
;
179 if (counter
>= state
->limit
)
181 put_partition(state
, counter
+ 1, offset
, size
);
184 data
= read_part_sector(state
, blk
* secperblk
, §
);
186 strlcat(state
->pp_buf
, "\n", PAGE_SIZE
);
194 static int find_lnx1_partitions(struct parsed_partitions
*state
,
195 struct hd_geometry
*geo
,
198 union label_t
*label
,
201 dasd_information2_t
*info
)
203 loff_t offset
, geo_size
, size
;
207 snprintf(tmp
, sizeof(tmp
), "LNX1/%8s:", name
);
208 strlcat(state
->pp_buf
, tmp
, PAGE_SIZE
);
209 secperblk
= blocksize
>> 9;
210 if (label
->lnx
.ldl_version
== 0xf2) {
211 size
= label
->lnx
.formatted_blocks
* secperblk
;
214 * Formated w/o large volume support. If the sanity check
215 * 'size based on geo == size based on i_size' is true, then
216 * we can safely assume that we know the formatted size of
217 * the disk, otherwise we need additional information
218 * that we can only get from a real DASD device.
220 geo_size
= geo
->cylinders
* geo
->heads
221 * geo
->sectors
* secperblk
;
223 if (size
!= geo_size
) {
225 strlcat(state
->pp_buf
, "\n", PAGE_SIZE
);
228 if (!strcmp(info
->type
, "ECKD"))
231 /* else keep size based on i_size */
234 /* first and only partition starts in the first block after the label */
235 offset
= labelsect
+ secperblk
;
236 put_partition(state
, 1, offset
, size
- offset
);
237 strlcat(state
->pp_buf
, "\n", PAGE_SIZE
);
241 static int find_cms1_partitions(struct parsed_partitions
*state
,
242 struct hd_geometry
*geo
,
245 union label_t
*label
,
253 * VM style CMS1 labeled disk
255 blocksize
= label
->cms
.block_size
;
256 secperblk
= blocksize
>> 9;
257 if (label
->cms
.disk_offset
!= 0) {
258 snprintf(tmp
, sizeof(tmp
), "CMS1/%8s(MDSK):", name
);
259 strlcat(state
->pp_buf
, tmp
, PAGE_SIZE
);
260 /* disk is reserved minidisk */
261 offset
= label
->cms
.disk_offset
* secperblk
;
262 size
= (label
->cms
.block_count
- 1) * secperblk
;
264 snprintf(tmp
, sizeof(tmp
), "CMS1/%8s:", name
);
265 strlcat(state
->pp_buf
, tmp
, PAGE_SIZE
);
267 * Special case for FBA devices:
268 * If an FBA device is CMS formatted with blocksize > 512 byte
269 * and the DIAG discipline is used, then the CMS label is found
270 * in sector 1 instead of block 1. However, the partition is
271 * still supposed to start in block 2.
274 offset
= 2 * secperblk
;
276 offset
= labelsect
+ secperblk
;
277 size
= label
->cms
.block_count
* secperblk
;
280 put_partition(state
, 1, offset
, size
-offset
);
281 strlcat(state
->pp_buf
, "\n", PAGE_SIZE
);
287 * This is the main function, called by check.c
289 int ibm_partition(struct parsed_partitions
*state
)
291 struct block_device
*bdev
= state
->bdev
;
293 loff_t i_size
, offset
, size
;
294 dasd_information2_t
*info
;
295 struct hd_geometry
*geo
;
299 union label_t
*label
;
302 blocksize
= bdev_logical_block_size(bdev
);
305 i_size
= i_size_read(bdev
->bd_inode
);
308 info
= kmalloc(sizeof(dasd_information2_t
), GFP_KERNEL
);
311 geo
= kmalloc(sizeof(struct hd_geometry
), GFP_KERNEL
);
314 label
= kmalloc(sizeof(union label_t
), GFP_KERNEL
);
317 if (ioctl_by_bdev(bdev
, HDIO_GETGEO
, (unsigned long)geo
) != 0)
319 if (ioctl_by_bdev(bdev
, BIODASDINFO2
, (unsigned long)info
) != 0) {
324 if (find_label(state
, info
, geo
, blocksize
, &labelsect
, name
, type
,
326 if (!strncmp(type
, "VOL1", 4)) {
327 res
= find_vol1_partitions(state
, geo
, blocksize
, name
,
329 } else if (!strncmp(type
, "LNX1", 4)) {
330 res
= find_lnx1_partitions(state
, geo
, blocksize
, name
,
331 label
, labelsect
, i_size
,
333 } else if (!strncmp(type
, "CMS1", 4)) {
334 res
= find_cms1_partitions(state
, geo
, blocksize
, name
,
339 * ugly but needed for backward compatibility:
340 * If the block device is a DASD (i.e. BIODASDINFO2 works),
341 * then we claim it in any case, even though it has no valid
342 * label. If it has the LDL format, then we simply define a
343 * partition as if it had an LNX1 label.
346 if (info
->format
== DASD_FORMAT_LDL
) {
347 strlcat(state
->pp_buf
, "(nonl)", PAGE_SIZE
);
349 offset
= (info
->label_block
+ 1) * (blocksize
>> 9);
350 put_partition(state
, 1, offset
, size
-offset
);
351 strlcat(state
->pp_buf
, "\n", PAGE_SIZE
);