1 /* $NetBSD: disk.h,v 1.79 2025/04/13 14:01:00 jakllsch Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1992, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * This software was developed by the Computer Systems Engineering group 38 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 39 * contributed to Berkeley. 40 * 41 * All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by the University of 44 * California, Lawrence Berkeley Laboratories. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * from: Header: disk.h,v 1.5 92/11/19 04:33:03 torek Exp (LBL) 71 * 72 * @(#)disk.h 8.2 (Berkeley) 1/9/95 73 */ 74 75 #ifndef _SYS_DISK_H_ 76 #define _SYS_DISK_H_ 77 78 /* 79 * Disk device structures. 80 */ 81 82 #include <sys/dkio.h> 83 #include <sys/time.h> 84 #include <sys/queue.h> 85 #include <sys/iostat.h> 86 87 /* 88 * Disk information dictionary. 89 * 90 * This contains general information for disk devices. 91 * 92 * <dict> 93 * <key>type</key> 94 * <string>...</string> 95 * <key>geometry</key> 96 * <dict> 97 * <!-- See below for disk geometry dictionary 98 * contents. --> 99 * </dict> 100 * 101 * <!-- optional information --> 102 * <key>rpm</key> 103 * <integer>...</integer> 104 * <key>sector-interleave</key> 105 * <integer>...</integer> 106 * <key>track-skew</key> 107 * <integer>...</integer> 108 * <key>cylinder-skew</key> 109 * <integer>...</integer> 110 * <key>head-switch-usecs</key> 111 * <integer>...</integer> 112 * <key>track-seek-usecs</key> 113 * <integer>...</integer> 114 * <key>removable</key> 115 * <false/> 116 * <key>ecc</key> 117 * <false/> 118 * <key>bad-sector-forwarding</key> 119 * <true/> 120 * <key>ramdisk</key> 121 * <false/> 122 * <key>back-to-back-transfers</key> 123 * <true/> 124 * 125 * <!-- additional information for SMD drives --> 126 * <key>smd-skip-sectoring</key> 127 * <false/> 128 * <!-- XXX better names for these properties --> 129 * <key>smd-mindist</key> 130 * <integer>...</integer> 131 * <key>smd-maxdist</key> 132 * <integer>...</integer> 133 * <key>smd-sdist</key> 134 * <integer>...</integer> 135 * 136 * <!-- additional information for ST506 drives --> 137 * <!-- XXX better names for these properties --> 138 * <key>st506-precompcyl</key> 139 * <integer>...</integer> 140 * <key>st506-gap3</key> 141 * <integer>...</integer> 142 * 143 * <!-- additional information for ATA drives --> 144 * <!-- XXX --> 145 * 146 * <!-- additional information for SCSI drives --> 147 * <!-- XXX --> 148 * </dict> 149 */ 150 151 /* 152 * dkwedge_info: 153 * 154 * Information needed to configure (or query configuration of) a 155 * disk wedge. 156 */ 157 struct dkwedge_info { 158 char dkw_devname[16];/* device-style name (e.g. "dk0") */ 159 uint8_t dkw_wname[128]; /* wedge name (Unicode, UTF-8) */ 160 char dkw_parent[16]; /* parent disk device name */ 161 daddr_t dkw_offset; /* LBA offset of wedge in parent */ 162 uint64_t dkw_size; /* size of wedge in blocks */ 163 char dkw_ptype[32]; /* partition type string */ 164 }; 165 166 /* 167 * dkwedge_list: 168 * 169 * Structure used to query a list of wedges. 170 */ 171 struct dkwedge_list { 172 void *dkwl_buf; /* storage for dkwedge_info array */ 173 size_t dkwl_bufsize; /* size of that buffer */ 174 u_int dkwl_nwedges; /* total number of wedges */ 175 u_int dkwl_ncopied; /* number actually copied */ 176 }; 177 178 /* Some common partition types */ 179 #define DKW_PTYPE_UNKNOWN "" 180 #define DKW_PTYPE_UNUSED "unused" 181 #define DKW_PTYPE_SWAP "swap" 182 #define DKW_PTYPE_V6 "v6" 183 #define DKW_PTYPE_V7 "v7" 184 #define DKW_PTYPE_SYSV "sysv" 185 #define DKW_PTYPE_V71K "v71k" 186 #define DKW_PTYPE_V8 "v8" 187 #define DKW_PTYPE_FFS "ffs" 188 #define DKW_PTYPE_FAT "msdos" 189 #define DKW_PTYPE_LFS "lfs" 190 #define DKW_PTYPE_OTHER "other" 191 #define DKW_PTYPE_HPFS "hpfs" 192 #define DKW_PTYPE_ISO9660 "cd9660" 193 #define DKW_PTYPE_BOOT "boot" 194 #define DKW_PTYPE_AMIGADOS "ados" 195 #define DKW_PTYPE_HFS "hfs" 196 #define DKW_PTYPE_FILECORE "filecore" 197 #define DKW_PTYPE_EXT2FS "ext2fs" 198 #define DKW_PTYPE_NTFS "ntfs" 199 #define DKW_PTYPE_RAIDFRAME "raidframe" 200 #define DKW_PTYPE_CCD "ccd" 201 #define DKW_PTYPE_JFS2 "jfs2" 202 #define DKW_PTYPE_APPLEUFS "appleufs" 203 #define DKW_PTYPE_VINUM "vinum" 204 #define DKW_PTYPE_UDF "udf" 205 #define DKW_PTYPE_APPLEHFS "hfs" 206 #define DKW_PTYPE_SYSVBFS "sysvbfs" 207 #define DKW_PTYPE_EFS "efs" 208 #define DKW_PTYPE_NILFS "nilfs" 209 #define DKW_PTYPE_CGD "cgd" 210 #define DKW_PTYPE_MINIXFS3 "minixfs3" 211 #define DKW_PTYPE_VMKCORE "vmkcore" 212 #define DKW_PTYPE_VMFS "vmfs" 213 #define DKW_PTYPE_VMWRESV "vmwresv" 214 #define DKW_PTYPE_ZFS "zfs" 215 216 /* 217 * Ensure each symbol used in FSTYPE_DEFN in <sys/disklabel.h> 218 * has a corresponding DKW_PTYPE_* definition. 219 */ 220 #define DKW_PTYPE_MSDOS DKW_PTYPE_FAT 221 #define DKW_PTYPE_BSDFFS DKW_PTYPE_FFS 222 #define DKW_PTYPE_BSDLFS DKW_PTYPE_LFS 223 #define DKW_PTYPE_ADOS DKW_PTYPE_AMIGADOS 224 #define DKW_PTYPE_EX2FS DKW_PTYPE_EXT2FS 225 #define DKW_PTYPE_RAID DKW_PTYPE_RAIDFRAME 226 227 /* 228 * Disk geometry dictionary. 229 * 230 * NOTE: Not all geometry information is relevant for every kind of disk. 231 * 232 * <dict> 233 * <key>sectors-per-unit</key> 234 * <integer>...</integer> 235 * <key>sector-size</key> 236 * <integer>...</integer> 237 * <key>sectors-per-track</key> 238 * <integer>...</integer> 239 * <key>tracks-per-cylinder</key> 240 * <integer>...</integer> 241 * <key>cylinders-per-unit</key> 242 * <integer>...</integer> 243 * <key>physical-cylinders-per-unit</key> 244 * <integer>...</integer> 245 * <key>spare-sectors-per-track</key> 246 * <integer>...</integer> 247 * <key>spare-sectors-per-cylinder</key> 248 * <integer>...</integer> 249 * <key>alternative-cylinders</key> 250 * <integer>...</integer> 251 * <key>physical-sector-size</key> 252 * <integer>...</integer> 253 * <key>aligned-sector</key> 254 * <integer>...</integer> 255 * </dict> 256 * NOTE: Not all geometry information is relevant for every kind of disk. 257 */ 258 259 struct disk_geom { 260 int64_t dg_secperunit; /* # of data sectors per unit */ 261 uint32_t dg_secsize; /* # of bytes per sector */ 262 uint32_t dg_nsectors; /* # of data sectors per track */ 263 uint32_t dg_ntracks; /* # of tracks per cylinder */ 264 uint32_t dg_ncylinders; /* # of data cylinders per unit */ 265 uint32_t dg_secpercyl; /* # of data sectors per cylinder */ 266 uint32_t dg_pcylinders; /* # of physical cylinders per unit */ 267 268 /* 269 * Spares (bad sector replacements) below are not counted in 270 * dg_nsectors or dg_secpercyl. Spare sectors are assumed to 271 * be physical sectors which occupy space at the end of each 272 * track and/or cylinder. 273 */ 274 uint32_t dg_sparespertrack; 275 uint32_t dg_sparespercyl; 276 /* 277 * Alternative cylinders include maintenance, replacement, 278 * configuration description areas, etc. 279 */ 280 uint32_t dg_acylinders; 281 282 uint32_t dg_physsecsize; /* # of bytes per physical sector */ 283 uint32_t dg_alignedsec; /* first aligned logical sector # */ 284 }; 285 286 /* 287 * Bad sector lists per fixed disk 288 */ 289 struct disk_badsectors { 290 SLIST_ENTRY(disk_badsectors) dbs_next; 291 daddr_t dbs_min; /* min. sector number */ 292 daddr_t dbs_max; /* max. sector number */ 293 struct timeval dbs_failedat; /* first failure at */ 294 }; 295 296 struct disk_badsecinfo { 297 uint32_t dbsi_bufsize; /* size of region pointed to */ 298 uint32_t dbsi_skip; /* how many to skip past */ 299 uint32_t dbsi_copied; /* how many got copied back */ 300 uint32_t dbsi_left; /* remaining to copy */ 301 void * dbsi_buffer; /* region to copy disk_badsectors to */ 302 }; 303 304 #define DK_STRATEGYNAMELEN 32 305 struct disk_strategy { 306 char dks_name[DK_STRATEGYNAMELEN]; /* name of strategy */ 307 char *dks_param; /* notyet; should be NULL */ 308 size_t dks_paramlen; /* notyet; should be 0 */ 309 }; 310 311 /* Sector alignment */ 312 struct disk_sectoralign { 313 uint32_t dsa_firstaligned; /* first aligned sector # */ 314 uint32_t dsa_alignment; /* sectors per aligned sector */ 315 }; 316 317 #ifdef _KERNEL 318 #include <sys/device.h> 319 #include <sys/mutex.h> 320 321 #include <prop/proplib.h> 322 323 struct buf; 324 struct disk; 325 struct disklabel; 326 struct cpu_disklabel; 327 struct lwp; 328 struct vnode; 329 330 /* 331 * dkwedge_discovery_method: 332 * 333 * Structure used to describe partition map parsing schemes 334 * used for wedge autodiscovery. 335 */ 336 struct dkwedge_discovery_method { 337 /* link in wedge driver's list */ 338 LIST_ENTRY(dkwedge_discovery_method) ddm_list; 339 const char *ddm_name; /* name of this method */ 340 int ddm_priority; /* search priority */ 341 int (*ddm_discover)(struct disk *, struct vnode *); 342 }; 343 344 #define DKWEDGE_DISCOVERY_METHOD_DECL(name, prio, discover) \ 345 static struct dkwedge_discovery_method name ## _ddm = { \ 346 { NULL, NULL }, \ 347 #name, \ 348 prio, \ 349 discover \ 350 }; \ 351 __link_set_add_data(dkwedge_methods, name ## _ddm) 352 353 /* 354 * Disk partition dictionary. 355 * 356 * A partition is represented as a dictionary containing generic partition 357 * properties (such as starting block and block count), as well as information 358 * that is specific to individual partition map formats. 359 * 360 * <dict> 361 * <key>start-block</key> 362 * <integer>...</integer> 363 * <key>block-count</key> 364 * <integer>...</integer> 365 * <!-- DKW_PTYPE strings ("" or missing if unknown) --> 366 * <key>type</type> 367 * <string>...</string> 368 * <!-- optional --> 369 * <key>name</key> 370 * <string>...</string> 371 * 372 * <!-- these are valid for GPT partition maps --> 373 * <key>gpt-type-guid</key> 374 * <string>...</string> 375 * <key>gpt-partition-guid</key> 376 * <string>...</string> 377 * <key>gpt-platform-required</key> 378 * <false/> 379 * 380 * <!-- these are valid for 4.4BSD partition maps --> 381 * <key>bsd44-partition-type</key> 382 * <integer>...</integer> 383 * <key>bsd44-fs-fragment-size</key> 384 * <integer>...</integer> 385 * <key>bsd44-iso9660-session-offset</key> 386 * <integer>...</integer> 387 * <key>bsd44-ffs-cylinders-per-group</key> 388 * <integer>...</integer> 389 * <key>bsd44-lfs-segment-shift</key> 390 * <integer>...</integer> 391 * 392 * <!-- these are valid for NeXT partition maps --> 393 * <key>next-block-size</key> 394 * <integer>...</integer> 395 * <key>next-fs-fragment-size</key> 396 * <integer>...</integer> 397 * <key>next-fs-optimization</key> 398 * <string>...</string> <!-- "space" or "time" --> 399 * <key>next-fs-cylinders-per-group</key> 400 * <integer>...</integer> 401 * <key>next-bytes-per-inode-density</key> 402 * <integer>...</integer> 403 * <key>next-minfree-percentage</key> 404 * <integer>...</integer> 405 * <key>next-run-newfs-during-init</key> 406 * <false/> 407 * <key>next-mount-point</key> 408 * <string>...</string> 409 * <key>next-automount</key> 410 * <true/> 411 * <key>next-partition-type</key> 412 * <string>...</string> 413 * 414 * <!-- these are valid for MBR partition maps --> 415 * <key>mbr-start-head</key> 416 * <integer>...</integer> 417 * <key>mbr-start-sector</key> 418 * <integer>...</integer> 419 * <key>mbr-start-cylinder</key> 420 * <integer>...</integer> 421 * <key>mbr-partition-type</key> 422 * <integer>...</integer> 423 * <key>mbr-end-head</key> 424 * <integer>...</integer> 425 * <key>mbr-end-sector</key> 426 * <integer>...</integer> 427 * <key>mbr-end-cylinder</key> 428 * <integer>...</integer> 429 * <key>mbr-active-partition</key> 430 * <false/> 431 * 432 * <!-- these are valid for Apple partition maps --> 433 * <key>apple-partition-type</key> 434 * <string>...</string> 435 * <!-- XXX What else do we need? wrstuden? --> 436 * 437 * <!-- these are valid for RISCiX partition maps --> 438 * <key>riscix-partition-type</key> 439 * <integer>...</integer> 440 * 441 * <!-- these are valid for MIPS/SGI partition maps --> 442 * <key>mips-partition-type</key> 443 * <integer>...</integer> 444 * 445 * <!-- SunOS 4 partition maps have no specific 446 * additional information. Note, however, 447 * that SunOS 4 partitions must begin on 448 * cylinder boundaries. --> 449 * 450 * <!-- XXX Need Amiga partition map info --> 451 * 452 * <!-- these are valid for VTOC partition maps --> 453 * <key>vtoc-tag</key> 454 * <integer>...</integer> 455 * <key>vtoc-unmount</key> 456 * <false/> 457 * <key>vtoc-read-only</key> 458 * <false/> 459 * <!-- XXX is this really part of the partition info? --> 460 * <key>vtoc-timestamp</key> 461 * <integer>...</integer> 462 * 463 * <!-- mvme68k partition maps use 4.4BSD partition 464 * info stuffed into two different areas of the 465 * disk information label recognized by BUG. --> 466 * 467 * <!-- XXX What else? --> 468 * </dict> 469 */ 470 471 struct disk { 472 TAILQ_ENTRY(disk) dk_link; /* link in global disklist */ 473 const char *dk_name; /* disk name */ 474 prop_dictionary_t dk_info; /* reference to disk-info dictionary */ 475 struct disk_geom dk_geom; /* cooked version of dk_info */ 476 int dk_bopenmask; /* block devices open */ 477 int dk_copenmask; /* character devices open */ 478 int dk_openmask; /* composite (bopen|copen) */ 479 int dk_state; /* label state ### */ 480 int dk_blkshift; /* shift to convert DEV_BSIZE to blks */ 481 int dk_byteshift; /* shift to convert bytes to blks */ 482 483 /* 484 * Metrics data; note that some metrics may have no meaning 485 * on certain types of disks. 486 */ 487 struct io_stats *dk_stats; 488 489 const struct dkdriver *dk_driver; /* pointer to driver */ 490 491 /* 492 * Information required to be the parent of a disk wedge. 493 */ 494 kmutex_t dk_rawlock; /* lock on these fields */ 495 u_int dk_rawopens; /* # of openes of rawvp */ 496 struct vnode *dk_rawvp; /* vnode for the RAW_PART bdev */ 497 498 kmutex_t dk_openlock; /* lock on these and openmask */ 499 u_int dk_nwedges; /* # of configured wedges */ 500 /* all wedges on this disk */ 501 LIST_HEAD(, dkwedge_softc) dk_wedges; 502 503 /* 504 * Disk label information. Storage for the in-core disk label 505 * must be dynamically allocated, otherwise the size of this 506 * structure becomes machine-dependent. 507 */ 508 daddr_t dk_labelsector; /* sector containing label */ 509 struct disklabel *dk_label; /* label */ 510 struct cpu_disklabel *dk_cpulabel; 511 }; 512 513 struct dkdriver { 514 void (*d_strategy)(struct buf *); 515 void (*d_minphys)(struct buf *); 516 int (*d_open)(dev_t, int, int, struct lwp *); 517 int (*d_close)(dev_t, int, int, struct lwp *); 518 int (*d_diskstart)(device_t, struct buf *); 519 void (*d_iosize)(device_t, int *); 520 int (*d_dumpblocks)(device_t, void *, daddr_t, int); 521 int (*d_lastclose)(device_t); 522 int (*d_discard)(device_t, off_t, off_t); 523 int (*d_firstopen)(device_t, dev_t, int, int); 524 void (*d_label)(device_t, struct disklabel *lp); 525 }; 526 527 /* states */ 528 #define DK_CLOSED 0 /* drive is closed */ 529 #define DK_WANTOPEN 1 /* drive being opened */ 530 #define DK_WANTOPENRAW 2 /* drive being opened */ 531 #define DK_RDLABEL 3 /* label being read */ 532 #define DK_OPEN 4 /* label read, drive open */ 533 #define DK_OPENRAW 5 /* open without label */ 534 535 #define DK_BSIZE2BLKSHIFT(b) ((ffs((b) / DEV_BSIZE)) - 1) 536 #define DK_BSIZE2BYTESHIFT(b) (ffs((b)) - 1) 537 #define DK_DEV_BSIZE_OK(b) \ 538 ((b) >= DEV_BSIZE && ((b) & ((b) - 1)) == 0 && (b) <= MAXPHYS) 539 540 extern int disk_count; /* number of disks in global disklist */ 541 542 struct proc; 543 544 void disk_rename(struct disk *, const char *); 545 void disk_attach(struct disk *); 546 int disk_begindetach(struct disk *, int (*)(device_t), device_t, int); 547 void disk_detach(struct disk *); 548 void disk_init(struct disk *, const char *, const struct dkdriver *); 549 void disk_destroy(struct disk *); 550 void disk_wait(struct disk *); 551 void disk_busy(struct disk *); 552 void disk_unbusy(struct disk *, long, int); 553 bool disk_isbusy(struct disk *); 554 struct disk *disk_find(const char *); 555 int disk_ioctl(struct disk *, dev_t, u_long, void *, int, struct lwp *); 556 void disk_set_info(device_t, struct disk *, const char *); 557 558 void dkwedge_init(void); 559 int dkwedge_add(struct dkwedge_info *); 560 int dkwedge_del(struct dkwedge_info *); 561 void dkwedge_delall(struct disk *); 562 void dkwedge_delidle(struct disk *); 563 int dkwedge_list(struct disk *, struct dkwedge_list *, struct lwp *); 564 void dkwedge_discover(struct disk *); 565 int dkwedge_read(struct disk *, struct vnode *, daddr_t, void *, size_t); 566 device_t dkwedge_find_by_wname(const char *); 567 device_t dkwedge_find_by_parent(const char *, size_t *); 568 const char *dkwedge_get_parent_name(dev_t); 569 void dkwedge_print_wnames(void); 570 device_t dkwedge_find_partition(device_t, daddr_t, uint64_t); 571 572 #endif /* _KERNEL */ 573 574 #endif /* _SYS_DISK_H_ */ 575