1/* $NetBSD: md.c,v 1.13 2022/06/24 22:28:11 tsutsui 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 52typedef struct parttab { 53 struct dos_partition dosparts[NDOSPART]; 54} parttab; 55 56parttab md_disklabel; 57int md_freepart; 58int md_nfreepart; 59#endif /* notyet */ 60 61int md_need_newdisk = 0; 62 63/* prototypes */ 64static int md_newdisk(void); 65 66void 67md_init(void) 68{ 69} 70 71void 72md_init_set_status(int flags) 73{ 74 (void)flags; 75} 76 77bool 78md_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 */ 148int 149md_make_bsd_partitions(struct install_partition_desc *install) 150{ 151 return make_bsd_partitions(install); 152} 153 154/* 155 * any additional partition validation 156 */ 157bool 158md_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 /* skip raw part and similar */ 168 if (install->infos[i].cur_flags & 169 (PTI_SEC_CONTAINER|PTI_PSCHEME_INTERNAL| 170 PTI_RAW_PART)) 171 continue; 172 173 if (install->infos[i].cur_start < last_end) { 174 snprintf(desc, sizeof desc, 175 "%zu (%s)", i, 176 install->infos[i].mount); 177 msg_fmt_display(MSG_ordering, "%s", desc); 178 if (ask_yesno(NULL)) 179 return false; 180 } 181 } 182 last_end = install->infos[i].cur_start + install->infos[i].size; 183 } 184 185 return true; 186} 187 188#ifdef notyet 189static int 190md_check_partitions(void) 191{ 192 int i, j; 193 int preserve; 194 195 /* check existing BSD partitions. */ 196 for (i = 0; i < NDOSPART; i++) { 197 if (md_disklabel.dosparts[i].dp_size == 0) 198 break; 199 if (memcmp(md_disklabel.dosparts[i].dp_typename, "Human68k", 8)) { 200 msg_display(MSG_existing); 201 preserve = ask_noyes(NULL); 202 break; 203 } 204 } 205 emptylabel(pm->bsdlabel); 206 pm->bsdlabel[C].pi_fstype = FS_UNUSED; 207 pm->bsdlabel[C].pi_offset = 0; 208 pm->bsdlabel[C].pi_size = pm->dlsize; 209 for (i = 0, j = A; i < NDOSPART;) { 210 if (j == C) { 211 j++; 212 continue; 213 } 214 if (!preserve && 215 memcmp(md_disklabel.dosparts[i].dp_typename, 216 "Human68k", 8)) { 217 /* discard it. */ 218 i++; 219 continue; 220 } 221 pm->bsdlabel[j].pi_fstype = (i == 1) ? FS_SWAP : FS_BSDFFS; 222 pm->bsdlabel[j].pi_offset = md_disklabel.dosparts[i].dp_start*2; 223 pm->bsdlabel[j].pi_size = md_disklabel.dosparts[i].dp_size*2; 224 i++; 225 j++; 226 } 227 if (j > 6) { 228 msg_fmt_display(MSG_nofreepart, "%s" pm->diskdev); 229 return 0; 230 } 231 md_nfreepart = 8 - j; 232 233 /* check for free space */ 234 fspm->ptsize = pm->bsdlabel[A].pi_offset - 64; 235 if (fpm->ptsize <= 0) { /* XXX: should not be 0; minfsdb? */ 236 msg_fmt_display(MSG_notfirst, "%s", pm->diskdev); 237 process_menu(MENU_ok); 238 exit(1); 239 } 240 241 /* Partitions should be preserved in md_make_bsdpartitions() */ 242} 243#endif /* notyet */ 244 245/* 246 * hook called before writing new disklabel. 247 */ 248bool 249md_pre_disklabel(struct install_partition_desc *install, 250 struct disk_partitions *parts) 251{ 252 if (md_need_newdisk) 253 md_newdisk (); 254 return true; 255} 256 257/* 258 * hook called after writing disklabel to new target disk. 259 */ 260bool 261md_post_disklabel(struct install_partition_desc *install, 262 struct disk_partitions *parts) 263{ 264 return true; 265} 266 267#ifdef DISKLABEL_NO_ONDISK_VERIFY 268/* 269 * hook to check if disklabel returned by readdisklabel(9) via DIOCGDINFO 270 * seems the default one, on ports that have no BSD disklabel on disks. 271 */ 272bool 273md_disklabel_is_default(const struct disklabel *lp) 274{ 275 bool maybe_default = 276 lp->d_npartitions == RAW_PART + 1 && 277 lp->d_partitions[0].p_size == lp->d_partitions[RAW_PART].p_size && 278 lp->d_partitions[0].p_fstype == FS_UNUSED && 279 lp->d_bbsize == 0 && 280 lp->d_sbsize == 0; 281 282 return maybe_default; 283} 284#endif 285 286/* 287 * hook called after upgrade() or install() has finished setting 288 * up the target disk but immediately before the user is given the 289 * ``disks are now set up'' message. 290 * 291 * On the x68k, we use this opportunity to install the boot blocks. 292 */ 293int 294md_post_newfs(struct install_partition_desc *install) 295{ 296 /* boot blocks ... */ 297 msg_fmt_display(MSG_dobootblks, "%s", pm->diskdev); 298 cp_to_target("/usr/mdec/boot", "/boot"); 299 if (run_program(RUN_DISPLAY | RUN_NO_CLEAR, 300 "/usr/mdec/installboot.new /usr/mdec/sdboot_ufs /dev/r%sa", 301 pm->diskdev)) 302 process_menu(MENU_ok, 303 __UNCONST("Warning: disk is probably not bootable")); 304 305 wclear(stdscr); 306 touchwin(stdscr); 307 clearok(stdscr, 1); 308 refresh(); 309 310 return 0; 311} 312 313int 314md_post_extract(struct install_partition_desc *install, bool upgrade) 315{ 316 return 0; 317} 318 319void 320md_cleanup_install(struct install_partition_desc *install) 321{ 322#ifndef DEBUG 323 enable_rc_conf(); 324#endif 325} 326 327int 328md_pre_update(struct install_partition_desc *install) 329{ 330 return 1; 331} 332 333/* Upgrade support */ 334int 335md_update(struct install_partition_desc *install) 336{ 337 md_post_newfs(install); 338 return 1; 339} 340 341static int 342md_newdisk(void) 343{ 344 msg_fmt_display(MSG_newdisk, "%s%s", pm->diskdev, pm->diskdev); 345 346 return run_program(RUN_FATAL|RUN_DISPLAY, 347 "/usr/mdec/newdisk -v %s", pm->diskdev); 348} 349 350 351int 352md_pre_mount(struct install_partition_desc *install, size_t ndx) 353{ 354 return 0; 355} 356 357bool 358md_parts_use_wholedisk(struct disk_partitions *parts) 359{ 360 return parts_use_wholedisk(parts, 0, NULL); 361} 362 363#ifdef HAVE_GPT 364bool 365md_gpt_post_write(struct disk_partitions *parts, part_id root_id, 366 bool root_is_new, part_id efi_id, bool efi_is_new) 367{ 368 /* no GPT boot support, nothing needs to be done here */ 369 return true; 370} 371#endif 372 373