1 /* $NetBSD: md.c,v 1.10 2020/02/03 13:09:29 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 /* 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 189 static int 190 md_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 */ 248 bool 249 md_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 */ 260 bool 261 md_post_disklabel(struct install_partition_desc *install, 262 struct disk_partitions *parts) 263 { 264 return true; 265 } 266 267 /* 268 * hook called after upgrade() or install() has finished setting 269 * up the target disk but immediately before the user is given the 270 * ``disks are now set up'' message. 271 * 272 * On the x68k, we use this opportunity to install the boot blocks. 273 */ 274 int 275 md_post_newfs(struct install_partition_desc *install) 276 { 277 /* boot blocks ... */ 278 msg_fmt_display(MSG_dobootblks, "%s", pm->diskdev); 279 cp_to_target("/usr/mdec/boot", "/boot"); 280 if (run_program(RUN_DISPLAY | RUN_NO_CLEAR, 281 "/usr/mdec/installboot.new /usr/mdec/sdboot_ufs /dev/r%sa", 282 pm->diskdev)) 283 process_menu(MENU_ok, 284 __UNCONST("Warning: disk is probably not bootable")); 285 286 wclear(stdscr); 287 touchwin(stdscr); 288 clearok(stdscr, 1); 289 refresh(); 290 291 return 0; 292 } 293 294 int 295 md_post_extract(struct install_partition_desc *install) 296 { 297 return 0; 298 } 299 300 void 301 md_cleanup_install(struct install_partition_desc *install) 302 { 303 #ifndef DEBUG 304 enable_rc_conf(); 305 #endif 306 } 307 308 int 309 md_pre_update(struct install_partition_desc *install) 310 { 311 return 1; 312 } 313 314 /* Upgrade support */ 315 int 316 md_update(struct install_partition_desc *install) 317 { 318 md_post_newfs(install); 319 return 1; 320 } 321 322 static int 323 md_newdisk(void) 324 { 325 msg_fmt_display(MSG_newdisk, "%s%s", pm->diskdev, pm->diskdev); 326 327 return run_program(RUN_FATAL|RUN_DISPLAY, 328 "/usr/mdec/newdisk -v %s", pm->diskdev); 329 } 330 331 332 int 333 md_pre_mount(struct install_partition_desc *install, size_t ndx) 334 { 335 return 0; 336 } 337 338 bool 339 md_parts_use_wholedisk(struct disk_partitions *parts) 340 { 341 return parts_use_wholedisk(parts, 0, NULL); 342 } 343 344 #ifdef HAVE_GPT 345 bool 346 md_gpt_post_write(struct disk_partitions *parts, part_id root_id, 347 bool root_is_new, part_id efi_id, bool efi_is_new) 348 { 349 /* no GPT boot support, nothing needs to be done here */ 350 return true; 351 } 352 #endif 353 354