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 #ifdef CONFIG_BLK_DEV_IDE
118 extern void ide_xlate_1024(dev_t);
119 #endif
120
121 read_mbr:
122 if (!(bh = bread(dev,0,1024))) {
123 printk("unable to read partition table\n");
124 return -1;
125 }
126 if (*(unsigned short *) (0x1fe + bh->b_data) != 0xAA55) {
127 brelse(bh);
128 return 0;
129 }
130 p = (struct partition *) (0x1be + bh->b_data);
131
132
133
134
135 if (p->sys_ind == DM6_PARTITION && !found_dm6++)
136 {
137 printk(" [DM6:DDO]");
138
139
140
141
142
143
144
145
146
147
148
149
150
151 first_sector += p->end_sector;
152 hd->part[MINOR(dev)].start_sect += p->end_sector;
153 hd->part[MINOR(dev)].nr_sects -= p->end_sector;
154 #ifdef CONFIG_BLK_DEV_IDE
155 ide_xlate_1024(dev);
156 #endif
157 bh->b_dirt = 0;
158 bh->b_uptodate = 0;
159 bh->b_req = 0;
160 brelse(bh);
161 goto read_mbr;
162 }
163
164
165
166
167 if (p->sys_ind == DM6_AUXPARTITION) {
168 printk(" [DM6]");
169 #ifdef CONFIG_BLK_DEV_IDE
170 ide_xlate_1024(dev);
171 #endif
172 }
173
174 current_minor += 4;
175 for (i=1 ; i<=4 ; minor++,i++,p++) {
176 if (!p->nr_sects)
177 continue;
178 add_partition(hd, minor, first_sector+p->start_sect, p->nr_sects);
179 if ((current_minor & 0x3f) >= 60)
180 continue;
181 if (p->sys_ind == EXTENDED_PARTITION) {
182 printk(" <");
183 extended_partition(hd, (hd->major << 8) | minor);
184 printk(" >");
185 }
186 }
187
188
189
190 if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
191 p = (struct partition *) (0x1be + bh->b_data);
192 for (i = 4 ; i < 16 ; i++, current_minor++) {
193 p--;
194 if ((current_minor & mask) >= mask-2)
195 break;
196 if (!(p->start_sect && p->nr_sects))
197 continue;
198 add_partition(hd, current_minor, p->start_sect, p->nr_sects);
199 }
200 }
201 printk("\n");
202 brelse(bh);
203 return 1;
204 }
205
206 #endif
207
208 #ifdef CONFIG_OSF_PARTITION
209
210 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
211 {
212 int i;
213 struct buffer_head *bh;
214 struct disklabel {
215 u32 d_magic;
216 u16 d_type,d_subtype;
217 u8 d_typename[16];
218 u8 d_packname[16];
219 u32 d_secsize;
220 u32 d_nsectors;
221 u32 d_ntracks;
222 u32 d_ncylinders;
223 u32 d_secpercyl;
224 u32 d_secprtunit;
225 u16 d_sparespertrack;
226 u16 d_sparespercyl;
227 u32 d_acylinders;
228 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
229 u32 d_headswitch, d_trkseek, d_flags;
230 u32 d_drivedata[5];
231 u32 d_spare[5];
232 u32 d_magic2;
233 u16 d_checksum;
234 u16 d_npartitions;
235 u32 d_bbsize, d_sbsize;
236 struct d_partition {
237 u32 p_size;
238 u32 p_offset;
239 u32 p_fsize;
240 u8 p_fstype;
241 u8 p_frag;
242 u16 p_cpg;
243 } d_partitions[8];
244 } * label;
245 struct d_partition * partition;
246 #define DISKLABELMAGIC (0x82564557UL)
247
248 if (!(bh = bread(dev,0,1024))) {
249 printk("unable to read partition table\n");
250 return -1;
251 }
252 label = (struct disklabel *) (bh->b_data+64);
253 partition = label->d_partitions;
254 if (label->d_magic != DISKLABELMAGIC) {
255 printk("magic: %08x\n", label->d_magic);
256 brelse(bh);
257 return 0;
258 }
259 if (label->d_magic2 != DISKLABELMAGIC) {
260 printk("magic2: %08x\n", label->d_magic2);
261 brelse(bh);
262 return 0;
263 }
264 for (i = 0 ; i < label->d_npartitions; i++, partition++) {
265 if (partition->p_size)
266 add_partition(hd, current_minor,
267 first_sector+partition->p_offset,
268 partition->p_size);
269 current_minor++;
270 }
271 printk("\n");
272 brelse(bh);
273 return 1;
274 }
275
276 #endif
277
278 static void check_partition(struct gendisk *hd, unsigned int dev)
279 {
280 static int first_time = 1;
281 unsigned long first_sector;
282
283 if (first_time)
284 printk("Partition check:\n");
285 first_time = 0;
286 first_sector = hd->part[MINOR(dev)].start_sect;
287
288
289
290
291
292 if ((int)first_sector == -1) {
293 hd->part[MINOR(dev)].start_sect = 0;
294 return;
295 }
296
297 printk(" %s%c:", hd->major_name, minor_name(hd, MINOR(dev)));
298 #ifdef CONFIG_MSDOS_PARTITION
299 if (msdos_partition(hd, dev, first_sector))
300 return;
301 #endif
302 #ifdef CONFIG_OSF_PARTITION
303 if (osf_partition(hd, dev, first_sector))
304 return;
305 #endif
306 printk("unknown partition table\n");
307 }
308
309
310
311
312
313
314
315
316
317
318 void resetup_one_dev(struct gendisk *dev, int drive)
319 {
320 int i;
321 int start = drive<<dev->minor_shift;
322 int j = start + dev->max_p;
323 int major = dev->major << 8;
324
325 current_minor = 1+(drive<<dev->minor_shift);
326 check_partition(dev, major+(drive<<dev->minor_shift));
327
328 for (i=start ; i < j ; i++)
329 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
330 }
331
332 static void setup_dev(struct gendisk *dev)
333 {
334 int i;
335 int j = dev->max_nr * dev->max_p;
336 int major = dev->major << 8;
337 int drive;
338
339
340 for (i = 0 ; i < j; i++) {
341 dev->part[i].start_sect = 0;
342 dev->part[i].nr_sects = 0;
343 }
344 dev->init();
345 for (drive=0 ; drive<dev->nr_real ; drive++) {
346 current_minor = 1+(drive<<dev->minor_shift);
347 check_partition(dev, major+(drive<<dev->minor_shift));
348 }
349 for (i=0 ; i < j ; i++)
350 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
351 blk_size[dev->major] = dev->sizes;
352 }
353
354 void device_setup(void)
355 {
356 struct gendisk *p;
357 int nr=0;
358
359 for (p = gendisk_head ; p ; p=p->next) {
360 setup_dev(p);
361 nr += p->nr_real;
362 }
363
364 if (ramdisk_size)
365 rd_load();
366 }