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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [partitions/] [ibm.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 
9
#include <linux/buffer_head.h>
10
#include <linux/hdreg.h>
11
#include <linux/slab.h>
12
#include <asm/dasd.h>
13
#include <asm/ebcdic.h>
14
#include <asm/uaccess.h>
15
#include <asm/vtoc.h>
16
 
17
#include "check.h"
18
#include "ibm.h"
19
 
20
/*
21
 * compute the block number from a
22
 * cyl-cyl-head-head structure
23
 */
24
static inline int
25
cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
26
        return ptr->cc * geo->heads * geo->sectors +
27
               ptr->hh * geo->sectors;
28
}
29
 
30
/*
31
 * compute the block number from a
32
 * cyl-cyl-head-head-block structure
33
 */
34
static inline int
35
cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
36
        return ptr->cc * geo->heads * geo->sectors +
37
                ptr->hh * geo->sectors +
38
                ptr->b;
39
}
40
 
41
/*
42
 */
43
int
44
ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
45
{
46
        int blocksize, offset, size,res;
47
        loff_t i_size;
48
        dasd_information2_t *info;
49
        struct hd_geometry *geo;
50
        char type[5] = {0,};
51
        char name[7] = {0,};
52
        union label_t {
53
                struct vtoc_volume_label vol;
54
                struct vtoc_cms_label cms;
55
        } *label;
56
        unsigned char *data;
57
        Sector sect;
58
 
59
        res = 0;
60
        blocksize = bdev_hardsect_size(bdev);
61
        if (blocksize <= 0)
62
                goto out_exit;
63
        i_size = i_size_read(bdev->bd_inode);
64
        if (i_size == 0)
65
                goto out_exit;
66
 
67
        info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
68
        if (info == NULL)
69
                goto out_exit;
70
        geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL);
71
        if (geo == NULL)
72
                goto out_nogeo;
73
        label = kmalloc(sizeof(union label_t), GFP_KERNEL);
74
        if (label == NULL)
75
                goto out_nolab;
76
 
77
        if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 ||
78
            ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
79
                goto out_freeall;
80
 
81
        /*
82
         * Get volume label, extract name and type.
83
         */
84
        data = read_dev_sector(bdev, info->label_block*(blocksize/512), &sect);
85
        if (data == NULL)
86
                goto out_readerr;
87
 
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));
94
        put_dev_sector(sect);
95
 
96
        EBCASC(type, 4);
97
        EBCASC(name, 6);
98
 
99
        res = 1;
100
 
101
        /*
102
         * Three different formats: LDL, CDL and unformated disk
103
         *
104
         * identified by info->format
105
         *
106
         * unformated disks we do not have to care about
107
         */
108
        if (info->format == DASD_FORMAT_LDL) {
109
                if (strncmp(type, "CMS1", 4) == 0) {
110
                        /*
111
                         * VM style CMS1 labeled disk
112
                         */
113
                        if (label->cms.disk_offset != 0) {
114
                                printk("CMS1/%8s(MDSK):", name);
115
                                /* disk is reserved minidisk */
116
                                blocksize = label->cms.block_size;
117
                                offset = label->cms.disk_offset;
118
                                size = (label->cms.block_count - 1)
119
                                        * (blocksize >> 9);
120
                        } else {
121
                                printk("CMS1/%8s:", name);
122
                                offset = (info->label_block + 1);
123
                                size = i_size >> 9;
124
                        }
125
                } else {
126
                        /*
127
                         * Old style LNX1 or unlabeled disk
128
                         */
129
                        if (strncmp(type, "LNX1", 4) == 0)
130
                                printk ("LNX1/%8s:", name);
131
                        else
132
                                printk("(nonl)");
133
                        offset = (info->label_block + 1);
134
                        size = i_size >> 9;
135
                }
136
                put_partition(state, 1, offset*(blocksize >> 9),
137
                                      size-offset*(blocksize >> 9));
138
        } else if (info->format == DASD_FORMAT_CDL) {
139
                /*
140
                 * New style CDL formatted disk
141
                 */
142
                unsigned int blk;
143
                int counter;
144
 
145
                /*
146
                 * check if VOL1 label is available
147
                 * if not, something is wrong, skipping partition detection
148
                 */
149
                if (strncmp(type, "VOL1",  4) == 0) {
150
                        printk("VOL1/%8s:", name);
151
                        /*
152
                         * get block number and read then go through format1
153
                         * labels
154
                         */
155
                        blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
156
                        counter = 0;
157
                        data = read_dev_sector(bdev, blk * (blocksize/512),
158
                                               &sect);
159
                        while (data != NULL) {
160
                                struct vtoc_format1_label f1;
161
 
162
                                memcpy(&f1, data,
163
                                       sizeof(struct vtoc_format1_label));
164
                                put_dev_sector(sect);
165
 
166
                                /* skip FMT4 / FMT5 / FMT7 labels */
167
                                if (f1.DS1FMTID == _ascebc['4']
168
                                    || f1.DS1FMTID == _ascebc['5']
169
                                    || f1.DS1FMTID == _ascebc['7']) {
170
                                        blk++;
171
                                        data = read_dev_sector(bdev, blk *
172
                                                               (blocksize/512),
173
                                                                &sect);
174
                                        continue;
175
                                }
176
 
177
                                /* only FMT1 valid at this point */
178
                                if (f1.DS1FMTID != _ascebc['1'])
179
                                        break;
180
 
181
                                /* OK, we got valid partition data */
182
                                offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
183
                                size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
184
                                        offset + geo->sectors;
185
                                if (counter >= state->limit)
186
                                        break;
187
                                put_partition(state, counter + 1,
188
                                              offset * (blocksize >> 9),
189
                                              size * (blocksize >> 9));
190
                                counter++;
191
                                blk++;
192
                                data = read_dev_sector(bdev,
193
                                                       blk * (blocksize/512),
194
                                                       &sect);
195
                        }
196
 
197
                        if (!data)
198
                                /* Are we not supposed to report this ? */
199
                                goto out_readerr;
200
                } else
201
                        printk(KERN_WARNING "Warning, expected Label VOL1 not "
202
                               "found, treating as CDL formated Disk");
203
 
204
        }
205
 
206
        printk("\n");
207
        goto out_freeall;
208
 
209
 
210
out_readerr:
211
        res = -1;
212
out_freeall:
213
        kfree(label);
214
out_nolab:
215
        kfree(geo);
216
out_nogeo:
217
        kfree(info);
218
out_exit:
219
        return res;
220
}

powered by: WebSVN 2.1.0

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