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