aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/partitions/ibm.c101
1 files changed, 71 insertions, 30 deletions
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 1e064c4a4f86..46297683cd34 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -21,20 +21,38 @@
21 * compute the block number from a 21 * compute the block number from a
22 * cyl-cyl-head-head structure 22 * cyl-cyl-head-head structure
23 */ 23 */
24static inline int 24static sector_t
25cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) { 25cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
26 return ptr->cc * geo->heads * geo->sectors + 26
27 ptr->hh * geo->sectors; 27 sector_t cyl;
28 __u16 head;
29
30 /*decode cylinder and heads for large volumes */
31 cyl = ptr->hh & 0xFFF0;
32 cyl <<= 12;
33 cyl |= ptr->cc;
34 head = ptr->hh & 0x000F;
35 return cyl * geo->heads * geo->sectors +
36 head * geo->sectors;
28} 37}
29 38
30/* 39/*
31 * compute the block number from a 40 * compute the block number from a
32 * cyl-cyl-head-head-block structure 41 * cyl-cyl-head-head-block structure
33 */ 42 */
34static inline int 43static sector_t
35cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { 44cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
36 return ptr->cc * geo->heads * geo->sectors + 45
37 ptr->hh * geo->sectors + 46 sector_t cyl;
47 __u16 head;
48
49 /*decode cylinder and heads for large volumes */
50 cyl = ptr->hh & 0xFFF0;
51 cyl <<= 12;
52 cyl |= ptr->cc;
53 head = ptr->hh & 0x000F;
54 return cyl * geo->heads * geo->sectors +
55 head * geo->sectors +
38 ptr->b; 56 ptr->b;
39} 57}
40 58
@@ -43,14 +61,15 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
43int 61int
44ibm_partition(struct parsed_partitions *state, struct block_device *bdev) 62ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
45{ 63{
46 int blocksize, offset, size,res; 64 int blocksize, res;
47 loff_t i_size; 65 loff_t i_size, offset, size, fmt_size;
48 dasd_information2_t *info; 66 dasd_information2_t *info;
49 struct hd_geometry *geo; 67 struct hd_geometry *geo;
50 char type[5] = {0,}; 68 char type[5] = {0,};
51 char name[7] = {0,}; 69 char name[7] = {0,};
52 union label_t { 70 union label_t {
53 struct vtoc_volume_label vol; 71 struct vtoc_volume_label_cdl vol;
72 struct vtoc_volume_label_ldl lnx;
54 struct vtoc_cms_label cms; 73 struct vtoc_cms_label cms;
55 } *label; 74 } *label;
56 unsigned char *data; 75 unsigned char *data;
@@ -85,14 +104,16 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
85 if (data == NULL) 104 if (data == NULL)
86 goto out_readerr; 105 goto out_readerr;
87 106
88 strncpy (type, data, 4);
89 if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD")))
90 strncpy(name, data + 8, 6);
91 else
92 strncpy(name, data + 4, 6);
93 memcpy(label, data, sizeof(union label_t)); 107 memcpy(label, data, sizeof(union label_t));
94 put_dev_sector(sect); 108 put_dev_sector(sect);
95 109
110 if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
111 strncpy(type, label->vol.vollbl, 4);
112 strncpy(name, label->vol.volid, 6);
113 } else {
114 strncpy(type, label->lnx.vollbl, 4);
115 strncpy(name, label->lnx.volid, 6);
116 }
96 EBCASC(type, 4); 117 EBCASC(type, 4);
97 EBCASC(name, 6); 118 EBCASC(name, 6);
98 119
@@ -110,36 +131,54 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
110 /* 131 /*
111 * VM style CMS1 labeled disk 132 * VM style CMS1 labeled disk
112 */ 133 */
134 blocksize = label->cms.block_size;
113 if (label->cms.disk_offset != 0) { 135 if (label->cms.disk_offset != 0) {
114 printk("CMS1/%8s(MDSK):", name); 136 printk("CMS1/%8s(MDSK):", name);
115 /* disk is reserved minidisk */ 137 /* disk is reserved minidisk */
116 blocksize = label->cms.block_size;
117 offset = label->cms.disk_offset; 138 offset = label->cms.disk_offset;
118 size = (label->cms.block_count - 1) 139 size = (label->cms.block_count - 1)
119 * (blocksize >> 9); 140 * (blocksize >> 9);
120 } else { 141 } else {
121 printk("CMS1/%8s:", name); 142 printk("CMS1/%8s:", name);
122 offset = (info->label_block + 1); 143 offset = (info->label_block + 1);
123 size = i_size >> 9; 144 size = label->cms.block_count
145 * (blocksize >> 9);
124 } 146 }
147 put_partition(state, 1, offset*(blocksize >> 9),
148 size-offset*(blocksize >> 9));
125 } else { 149 } else {
126 /* 150 if (strncmp(type, "LNX1", 4) == 0) {
127 * Old style LNX1 or unlabeled disk 151 printk("LNX1/%8s:", name);
128 */ 152 if (label->lnx.ldl_version == 0xf2) {
129 if (strncmp(type, "LNX1", 4) == 0) 153 fmt_size = label->lnx.formatted_blocks
130 printk ("LNX1/%8s:", name); 154 * (blocksize >> 9);
131 else 155 } else if (!strcmp(info->type, "ECKD")) {
156 /* formated w/o large volume support */
157 fmt_size = geo->cylinders * geo->heads
158 * geo->sectors * (blocksize >> 9);
159 } else {
160 /* old label and no usable disk geometry
161 * (e.g. DIAG) */
162 fmt_size = i_size >> 9;
163 }
164 size = i_size >> 9;
165 if (fmt_size < size)
166 size = fmt_size;
167 offset = (info->label_block + 1);
168 } else {
169 /* unlabeled disk */
132 printk("(nonl)"); 170 printk("(nonl)");
133 offset = (info->label_block + 1); 171 size = i_size >> 9;
134 size = i_size >> 9; 172 offset = (info->label_block + 1);
135 } 173 }
136 put_partition(state, 1, offset*(blocksize >> 9), 174 put_partition(state, 1, offset*(blocksize >> 9),
137 size-offset*(blocksize >> 9)); 175 size-offset*(blocksize >> 9));
176 }
138 } else if (info->format == DASD_FORMAT_CDL) { 177 } else if (info->format == DASD_FORMAT_CDL) {
139 /* 178 /*
140 * New style CDL formatted disk 179 * New style CDL formatted disk
141 */ 180 */
142 unsigned int blk; 181 sector_t blk;
143 int counter; 182 int counter;
144 183
145 /* 184 /*
@@ -166,7 +205,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
166 /* skip FMT4 / FMT5 / FMT7 labels */ 205 /* skip FMT4 / FMT5 / FMT7 labels */
167 if (f1.DS1FMTID == _ascebc['4'] 206 if (f1.DS1FMTID == _ascebc['4']
168 || f1.DS1FMTID == _ascebc['5'] 207 || f1.DS1FMTID == _ascebc['5']
169 || f1.DS1FMTID == _ascebc['7']) { 208 || f1.DS1FMTID == _ascebc['7']
209 || f1.DS1FMTID == _ascebc['9']) {
170 blk++; 210 blk++;
171 data = read_dev_sector(bdev, blk * 211 data = read_dev_sector(bdev, blk *
172 (blocksize/512), 212 (blocksize/512),
@@ -174,8 +214,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
174 continue; 214 continue;
175 } 215 }
176 216
177 /* only FMT1 valid at this point */ 217 /* only FMT1 and 8 labels valid at this point */
178 if (f1.DS1FMTID != _ascebc['1']) 218 if (f1.DS1FMTID != _ascebc['1'] &&
219 f1.DS1FMTID != _ascebc['8'])
179 break; 220 break;
180 221
181 /* OK, we got valid partition data */ 222 /* OK, we got valid partition data */