Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / disk / dmraid_nvidia.c
blobfc02f5715ccca528a102fc777f4e68a8d05f4c19
1 /* dmraid_nvidia.c - module to handle Nvidia fakeraid. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/dl.h>
21 #include <grub/disk.h>
22 #include <grub/mm.h>
23 #include <grub/err.h>
24 #include <grub/misc.h>
25 #include <grub/diskfilter.h>
27 GRUB_MOD_LICENSE ("GPLv3+");
29 #define NV_SIGNATURES 4
31 #define NV_IDLE 0
32 #define NV_SCDB_INIT_RAID 2
33 #define NV_SCDB_REBUILD_RAID 3
34 #define NV_SCDB_UPGRADE_RAID 4
35 #define NV_SCDB_SYNC_RAID 5
37 #define NV_LEVEL_UNKNOWN 0x00
38 #define NV_LEVEL_JBOD 0xFF
39 #define NV_LEVEL_0 0x80
40 #define NV_LEVEL_1 0x81
41 #define NV_LEVEL_3 0x83
42 #define NV_LEVEL_5 0x85
43 #define NV_LEVEL_10 0x8a
44 #define NV_LEVEL_1_0 0x8180
46 #define NV_ARRAY_FLAG_BOOT 1 /* BIOS use only. */
47 #define NV_ARRAY_FLAG_ERROR 2 /* Degraded or offline. */
48 #define NV_ARRAY_FLAG_PARITY_VALID 4 /* RAID-3/5 parity valid. */
50 struct grub_nv_array
52 grub_uint32_t version;
53 grub_uint32_t signature[NV_SIGNATURES];
54 grub_uint8_t raid_job_code;
55 grub_uint8_t stripe_width;
56 grub_uint8_t total_volumes;
57 grub_uint8_t original_width;
58 grub_uint32_t raid_level;
59 grub_uint32_t stripe_block_size;
60 grub_uint32_t stripe_block_size_bytes;
61 grub_uint32_t stripe_block_size_log2;
62 grub_uint32_t stripe_mask;
63 grub_uint32_t stripe_size;
64 grub_uint32_t stripe_size_bytes;
65 grub_uint32_t raid_job_mask;
66 grub_uint32_t original_capacity;
67 grub_uint32_t flags;
70 #define NV_ID_LEN 8
71 #define NV_ID_STRING "NVIDIA"
72 #define NV_VERSION 100
74 #define NV_PRODID_LEN 16
75 #define NV_PRODREV_LEN 4
77 struct grub_nv_super
79 char vendor[NV_ID_LEN]; /* 0x00 - 0x07 ID string. */
80 grub_uint32_t size; /* 0x08 - 0x0B Size of metadata in dwords. */
81 grub_uint32_t chksum; /* 0x0C - 0x0F Checksum of this struct. */
82 grub_uint16_t version; /* 0x10 - 0x11 NV version. */
83 grub_uint8_t unit_number; /* 0x12 Disk index in array. */
84 grub_uint8_t reserved; /* 0x13. */
85 grub_uint32_t capacity; /* 0x14 - 0x17 Array capacity in sectors. */
86 grub_uint32_t sector_size; /* 0x18 - 0x1B Sector size. */
87 char prodid[NV_PRODID_LEN]; /* 0x1C - 0x2B Array product ID. */
88 char prodrev[NV_PRODREV_LEN]; /* 0x2C - 0x2F Array product revision */
89 grub_uint32_t unit_flags; /* 0x30 - 0x33 Flags for this disk */
90 struct grub_nv_array array; /* Array information */
91 } GRUB_PACKED;
93 static struct grub_diskfilter_vg *
94 grub_dmraid_nv_detect (grub_disk_t disk,
95 struct grub_diskfilter_pv_id *id,
96 grub_disk_addr_t *start_sector)
98 grub_disk_addr_t sector;
99 struct grub_nv_super sb;
100 int level;
101 grub_uint64_t disk_size;
102 char *uuid;
104 if (disk->partition)
105 /* Skip partition. */
106 return NULL;
108 sector = grub_disk_get_size (disk);
109 if (sector == GRUB_DISK_SIZE_UNKNOWN)
110 /* Not raid. */
111 return NULL;
112 sector -= 2;
113 if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb))
114 return NULL;
116 if (grub_memcmp (sb.vendor, NV_ID_STRING, 6))
117 /* Not raid. */
118 return NULL;
120 if (sb.version != NV_VERSION)
122 grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
123 "unknown version: %d.%d", sb.version);
124 return NULL;
127 switch (sb.array.raid_level)
129 case NV_LEVEL_0:
130 level = 0;
131 disk_size = sb.capacity / sb.array.total_volumes;
132 if (sb.array.total_volumes == 0)
133 /* Not RAID. */
134 return NULL;
135 break;
137 case NV_LEVEL_1:
138 level = 1;
139 disk_size = sb.capacity;
140 break;
142 case NV_LEVEL_5:
143 level = 5;
144 disk_size = sb.capacity / (sb.array.total_volumes - 1);
145 if (sb.array.total_volumes == 0 || sb.array.total_volumes == 1)
146 /* Not RAID. */
147 return NULL;
148 break;
150 default:
151 grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
152 "unsupported RAID level: %d", sb.array.raid_level);
153 return NULL;
156 uuid = grub_malloc (sizeof (sb.array.signature));
157 if (! uuid)
158 return NULL;
160 grub_memcpy (uuid, (char *) &sb.array.signature,
161 sizeof (sb.array.signature));
163 id->uuidlen = 0;
164 id->id = sb.unit_number;
166 *start_sector = 0;
168 return grub_diskfilter_make_raid (sizeof (sb.array.signature),
169 uuid, sb.array.total_volumes,
170 NULL, disk_size,
171 sb.array.stripe_block_size,
172 GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC,
173 level);
176 static struct grub_diskfilter grub_dmraid_nv_dev =
178 .name = "dmraid_nv",
179 .detect = grub_dmraid_nv_detect,
180 .next = 0
183 GRUB_MOD_INIT(dm_nv)
185 grub_diskfilter_register_front (&grub_dmraid_nv_dev);
188 GRUB_MOD_FINI(dm_nv)
190 grub_diskfilter_unregister (&grub_dmraid_nv_dev);