mmc: core: keep consistent with upstream
[firefly-linux-kernel-4.4.55.git] / block / partitions / check.c
1 /*
2  *  fs/partitions/check.c
3  *
4  *  Code extracted from drivers/block/genhd.c
5  *  Copyright (C) 1991-1998  Linus Torvalds
6  *  Re-organised Feb 1998 Russell King
7  *
8  *  We now have independent partition support from the
9  *  block drivers, which allows all the partition code to
10  *  be grouped in one location, and it to be mostly self
11  *  contained.
12  *
13  *  Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl}
14  */
15
16 #include <linux/slab.h>
17 #include <linux/vmalloc.h>
18 #include <linux/ctype.h>
19 #include <linux/genhd.h>
20
21 #include "check.h"
22
23 #include "rk.h"
24 #include "acorn.h"
25 #include "amiga.h"
26 #include "atari.h"
27 #include "ldm.h"
28 #include "mac.h"
29 #include "msdos.h"
30 #include "osf.h"
31 #include "sgi.h"
32 #include "sun.h"
33 #include "ibm.h"
34 #include "ultrix.h"
35 #include "efi.h"
36 #include "karma.h"
37 #include "sysv68.h"
38 #include "cmdline.h"
39
40 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
41
42 static int (*check_part[])(struct parsed_partitions *) = {
43         /*
44          * Probe partition formats with tables at disk address 0
45          * that also have an ADFS boot block at 0xdc0.
46          */
47 #ifdef CONFIG_ACORN_PARTITION_ICS
48         adfspart_check_ICS,
49 #endif
50 #ifdef CONFIG_ACORN_PARTITION_POWERTEC
51         adfspart_check_POWERTEC,
52 #endif
53 #ifdef CONFIG_ACORN_PARTITION_EESOX
54         adfspart_check_EESOX,
55 #endif
56
57         /*
58          * Now move on to formats that only have partition info at
59          * disk address 0xdc0.  Since these may also have stale
60          * PC/BIOS partition tables, they need to come before
61          * the msdos entry.
62          */
63 #ifdef CONFIG_ACORN_PARTITION_CUMANA
64         adfspart_check_CUMANA,
65 #endif
66 #ifdef CONFIG_ACORN_PARTITION_ADFS
67         adfspart_check_ADFS,
68 #endif
69
70 #ifdef CONFIG_RK_PARTITION
71         rkpart_partition,
72 #endif
73 #ifdef CONFIG_CMDLINE_PARTITION
74         cmdline_partition,
75 #endif
76 #ifdef CONFIG_EFI_PARTITION
77         efi_partition,          /* this must come before msdos */
78 #endif
79 #ifdef CONFIG_SGI_PARTITION
80         sgi_partition,
81 #endif
82 #ifdef CONFIG_LDM_PARTITION
83         ldm_partition,          /* this must come before msdos */
84 #endif
85 #ifdef CONFIG_MSDOS_PARTITION
86         msdos_partition,
87 #endif
88 #ifdef CONFIG_OSF_PARTITION
89         osf_partition,
90 #endif
91 #ifdef CONFIG_SUN_PARTITION
92         sun_partition,
93 #endif
94 #ifdef CONFIG_AMIGA_PARTITION
95         amiga_partition,
96 #endif
97 #ifdef CONFIG_ATARI_PARTITION
98         atari_partition,
99 #endif
100 #ifdef CONFIG_MAC_PARTITION
101         mac_partition,
102 #endif
103 #ifdef CONFIG_ULTRIX_PARTITION
104         ultrix_partition,
105 #endif
106 #ifdef CONFIG_IBM_PARTITION
107         ibm_partition,
108 #endif
109 #ifdef CONFIG_KARMA_PARTITION
110         karma_partition,
111 #endif
112 #ifdef CONFIG_SYSV68_PARTITION
113         sysv68_partition,
114 #endif
115         NULL
116 };
117
118 static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
119 {
120         struct parsed_partitions *state;
121         int nr;
122
123         state = kzalloc(sizeof(*state), GFP_KERNEL);
124         if (!state)
125                 return NULL;
126
127         nr = disk_max_parts(hd);
128         state->parts = vzalloc(nr * sizeof(state->parts[0]));
129         if (!state->parts) {
130                 kfree(state);
131                 return NULL;
132         }
133
134         state->limit = nr;
135
136         return state;
137 }
138
139 void free_partitions(struct parsed_partitions *state)
140 {
141         vfree(state->parts);
142         kfree(state);
143 }
144
145 struct parsed_partitions *
146 check_partition(struct gendisk *hd, struct block_device *bdev)
147 {
148         struct parsed_partitions *state;
149         int i, res, err;
150
151         state = allocate_partitions(hd);
152         if (!state)
153                 return NULL;
154         state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
155         if (!state->pp_buf) {
156                 free_partitions(state);
157                 return NULL;
158         }
159         state->pp_buf[0] = '\0';
160
161         state->bdev = bdev;
162         disk_name(hd, 0, state->name);
163         snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
164         if (isdigit(state->name[strlen(state->name)-1]))
165                 sprintf(state->name, "p");
166
167         i = res = err = 0;
168         while (!res && check_part[i]) {
169                 memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
170                 res = check_part[i++](state);
171                 if (res < 0) {
172                         /* We have hit an I/O error which we don't report now.
173                         * But record it, and let the others do their job.
174                         */
175                         err = res;
176                         res = 0;
177                 }
178
179         }
180         if (res > 0) {
181                 printk(KERN_INFO "%s", state->pp_buf);
182
183                 free_page((unsigned long)state->pp_buf);
184                 return state;
185         }
186         if (state->access_beyond_eod)
187                 err = -ENOSPC;
188         if (err)
189         /* The partition is unrecognized. So report I/O errors if there were any */
190                 res = err;
191         if (res) {
192                 if (warn_no_part)
193                         strlcat(state->pp_buf,
194                                 " unable to read partition table\n", PAGE_SIZE);
195                 printk(KERN_INFO "%s", state->pp_buf);
196         }
197
198         free_page((unsigned long)state->pp_buf);
199         free_partitions(state);
200         return ERR_PTR(res);
201 }