blob: 087133d264c002c8ae596008f345030071f6e7ed [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * Support for harddisk partitions.
26 *
27 * To be compatible with LinuxPPC and Apple we use the standard Apple
28 * SCSI disk partitioning scheme. For more information see:
29 * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
30 */
31
32#include <common.h>
33#include <command.h>
34#include <ide.h>
35#include <cmd_disk.h>
36#include "part_mac.h"
37
38#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_MAC_PARTITION)
39
40/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
41#ifndef __ldiv_t_defined
42typedef struct {
43 long int quot; /* Quotient */
44 long int rem; /* Remainder */
45} ldiv_t;
46extern ldiv_t ldiv (long int __numer, long int __denom);
47# define __ldiv_t_defined 1
48#endif
49
50
51static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p);
52static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p);
53
54/*
55 * Test for a valid MAC partition
56 */
57int test_part_mac (block_dev_desc_t *dev_desc)
58{
59 mac_driver_desc_t ddesc;
60 mac_partition_t mpart;
61 ulong i, n;
62
63 if (part_mac_read_ddb (dev_desc, &ddesc)) {
64 /* error reading Driver Desriptor Block, or no valid Signature */
65 return (-1);
66 }
67
68 n = 1; /* assuming at least one partition */
69 for (i=1; i<=n; ++i) {
70 if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) ||
71 (mpart.signature != MAC_PARTITION_MAGIC) ) {
72 return (-1);
73 }
74 /* update partition count */
75 n = mpart.map_count;
76 }
77 return (0);
78}
79
80
81void print_part_mac (block_dev_desc_t *dev_desc)
82{
83 ulong i, n;
84 mac_driver_desc_t ddesc;
85 mac_partition_t mpart;
86 ldiv_t mb, gb;
87
88 if (part_mac_read_ddb (dev_desc, &ddesc)) {
89 /* error reading Driver Desriptor Block, or no valid Signature */
90 return;
91 }
92
93 n = ddesc.blk_count;
94
95 mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */
96 /* round to 1 digit */
97 mb.rem *= 10 * ddesc.blk_size;
98 mb.rem += 512 * 1024;
99 mb.rem /= 1024 * 1024;
100
101 gb = ldiv(10 * mb.quot + mb.rem, 10240);
102 gb.rem += 512;
103 gb.rem /= 1024;
104
105
106 printf ("Block Size=%d, Number of Blocks=%d, "
107 "Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
108 "DeviceType=0x%x, DeviceId=0x%x\n\n"
109 " #: type name"
110 " length base (size)\n",
111 ddesc.blk_size,
112 ddesc.blk_count,
113 mb.quot, mb.rem, gb.quot, gb.rem,
114 ddesc.dev_type, ddesc.dev_id
115 );
116
117 n = 1; /* assuming at least one partition */
118 for (i=1; i<=n; ++i) {
119 ulong bytes;
120 char c;
121
122 printf ("%4ld: ", i);
123 if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) {
124 printf ("** Can't read Partition Map on %d:%ld **\n",
125 dev_desc->dev, i);
126 return;
127 }
128
129 if (mpart.signature != MAC_PARTITION_MAGIC) {
130 printf ("** Bad Signature on %d:%ld - "
131 "expected 0x%04x, got 0x%04x\n",
132 dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature);
133 return;
134 }
135
136 /* update partition count */
137 n = mpart.map_count;
138
139 c = 'k';
140 bytes = mpart.block_count;
141 bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */
142 if (bytes >= 1024) {
143 bytes >>= 10;
144 c = 'M';
145 }
146 if (bytes >= 1024) {
147 bytes >>= 10;
148 c = 'G';
149 }
150
151 printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
152 mpart.type,
153 mpart.name,
154 mpart.block_count,
155 mpart.start_block,
156 bytes, c
157 );
158 }
159
160 return;
161}
162
163
164/*
165 * Read Device Descriptor Block
166 */
167static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)
168{
169 if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) {
170 printf ("** Can't read Driver Desriptor Block **\n");
171 return (-1);
172 }
173
174 if (ddb_p->signature != MAC_DRIVER_MAGIC) {
175#if 0
176 printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n",
177 MAC_DRIVER_MAGIC, ddb_p->signature);
178#endif
179 return (-1);
180 }
181 return (0);
182}
183
184/*
185 * Read Partition Descriptor Block
186 */
187static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)
188{
189 int n = 1;
190
191 for (;;) {
192 /*
wdenk8bde7f72003-06-27 21:31:46 +0000193 * We must always read the descritpor block for
194 * partition 1 first since this is the only way to
195 * know how many partitions we have.
wdenkfe8c2802002-11-03 00:38:21 +0000196 */
197 if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {
198 printf ("** Can't read Partition Map on %d:%d **\n",
199 dev_desc->dev, n);
200 return (-1);
201 }
202
203 if (pdb_p->signature != MAC_PARTITION_MAGIC) {
204 printf ("** Bad Signature on %d:%d: "
205 "expected 0x%04x, got 0x%04x\n",
206 dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
207 return (-1);
208 }
209
210 if (n == part)
211 return (0);
212
213 if ((part < 1) || (part > pdb_p->map_count)) {
214 printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
215 dev_desc->dev, part,
216 dev_desc->dev,
217 dev_desc->dev, pdb_p->map_count);
218 return (-1);
219 }
220
221 /* update partition count */
222 n = part;
223 }
224
225 /* NOTREACHED */
226}
227
228int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
229{
230 mac_driver_desc_t ddesc;
231 mac_partition_t mpart;
232
233 if (part_mac_read_ddb (dev_desc, &ddesc)) {
234 return (-1);
235 }
236
237 info->blksz = ddesc.blk_size;
238
239 if (part_mac_read_pdb (dev_desc, part, &mpart)) {
240 return (-1);
241 }
242
243 info->start = mpart.start_block;
244 info->size = mpart.block_count;
245 memcpy (info->type, mpart.type, sizeof(info->type));
246 memcpy (info->name, mpart.name, sizeof(info->name));
247
248 return (0);
249}
250
251#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_MAC_PARTITION */