1 /* $NetBSD: md.c,v 1.9 2019/12/15 13:39:24 martin Exp $ */ 2 3 /* 4 * Copyright 1997 Piermont Information Systems Inc. 5 * All rights reserved. 6 * 7 * Based on code written by Philip A. Nelson for Piermont Information 8 * Systems Inc. Modified by Minoura Makoto for x68k. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of Piermont Information Systems Inc. may not be used to endorse 19 * or promote products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* md.c -- x68k machine specific routines */ 36 /* This file is in close sync with pmax, sparc, and vax md.c */ 37 38 #include <stdio.h> 39 #include <unistd.h> 40 #include <sys/ioctl.h> 41 #include <sys/param.h> 42 #include <util.h> 43 44 #include "defs.h" 45 #include "md.h" 46 #include "msg_defs.h" 47 #include "menu_defs.h" 48 49 #ifdef notyet 50 #undef NDOSPART 8 51 #define NDOSPART 16 52 typedef struct parttab { 53 struct dos_partition dosparts[NDOSPART]; 54 } parttab; 55 56 parttab md_disklabel; 57 int md_freepart; 58 int md_nfreepart; 59 #endif /* notyet */ 60 61 int md_need_newdisk = 0; 62 63 /* prototypes */ 64 static int md_newdisk(void); 65 66 void 67 md_init(void) 68 { 69 } 70 71 void 72 md_init_set_status(int flags) 73 { 74 (void)flags; 75 } 76 77 bool 78 md_get_info(struct install_partition_desc *install) 79 { 80 char buf[1024]; 81 int fd; 82 char dev_name[100]; 83 struct disklabel disklabel; 84 85 snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev); 86 87 fd = open(dev_name, O_RDONLY, 0); 88 if (fd < 0) { 89 if (logfp) 90 (void)fprintf(logfp, "Can't open %s\n", dev_name); 91 endwin(); 92 fprintf(stderr, "Can't open %s\n", dev_name); 93 exit(1); 94 } 95 if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 96 if (logfp) 97 (void)fprintf(logfp, "Can't read disklabel on %s.\n", 98 dev_name); 99 endwin(); 100 fprintf(stderr, "Can't read disklabel on %s.\n", dev_name); 101 close(fd); 102 exit(1); 103 } 104 if (disklabel.d_secsize != 512) { 105 endwin(); 106 fprintf(stderr, "Non-512byte/sector disk is not supported.\n"); 107 close(fd); 108 exit(1); 109 } 110 111 pm->dlcyl = disklabel.d_ncylinders; 112 pm->dlhead = disklabel.d_ntracks; 113 pm->dlsec = disklabel.d_nsectors; 114 pm->sectorsize = disklabel.d_secsize; 115 pm->dlcylsize = disklabel.d_secpercyl; 116 pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec; 117 118 if (read(fd, buf, 1024) < 0) { 119 endwin(); 120 fprintf(stderr, "Can't read %s\n", dev_name); 121 close(fd); 122 exit(1); 123 } 124 if (memcmp(buf, "X68SCSI1", 8) != 0) 125 md_need_newdisk = 1; 126 #ifdef notyet 127 else 128 if (read(fd, md_disklabel, sizeof(md_disklabel)) < 0) { 129 endwin(); 130 fprintf(stderr, "Can't read %s\n", dev_name); 131 close(fd); 132 exit(1); 133 } 134 #endif 135 /* preserve first 64 sectors for system. */ 136 pm->ptstart = 64; 137 138 /* preserve existing partitions? */ 139 140 close(fd); 141 142 return true; 143 } 144 145 /* 146 * md back-end code for menu-driven BSD disklabel editor. 147 */ 148 bool 149 md_make_bsd_partitions(struct install_partition_desc *install) 150 { 151 return make_bsd_partitions(install); 152 } 153 154 /* 155 * any additional partition validation 156 */ 157 bool 158 md_check_partitions(struct install_partition_desc *install) 159 { 160 /* X68k partitions must be in order of the range. */ 161 daddr_t last_end = 0; 162 size_t i; 163 char desc[STRSIZE]; 164 165 for (i = 0; i < install->num; i++) { 166 if (i > 0) { 167 if (install->infos[i].cur_start < last_end) { 168 snprintf(desc, sizeof desc, 169 "%zu (%s)", i, 170 install->infos[i].mount); 171 msg_fmt_display(MSG_ordering, "%s", desc); 172 if (ask_yesno(NULL)) 173 return false; 174 } 175 } 176 last_end = install->infos[i].cur_start + install->infos[i].size; 177 } 178 179 return true; 180 } 181 182 #ifdef notyet 183 static int 184 md_check_partitions(void) 185 { 186 int i, j; 187 int preserve; 188 189 /* check existing BSD partitions. */ 190 for (i = 0; i < NDOSPART; i++) { 191 if (md_disklabel.dosparts[i].dp_size == 0) 192 break; 193 if (memcmp(md_disklabel.dosparts[i].dp_typename, "Human68k", 8)) { 194 msg_display(MSG_existing); 195 preserve = ask_noyes(NULL); 196 break; 197 } 198 } 199 emptylabel(pm->bsdlabel); 200 pm->bsdlabel[C].pi_fstype = FS_UNUSED; 201 pm->bsdlabel[C].pi_offset = 0; 202 pm->bsdlabel[C].pi_size = pm->dlsize; 203 for (i = 0, j = A; i < NDOSPART;) { 204 if (j == C) { 205 j++; 206 continue; 207 } 208 if (!preserve && 209 memcmp(md_disklabel.dosparts[i].dp_typename, 210 "Human68k", 8)) { 211 /* discard it. */ 212 i++; 213 continue; 214 } 215 pm->bsdlabel[j].pi_fstype = (i == 1) ? FS_SWAP : FS_BSDFFS; 216 pm->bsdlabel[j].pi_offset = md_disklabel.dosparts[i].dp_start*2; 217 pm->bsdlabel[j].pi_size = md_disklabel.dosparts[i].dp_size*2; 218 i++; 219 j++; 220 } 221 if (j > 6) { 222 msg_fmt_display(MSG_nofreepart, "%s" pm->diskdev); 223 return 0; 224 } 225 md_nfreepart = 8 - j; 226 227 /* check for free space */ 228 fspm->ptsize = pm->bsdlabel[A].pi_offset - 64; 229 if (fpm->ptsize <= 0) { /* XXX: should not be 0; minfsdb? */ 230 msg_fmt_display(MSG_notfirst, "%s", pm->diskdev); 231 process_menu(MENU_ok); 232 exit(1); 233 } 234 235 /* Partitions should be preserved in md_make_bsdpartitions() */ 236 } 237 #endif /* notyet */ 238 239 /* 240 * hook called before writing new disklabel. 241 */ 242 bool 243 md_pre_disklabel(struct install_partition_desc *install, 244 struct disk_partitions *parts) 245 { 246 if (md_need_newdisk) 247 md_newdisk (); 248 return true; 249 } 250 251 /* 252 * hook called after writing disklabel to new target disk. 253 */ 254 bool 255 md_post_disklabel(struct install_partition_desc *install, 256 struct disk_partitions *parts) 257 { 258 return true; 259 } 260 261 /* 262 * hook called after upgrade() or install() has finished setting 263 * up the target disk but immediately before the user is given the 264 * ``disks are now set up'' message. 265 * 266 * On the x68k, we use this opportunity to install the boot blocks. 267 */ 268 int 269 md_post_newfs(struct install_partition_desc *install) 270 { 271 /* boot blocks ... */ 272 msg_fmt_display(MSG_dobootblks, "%s", pm->diskdev); 273 cp_to_target("/usr/mdec/boot", "/boot"); 274 if (run_program(RUN_DISPLAY | RUN_NO_CLEAR, 275 "/usr/mdec/installboot.new /usr/mdec/sdboot_ufs /dev/r%sa", 276 pm->diskdev)) 277 process_menu(MENU_ok, 278 __UNCONST("Warning: disk is probably not bootable")); 279 280 wclear(stdscr); 281 touchwin(stdscr); 282 clearok(stdscr, 1); 283 refresh(); 284 285 return 0; 286 } 287 288 int 289 md_post_extract(struct install_partition_desc *install) 290 { 291 return 0; 292 } 293 294 void 295 md_cleanup_install(struct install_partition_desc *install) 296 { 297 #ifndef DEBUG 298 enable_rc_conf(); 299 #endif 300 } 301 302 int 303 md_pre_update(struct install_partition_desc *install) 304 { 305 return 1; 306 } 307 308 /* Upgrade support */ 309 int 310 md_update(struct install_partition_desc *install) 311 { 312 md_post_newfs(install); 313 return 1; 314 } 315 316 static int 317 md_newdisk(void) 318 { 319 msg_fmt_display(MSG_newdisk, "%s%s", pm->diskdev, pm->diskdev); 320 321 return run_program(RUN_FATAL|RUN_DISPLAY, 322 "/usr/mdec/newdisk -v %s", pm->diskdev); 323 } 324 325 326 int 327 md_pre_mount(struct install_partition_desc *install, size_t ndx) 328 { 329 return 0; 330 } 331 332 bool 333 md_parts_use_wholedisk(struct disk_partitions *parts) 334 { 335 return parts_use_wholedisk(parts, 0, NULL); 336 } 337 338 #ifdef HAVE_GPT 339 bool 340 md_gpt_post_write(struct disk_partitions *parts, part_id root_id, 341 bool root_is_new, part_id efi_id, bool efi_is_new) 342 { 343 /* no GPT boot support, nothing needs to be done here */ 344 return true; 345 } 346 #endif 347 348