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