This source file includes following definitions.
- minor_name
- add_partition
- extended_partition
- msdos_partition
- osf_partition
- check_partition
- resetup_one_dev
- setup_dev
- device_setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <linux/fs.h>
19 #include <linux/genhd.h>
20 #include <linux/kernel.h>
21 #include <linux/major.h>
22
23 struct gendisk *gendisk_head = NULL;
24
25 static int current_minor = 0;
26 extern int *blk_size[];
27 extern void rd_load(void);
28 extern int ramdisk_size;
29
30 static char minor_name (struct gendisk *hd, int minor)
31 {
32 char base_name = (hd->major == IDE1_MAJOR) ? 'c' : 'a';
33 return base_name + (minor >> hd->minor_shift);
34 }
35
36 static void add_partition (struct gendisk *hd, int minor, int start, int size)
37 {
38 hd->part[minor].start_sect = start;
39 hd->part[minor].nr_sects = size;
40 printk(" %s%c%d", hd->major_name, minor_name(hd, minor),
41 minor & ((1 << hd->minor_shift) - 1));
42 }
43
44 #ifdef CONFIG_MSDOS_PARTITION
45
46
47
48
49
50
51
52
53
54
55
56 static void extended_partition(struct gendisk *hd, int dev)
57 {
58 struct buffer_head *bh;
59 struct partition *p;
60 unsigned long first_sector, this_sector;
61 int mask = (1 << hd->minor_shift) - 1;
62
63 first_sector = hd->part[MINOR(dev)].start_sect;
64 this_sector = first_sector;
65
66 while (1) {
67 if ((current_minor & mask) >= (4 + hd->max_p))
68 return;
69 if (!(bh = bread(dev,0,1024)))
70 return;
71
72
73
74
75 bh->b_dirt = 0;
76 bh->b_uptodate = 0;
77 bh->b_req = 0;
78 if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
79 p = (struct partition *) (0x1BE + bh->b_data);
80
81
82
83
84 if (p->sys_ind == EXTENDED_PARTITION || !p->nr_sects)
85 goto done;
86 add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
87 current_minor++;
88 p++;
89
90
91
92
93
94
95
96 if (p->sys_ind != EXTENDED_PARTITION ||
97 !(hd->part[current_minor].nr_sects = p->nr_sects))
98 goto done;
99 hd->part[current_minor].start_sect = first_sector + p->start_sect;
100 hd->sizes[current_minor] = p->nr_sects >> (BLOCK_SIZE_BITS - 9);
101 this_sector = first_sector + p->start_sect;
102 dev = ((hd->major) << 8) | current_minor;
103 brelse(bh);
104 } else
105 goto done;
106 }
107 done:
108 brelse(bh);
109 }
110
111 static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
112 {
113 int i, minor = current_minor, found_dm6 = 0;
114 struct buffer_head *bh;
115 struct partition *p;
116 int mask = (1 << hd->minor_shift) - 1;
117 extern void ide_xlate_1024(dev_t);
118
119 read_mbr:
120 if (!(bh = bread(dev,0,1024))) {
121 printk("unable to read partition table\n");
122 return -1;
123 }
124 if (*(unsigned short *) (0x1fe + bh->b_data) != 0xAA55) {
125 brelse(bh);
126 return 0;
127 }
128 p = (struct partition *) (0x1be + bh->b_data);
129
130
131
132
133 if (p->sys_ind == DM6_PARTITION && !found_dm6++)
134 {
135 printk(" [DM6:DDO]");
136
137
138
139
140
141
142
143
144
145
146
147
148
149 first_sector += p->end_sector;
150 hd->part[MINOR(dev)].start_sect += p->end_sector;
151 hd->part[MINOR(dev)].nr_sects -= p->end_sector;
152 ide_xlate_1024(dev);
153 bh->b_dirt = 0;
154 bh->b_uptodate = 0;
155 bh->b_req = 0;
156 brelse(bh);
157 goto read_mbr;
158 }
159
160
161
162
163 if (p->sys_ind == DM6_AUXPARTITION) {
164 printk(" [DM6]");
165 ide_xlate_1024(dev);
166 }
167
168 current_minor += 4;
169 for (i=1 ; i<=4 ; minor++,i++,p++) {
170 if (!p->nr_sects)
171 continue;
172 add_partition(hd, minor, first_sector+p->start_sect, p->nr_sects);
173 if ((current_minor & 0x3f) >= 60)
174 continue;
175 if (p->sys_ind == EXTENDED_PARTITION) {
176 printk(" <");
177 extended_partition(hd, (hd->major << 8) | minor);
178 printk(" >");
179 }
180 }
181
182
183
184 if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
185 p = (struct partition *) (0x1be + bh->b_data);
186 for (i = 4 ; i < 16 ; i++, current_minor++) {
187 p--;
188 if ((current_minor & mask) >= mask-2)
189 break;
190 if (!(p->start_sect && p->nr_sects))
191 continue;
192 add_partition(hd, current_minor, p->start_sect, p->nr_sects);
193 }
194 }
195 printk("\n");
196 brelse(bh);
197 return 1;
198 }
199
200 #endif
201
202 #ifdef CONFIG_OSF_PARTITION
203
204 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
205 {
206 int i;
207 struct buffer_head *bh;
208 struct disklabel {
209 u32 d_magic;
210 u16 d_type,d_subtype;
211 u8 d_typename[16];
212 u8 d_packname[16];
213 u32 d_secsize;
214 u32 d_nsectors;
215 u32 d_ntracks;
216 u32 d_ncylinders;
217 u32 d_secpercyl;
218 u32 d_secprtunit;
219 u16 d_sparespertrack;
220 u16 d_sparespercyl;
221 u32 d_acylinders;
222 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
223 u32 d_headswitch, d_trkseek, d_flags;
224 u32 d_drivedata[5];
225 u32 d_spare[5];
226 u32 d_magic2;
227 u16 d_checksum;
228 u16 d_npartitions;
229 u32 d_bbsize, d_sbsize;
230 struct d_partition {
231 u32 p_size;
232 u32 p_offset;
233 u32 p_fsize;
234 u8 p_fstype;
235 u8 p_frag;
236 u16 p_cpg;
237 } d_partitions[8];
238 } * label;
239 struct d_partition * partition;
240 #define DISKLABELMAGIC (0x82564557UL)
241
242 if (!(bh = bread(dev,0,1024))) {
243 printk("unable to read partition table\n");
244 return -1;
245 }
246 label = (struct disklabel *) (bh->b_data+64);
247 partition = label->d_partitions;
248 if (label->d_magic != DISKLABELMAGIC) {
249 printk("magic: %08x\n", label->d_magic);
250 brelse(bh);
251 return 0;
252 }
253 if (label->d_magic2 != DISKLABELMAGIC) {
254 printk("magic2: %08x\n", label->d_magic2);
255 brelse(bh);
256 return 0;
257 }
258 for (i = 0 ; i < label->d_npartitions; i++, partition++) {
259 if (partition->p_size)
260 add_partition(hd, current_minor,
261 first_sector+partition->p_offset,
262 partition->p_size);
263 current_minor++;
264 }
265 printk("\n");
266 brelse(bh);
267 return 1;
268 }
269
270 #endif
271
272 static void check_partition(struct gendisk *hd, unsigned int dev)
273 {
274 static int first_time = 1;
275 unsigned long first_sector;
276
277 if (first_time)
278 printk("Partition check:\n");
279 first_time = 0;
280 first_sector = hd->part[MINOR(dev)].start_sect;
281
282
283
284
285
286 if ((int)first_sector == -1) {
287 hd->part[MINOR(dev)].start_sect = 0;
288 return;
289 }
290
291 printk(" %s%c:", hd->major_name, minor_name(hd, MINOR(dev)));
292 #ifdef CONFIG_MSDOS_PARTITION
293 if (msdos_partition(hd, dev, first_sector))
294 return;
295 #endif
296 #ifdef CONFIG_OSF_PARTITION
297 if (osf_partition(hd, dev, first_sector))
298 return;
299 #endif
300 printk("unknown partition table\n");
301 }
302
303
304
305
306
307
308
309
310
311
312 void resetup_one_dev(struct gendisk *dev, int drive)
313 {
314 int i;
315 int start = drive<<dev->minor_shift;
316 int j = start + dev->max_p;
317 int major = dev->major << 8;
318
319 current_minor = 1+(drive<<dev->minor_shift);
320 check_partition(dev, major+(drive<<dev->minor_shift));
321
322 for (i=start ; i < j ; i++)
323 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
324 }
325
326 static void setup_dev(struct gendisk *dev)
327 {
328 int i;
329 int j = dev->max_nr * dev->max_p;
330 int major = dev->major << 8;
331 int drive;
332
333
334 for (i = 0 ; i < j; i++) {
335 dev->part[i].start_sect = 0;
336 dev->part[i].nr_sects = 0;
337 }
338 dev->init();
339 for (drive=0 ; drive<dev->nr_real ; drive++) {
340 current_minor = 1+(drive<<dev->minor_shift);
341 check_partition(dev, major+(drive<<dev->minor_shift));
342 }
343 for (i=0 ; i < j ; i++)
344 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
345 blk_size[dev->major] = dev->sizes;
346 }
347
348 void device_setup(void)
349 {
350 struct gendisk *p;
351 int nr=0;
352
353 for (p = gendisk_head ; p ; p=p->next) {
354 setup_dev(p);
355 nr += p->nr_real;
356 }
357
358 if (ramdisk_size)
359 rd_load();
360 }