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