FreeBSD/Linux Kernel Cross Reference
sys/scsi/rz_labels.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: rz_labels.c,v $
29 * Revision 2.10 93/08/10 15:19:51 mrt
30 * We now use bsd labels internally and convert from "local labels"
31 * if we find them on the disk.
32 * [93/08/03 20:36:46 rvb]
33 *
34 * Revision 2.9 93/05/10 21:22:41 rvb
35 * Removed depends on DEV_BSIZE.
36 * [93/05/06 10:09:09 af]
37 *
38 * Revision 2.8 93/03/09 11:18:35 danner
39 * If there is no recognizable label, we must set p_size of the
40 * MAXPARTITION slice. We use MAXPARTITION to do ABSOLUTE reads.
41 * [93/02/23 rvb]
42 *
43 * Revision 2.7 92/08/03 17:53:58 jfriedl
44 * removed silly prototypes
45 * [92/08/02 jfriedl]
46 *
47 * Revision 2.6 92/05/21 17:23:47 jfriedl
48 * tried prototypes.
49 * [92/05/20 jfriedl]
50 *
51 * Revision 2.5 92/04/03 12:10:09 rpd
52 * Let "grab_bob_label" return failure so we take the default.
53 * [92/04/01 rvb]
54 *
55 * Revision 2.4 92/02/23 22:44:31 elf
56 * Actually, scan for all possible (bogus) label formats.
57 * This makes it possible to cross-mount disks even if
58 * they do not have the standard BSD label.
59 * [92/02/22 af]
60 *
61 * Revision 2.3 91/08/24 12:28:06 af
62 * Created, splitting out DEC-specific code from rz_disk.c and
63 * adding some more.
64 * [91/06/26 af]
65 *
66 */
67 /*
68 * File: rz_labels.c
69 * Author: Alessandro Forin, Carnegie Mellon University
70 * Date: 6/91
71 *
72 * Routines for various vendor's disk label formats.
73 */
74
75 #include <platforms.h>
76
77 #include <mach/std_types.h>
78 #include <scsi/compat_30.h>
79 #include <scsi/scsi_defs.h>
80 #include <scsi/rz_labels.h>
81
82 #define LABEL_DEBUG(x,y) if (label_flag&x) y
83
84
85 /*
86 * Find and convert from a DEC label to BSD
87 */
88 boolean_t
89 rz_dec_label(tgt, label, ior)
90 target_info_t *tgt;
91 struct disklabel *label;
92 io_req_t ior;
93 {
94 /* here look for a DEC label */
95 register scsi_dec_label_t *part;
96 char *data;
97 int i, dev_bsize = tgt->block_size;
98
99 ior->io_count = dev_bsize;
100 ior->io_op = IO_READ;
101 tgt->ior = ior;
102 scdisk_read( tgt, DEC_LABEL_BYTE_OFFSET/dev_bsize, ior);
103 iowait(ior);
104 data = (char *)ior->io_data;
105 part = (scsi_dec_label_t*)&data[DEC_LABEL_BYTE_OFFSET%dev_bsize];
106 if (part->magic == DEC_LABEL_MAGIC) {
107 if (scsi_debug)
108 printf("{Using DEC label}");
109 for (i = 0; i < 8; i++) {
110 label->d_partitions[i].p_size = part->partitions[i].n_sectors;
111 label->d_partitions[i].p_offset = part->partitions[i].offset;
112 }
113 return TRUE;
114 }
115 return FALSE;
116 }
117
118 /*
119 * Find and convert from a Omron label to BSD
120 */
121 boolean_t
122 rz_omron_label(tgt, label, ior)
123 target_info_t *tgt;
124 struct disklabel *label;
125 io_req_t ior;
126 {
127 /* here look for an Omron label */
128 register scsi_omron_label_t *part;
129 char *data;
130 int i, dev_bsize = tgt->block_size;
131
132 ior->io_count = dev_bsize;
133 ior->io_op = IO_READ;
134 tgt->ior = ior;
135 scdisk_read( tgt, OMRON_LABEL_BYTE_OFFSET/dev_bsize, ior);
136 iowait(ior);
137 data = (char *)ior->io_data;
138 part = (scsi_omron_label_t*)&data[OMRON_LABEL_BYTE_OFFSET%dev_bsize];
139 if (part->magic == OMRON_LABEL_MAGIC) {
140 if (scsi_debug)
141 printf("{Using OMRON label}");
142 for (i = 0; i < 8; i++) {
143 label->d_partitions[i].p_size = part->partitions[i].n_sectors;
144 label->d_partitions[i].p_offset = part->partitions[i].offset;
145 }
146 bcopy(part->packname, label->d_packname, 16);
147 label->d_ncylinders = part->ncyl;
148 label->d_acylinders = part->acyl;
149 label->d_ntracks = part->nhead;
150 label->d_nsectors = part->nsect;
151 /* Many disks have this wrong, therefore.. */
152 #if 0
153 label->d_secperunit = part->maxblk;
154 #else
155 label->d_secperunit = label->d_ncylinders * label->d_ntracks *
156 label->d_nsectors;
157 #endif
158 return TRUE;
159 }
160 return FALSE;
161 }
162
163 /*
164 * Find and convert from a Intel BIOS label to BSD
165 */
166 extern int label_flag;
167 extern int OS;
168 #define BSDOS 165
169 #define LBLLOC 1
170 boolean_t
171 rz_bios_label(tgt, label, ior)
172 target_info_t *tgt;
173 struct disklabel *label;
174 io_req_t ior;
175 {
176 /* here look for a BIOS label */
177 char *data;
178 int i, dev_bsize = tgt->block_size;
179 scsi_bios_label_t part;
180
181 ior->io_count = dev_bsize;
182 ior->io_op = IO_READ;
183 tgt->ior = ior;
184 scdisk_read( tgt, BIOS_LABEL_BYTE_OFFSET/dev_bsize, ior);
185 iowait(ior);
186 data = (char *)ior->io_data;
187 /*
188 * It's safer to just copy the data here and not worry about
189 * scdisk_read's down the line will clobber the buffer.
190 */
191 part = *(scsi_bios_label_t*)&data[BIOS_LABEL_BYTE_OFFSET%dev_bsize];
192 if (((scsi_bios_label_t*)&data[BIOS_LABEL_BYTE_OFFSET%dev_bsize])->magic
193 == BIOS_LABEL_MAGIC) {
194 struct bios_partition_info *bpart, *ospart = (struct bios_partition_info *)0;
195 if (scsi_debug)
196 printf("{Using BIOS label}");
197 for (i = 0; i < 4; i++) {
198 bpart = &(((struct bios_partition_info *)part.partitions)[i]);
199 LABEL_DEBUG(1,print_dos_partition(i, bpart));
200 label->d_partitions[i].p_size = bpart->n_sectors;
201 label->d_partitions[i].p_offset = bpart->offset;
202 if (bpart->systid == UNIXOS || bpart->systid == BSDOS) {
203 if ((int) ospart) {
204 if (bpart->bootid == BIOS_BOOTABLE)
205 ospart = bpart;
206 } else
207 ospart = bpart;
208 }
209 }
210 tgt->dev_info.disk.l.d_partitions[MAXPARTITIONS].p_offset= 0;
211 tgt->dev_info.disk.l.d_partitions[MAXPARTITIONS].p_size = -1;
212
213 if (!((int)ospart))
214 return FALSE;
215 OS = ospart->systid;
216 if (OS == UNIXOS)
217 printf("sd%d: MACH OS ", tgt->target_id);
218 if (OS == BSDOS)
219 printf("sd%d: XXXBSD OS ", tgt->target_id);
220
221 if (rz_bios_bsd_label(tgt, label, ior, ospart))
222 return TRUE;
223
224 #ifdef AT386 /* this goes away real fast */
225 if (!grab_bob_label(tgt, label, ior,
226 ((struct bios_partition_info *)part.partitions)))
227 return FALSE; /* take default setup of "a" and "c" */
228 #else
229 label->d_npartitions = 4;
230 #endif
231 label->d_bbsize = BIOS_BOOT0_SIZE;
232 return TRUE;
233 }
234 return FALSE;
235 }
236
237 rz_bios_bsd_label(tgt, label, ior, ospart)
238 target_info_t *tgt;
239 struct disklabel *label;
240 io_req_t ior;
241 struct bios_partition_info *ospart;
242 {
243 struct disklabel *dlp;
244 int dev_bsize = tgt->block_size;
245 int i;
246 extern int allow_bsd_label;
247
248 ior->io_count = dev_bsize;
249 ior->io_op = IO_READ;
250 tgt->ior = ior;
251 scdisk_read( tgt, (ospart->offset + LBLLOC) * 512 / dev_bsize, ior);
252 iowait(ior);
253 dlp = (struct disklabel *)ior->io_data;
254
255 if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
256 if (OS == BSDOS) {
257 printf("NO BSD LABEL!!\n");
258 }
259 return FALSE;
260 }
261
262 printf("BSD LABEL ");
263 LABEL_DEBUG(2,print_bsd_label(dlp, "dk:"));
264 /*
265 * here's were we dump label
266 */
267 if (allow_bsd_label == 0)
268 return FALSE;
269
270 i = label->d_secperunit;
271 *label = *dlp;
272 label->d_secperunit = i;
273
274 tgt->dev_info.disk.labeloffset = 0;
275 tgt->dev_info.disk.labelsector = (ospart->offset + LBLLOC) * 512 / dev_bsize;
276
277 LABEL_DEBUG(0x20,print_bsd_label(dlp, " "));
278 return TRUE;
279 }
280
281 /*
282 * Try all of the above
283 */
284 boolean_t rz_vendor_label(tgt, label, ior)
285 target_info_t *tgt;
286 struct disklabel *label;
287 io_req_t ior;
288 {
289 /* If for any reason there might be problems someday.. */
290 #ifdef VENDOR_LABEL
291 if (VENDOR_LABEL( tgt, label, ior)) return TRUE;
292 #endif /*VENDOR_LABEL*/
293
294 if (rz_dec_label( tgt, label, ior)) return TRUE;
295 if (rz_bios_label( tgt, label, ior)) return TRUE;
296 if (rz_omron_label( tgt, label, ior)) return TRUE;
297 return FALSE;
298 }
299
Cache object: c78d8c4915283491348ef921840f6679
|