diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-11 01:46:09 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-11 01:46:09 +0400 |
commit | 9f9d76321659b5ebc9939101481f7c3ce228ea6e (patch) | |
tree | 7abd21796ad85ba6c606cd2a93e787fb90b3abe6 /fs | |
parent | 1b21f458ddbc8fb6fceeb68158e9e04b2571dabd (diff) | |
parent | f60d89108f3481ca11672b82cf7e67171e050ce4 (diff) | |
download | linux-9f9d76321659b5ebc9939101481f7c3ce228ea6e.tar.xz |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] vmlogrdr function annotation.
[S390] s390: rename CPU_IDLE to S390_CPU_IDLE
[S390] cio: Remove prototype for non-existing function cmf_reset().
[S390] zcrypt: fix request timeout handling
[S390] system call optimization.
[S390] dasd: Avoid compile warnings on !CONFIG_DASD_PROFILE
[S390] Remove volatile from atomic_t
[S390] Program check in diag 210 under 31 bit
[S390] Bogomips calculation for 64 bit.
[S390] smp: Merge smp_count_cpus() and smp_get_save_areas().
[S390] zcore: Fix __user annotation.
[S390] fixed cdl-format detection.
[S390] sclp: Test facility list before executing a service call.
[S390] sclp: introduce some new interfaces.
[S390] Fixed comment typo.
[S390] vmcp cleanup
Diffstat (limited to 'fs')
-rw-r--r-- | fs/partitions/ibm.c | 167 |
1 files changed, 97 insertions, 70 deletions
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 9f7ad4244f63..1e064c4a4f86 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c @@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { int blocksize, offset, size,res; loff_t i_size; - dasd_information_t *info; + dasd_information2_t *info; struct hd_geometry *geo; char type[5] = {0,}; char name[7] = {0,}; @@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) if (i_size == 0) goto out_exit; - if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) + info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); + if (info == NULL) goto out_exit; - if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) + geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); + if (geo == NULL) goto out_nogeo; - if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) + label = kmalloc(sizeof(union label_t), GFP_KERNEL); + if (label == NULL) goto out_nolab; - if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || + if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) goto out_freeall; @@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) res = 1; /* - * Three different types: CMS1, VOL1 and LNX1/unlabeled + * Three different formats: LDL, CDL and unformated disk + * + * identified by info->format + * + * unformated disks we do not have to care about */ - if (strncmp(type, "CMS1", 4) == 0) { - /* - * VM style CMS1 labeled disk - */ - if (label->cms.disk_offset != 0) { - printk("CMS1/%8s(MDSK):", name); - /* disk is reserved minidisk */ - blocksize = label->cms.block_size; - offset = label->cms.disk_offset; - size = (label->cms.block_count - 1) * (blocksize >> 9); + if (info->format == DASD_FORMAT_LDL) { + if (strncmp(type, "CMS1", 4) == 0) { + /* + * VM style CMS1 labeled disk + */ + if (label->cms.disk_offset != 0) { + printk("CMS1/%8s(MDSK):", name); + /* disk is reserved minidisk */ + blocksize = label->cms.block_size; + offset = label->cms.disk_offset; + size = (label->cms.block_count - 1) + * (blocksize >> 9); + } else { + printk("CMS1/%8s:", name); + offset = (info->label_block + 1); + size = i_size >> 9; + } } else { - printk("CMS1/%8s:", name); + /* + * Old style LNX1 or unlabeled disk + */ + if (strncmp(type, "LNX1", 4) == 0) + printk ("LNX1/%8s:", name); + else + printk("(nonl)"); offset = (info->label_block + 1); size = i_size >> 9; } put_partition(state, 1, offset*(blocksize >> 9), - size-offset*(blocksize >> 9)); - } else if ((strncmp(type, "VOL1", 4) == 0) && - (!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) { + size-offset*(blocksize >> 9)); + } else if (info->format == DASD_FORMAT_CDL) { /* - * New style VOL1 labeled disk + * New style CDL formatted disk */ unsigned int blk; int counter; - printk("VOL1/%8s:", name); - - /* get block number and read then go through format1 labels */ - blk = cchhb2blk(&label->vol.vtoc, geo) + 1; - counter = 0; - while ((data = read_dev_sector(bdev, blk*(blocksize/512), - §)) != NULL) { - struct vtoc_format1_label f1; - - memcpy(&f1, data, sizeof(struct vtoc_format1_label)); - put_dev_sector(sect); - - /* skip FMT4 / FMT5 / FMT7 labels */ - if (f1.DS1FMTID == _ascebc['4'] - || f1.DS1FMTID == _ascebc['5'] - || f1.DS1FMTID == _ascebc['7']) { - blk++; - continue; - } - - /* only FMT1 valid at this point */ - if (f1.DS1FMTID != _ascebc['1']) - break; - - /* OK, we got valid partition data */ - offset = cchh2blk(&f1.DS1EXT1.llimit, geo); - size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - - offset + geo->sectors; - if (counter >= state->limit) - break; - put_partition(state, counter + 1, - offset * (blocksize >> 9), - size * (blocksize >> 9)); - counter++; - blk++; - } - if (!data) - /* Are we not supposed to report this ? */ - goto out_readerr; - } else { /* - * Old style LNX1 or unlabeled disk + * check if VOL1 label is available + * if not, something is wrong, skipping partition detection */ - if (strncmp(type, "LNX1", 4) == 0) - printk ("LNX1/%8s:", name); - else - printk("(nonl)/%8s:", name); - offset = (info->label_block + 1); - size = i_size >> 9; - put_partition(state, 1, offset*(blocksize >> 9), - size-offset*(blocksize >> 9)); + if (strncmp(type, "VOL1", 4) == 0) { + printk("VOL1/%8s:", name); + /* + * get block number and read then go through format1 + * labels + */ + blk = cchhb2blk(&label->vol.vtoc, geo) + 1; + counter = 0; + data = read_dev_sector(bdev, blk * (blocksize/512), + §); + while (data != NULL) { + struct vtoc_format1_label f1; + + memcpy(&f1, data, + sizeof(struct vtoc_format1_label)); + put_dev_sector(sect); + + /* skip FMT4 / FMT5 / FMT7 labels */ + if (f1.DS1FMTID == _ascebc['4'] + || f1.DS1FMTID == _ascebc['5'] + || f1.DS1FMTID == _ascebc['7']) { + blk++; + data = read_dev_sector(bdev, blk * + (blocksize/512), + §); + continue; + } + + /* only FMT1 valid at this point */ + if (f1.DS1FMTID != _ascebc['1']) + break; + + /* OK, we got valid partition data */ + offset = cchh2blk(&f1.DS1EXT1.llimit, geo); + size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - + offset + geo->sectors; + if (counter >= state->limit) + break; + put_partition(state, counter + 1, + offset * (blocksize >> 9), + size * (blocksize >> 9)); + counter++; + blk++; + data = read_dev_sector(bdev, + blk * (blocksize/512), + §); + } + + if (!data) + /* Are we not supposed to report this ? */ + goto out_readerr; + } else + printk(KERN_WARNING "Warning, expected Label VOL1 not " + "found, treating as CDL formated Disk"); + } printk("\n"); |