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