OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [partitions/] [ibm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * File...........: linux/fs/partitions/ibm.c
3
 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4
 *                  Volker Sameske <sameske@de.ibm.com>
5
 * Bugreports.to..: <Linux390@de.ibm.com>
6
 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7
 
8
 * History of changes (starts July 2000)
9
 * 07/10/00 Fixed detection of CMS formatted disks
10
 * 02/13/00 VTOC partition support added
11
 * 12/27/01 fixed PL030593 (CMS reserved minidisk not detected on 64 bit)
12
 */
13
 
14
#include <linux/config.h>
15
#include <linux/fs.h>
16
#include <linux/genhd.h>
17
#include <linux/kernel.h>
18
#include <linux/major.h>
19
#include <linux/string.h>
20
#include <linux/blk.h>
21
#include <linux/slab.h>
22
#include <linux/hdreg.h>
23
#include <linux/ioctl.h>
24
#include <linux/version.h>
25
#include <asm/ebcdic.h>
26
#include <asm/uaccess.h>
27
#include <asm/dasd.h>
28
 
29
#include "ibm.h"
30
#include "check.h"
31
#include <asm/vtoc.h>
32
 
33
/*
34
 * compute the block number from a
35
 * cyl-cyl-head-head structure
36
 */
37
static inline int
38
cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
39
        return ptr->cc * geo->heads * geo->sectors +
40
               ptr->hh * geo->sectors;
41
}
42
 
43
 
44
/*
45
 * compute the block number from a
46
 * cyl-cyl-head-head-block structure
47
 */
48
static inline int
49
cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
50
        return ptr->cc * geo->heads * geo->sectors +
51
                ptr->hh * geo->sectors +
52
                ptr->b;
53
}
54
 
55
/*
56
 * We used to use ioctl_by_bdev in early 2.4, but it broke
57
 * between 2.4.9 and 2.4.18 somewhere.
58
 */
59
extern int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
60
                            unsigned int no, unsigned long data);
61
 
62
static int
63
ibm_ioctl_unopened(struct block_device *bdev, unsigned cmd, unsigned long arg)
64
{
65
        int res;
66
        mm_segment_t old_fs = get_fs();
67
 
68
        if (genhd_dasd_ioctl == NULL)
69
                return -ENODEV;
70
#if 0
71
        lock_kernel();
72
        if (bd_ops->owner)
73
                __MOD_INC_USE_COUNT(bdev->bd_op->owner);
74
        unlock_kernel();
75
#endif
76
        set_fs(KERNEL_DS);
77
        res = (*genhd_dasd_ioctl)(bdev->bd_inode, NULL, cmd, arg);
78
        set_fs(old_fs);
79
#if 0
80
        lock_kernel();
81
        if (bd_ops->owner)
82
                __MOD_DEV_USE_COUNT(bd_ops->owner);
83
        unlock_kernel();
84
#endif
85
        return res;
86
}
87
 
88
/*
89
 */
90
int
91
ibm_partition(struct gendisk *hd, struct block_device *bdev,
92
              unsigned long first_sector, int first_part_minor)
93
{
94
        int blocksize, offset, size;
95
        dasd_information_t *info;
96
        struct hd_geometry *geo;
97
        char type[5] = {0,};
98
        char name[7] = {0,};
99
        volume_label_t *vlabel;
100
        unsigned char *data;
101
        Sector sect;
102
 
103
        if ( first_sector != 0 )
104
                BUG();
105
 
106
        if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
107
                goto out_noinfo;
108
        if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
109
                goto out_nogeo;
110
        if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
111
                goto out_novlab;
112
 
113
        if (ibm_ioctl_unopened(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
114
            ibm_ioctl_unopened(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
115
                goto out_noioctl;
116
 
117
        if ((blocksize = get_hardsect_size(to_kdev_t(bdev->bd_dev))) <= 0)
118
                goto out_badsect;
119
 
120
        /*
121
         * Get volume label, extract name and type.
122
         */
123
        data = read_dev_sector(bdev, info->label_block*(blocksize/512), &sect);
124
        if (data == NULL)
125
                goto out_readerr;
126
        strncpy (type, data, 4);
127
        if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD")))
128
                strncpy(name, data + 8, 6);
129
        else
130
                strncpy(name, data + 4, 6);
131
        memcpy (vlabel, data, sizeof(volume_label_t));
132
        put_dev_sector(sect);
133
 
134
        EBCASC(type, 4);
135
        EBCASC(name, 6);
136
 
137
        /*
138
         * Three different types: CMS1, VOL1 and LNX1/unlabeled
139
         */
140
        if (strncmp(type, "CMS1", 4) == 0) {
141
                /*
142
                 * VM style CMS1 labeled disk
143
                 */
144
                int *label = (int *) data;
145
 
146
                if (label[13] != 0) {
147
                        printk("CMS1/%8s(MDSK):", name);
148
                        /* disk is reserved minidisk */
149
                        blocksize = label[3];
150
                        offset = label[13];
151
                        size = (label[7] - 1)*(blocksize >> 9);
152
                } else {
153
                        printk("CMS1/%8s:", name);
154
                        offset = (info->label_block + 1);
155
                        size = bdev->bd_inode->i_size >> 9;
156
                }
157
                // add_gd_partition(hd, first_part_minor - 1, 0, size);
158
                add_gd_partition(hd, first_part_minor,
159
                                 offset*(blocksize >> 9),
160
                                 size-offset*(blocksize >> 9));
161
        } else if (strncmp(type, "VOL1", 4) == 0) {
162
                /*
163
                 * New style VOL1 labeled disk
164
                 */
165
                unsigned int blk;
166
                int counter;
167
 
168
                printk("VOL1/%8s:", name);
169
 
170
                /* get block number and read then go through format1 labels */
171
                blk = cchhb2blk(&vlabel->vtoc, geo) + 1;
172
                counter = 0;
173
                while ((data = read_dev_sector(bdev, blk*(blocksize/512),
174
                                               &sect)) != NULL) {
175
                        format1_label_t f1;
176
 
177
                        memcpy(&f1, data, sizeof(format1_label_t));
178
                        put_dev_sector(sect);
179
 
180
                        /* skip FMT4 / FMT5 / FMT7 labels */
181
                        if (f1.DS1FMTID == _ascebc['4']
182
                            || f1.DS1FMTID == _ascebc['5']
183
                            || f1.DS1FMTID == _ascebc['7']) {
184
                                blk++;
185
                                continue;
186
                        }
187
 
188
                        /* only FMT1 valid at this point */
189
                        if (f1.DS1FMTID != _ascebc['1'])
190
                                break;
191
 
192
                        /* OK, we got valid partition data */
193
                        offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
194
                        size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
195
                                offset + geo->sectors;
196
                        if (counter >= hd->max_p)
197
                                break;
198
                        add_gd_partition(hd, first_part_minor + counter,
199
                                         offset * (blocksize >> 9),
200
                                         size * (blocksize >> 9));
201
                        counter++;
202
                        blk++;
203
                }
204
        } else {
205
                /*
206
                 * Old style LNX1 or unlabeled disk
207
                 */
208
                if (strncmp(type, "LNX1", 4) == 0)
209
                        printk ("LNX1/%8s:", name);
210
                else
211
                        printk("(nonl)/%8s:", name);
212
                offset = (info->label_block + 1);
213
                size = (bdev->bd_inode->i_size >> 9);
214
                // add_gd_partition(hd, first_part_minor - 1, 0, size);
215
                add_gd_partition(hd, first_part_minor,
216
                                 offset*(blocksize >> 9),
217
                                  size-offset*(blocksize >> 9));
218
        }
219
 
220
        printk("\n");
221
        kfree(vlabel);
222
        kfree(geo);
223
        kfree(info);
224
        return 1;
225
 
226
out_readerr:
227
out_badsect:
228
out_noioctl:
229
        kfree(vlabel);
230
out_novlab:
231
        kfree(geo);
232
out_nogeo:
233
        kfree(info);
234
out_noinfo:
235
        return 0;
236
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.