1/* $NetBSD$ */ 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#ifdef _KERNEL 83#include <sys/device.h> 84#endif 85#include <sys/dkio.h> 86#include <sys/time.h> 87#include <sys/queue.h> 88#include <sys/mutex.h> 89#include <sys/iostat.h> 90 91#include <prop/proplib.h> 92 93struct buf; 94struct disk; 95struct disklabel; 96struct cpu_disklabel; 97struct lwp; 98struct vnode; 99 100/* 101 * Disk information dictionary. 102 * 103 * This contains general infomation for disk devices. 104 * 105 * <dict> 106 * <key>type</key> 107 * <string>...</string> 108 * <key>geometry</key> 109 * <dict> 110 * <!-- See below for disk geometry dictionary 111 * contents. --> 112 * </dict> 113 * 114 * <!-- optional information --> 115 * <key>rpm</key> 116 * <integer>...</integer> 117 * <key>sector-interleave</key> 118 * <integer>...</integer> 119 * <key>track-skew</key> 120 * <integer>...</integer> 121 * <key>cylinder-skew</key> 122 * <integer>...</integer> 123 * <key>head-switch-usecs</key> 124 * <integer>...</integer> 125 * <key>track-seek-usecs</key> 126 * <integer>...</integer> 127 * <key>removable</key> 128 * <false/> 129 * <key>ecc</key> 130 * <false/> 131 * <key>bad-sector-forwarding</key> 132 * <true/> 133 * <key>ramdisk</key> 134 * <false/> 135 * <key>back-to-back-transfers</key> 136 * <true/> 137 * 138 * <!-- additional information for SMD drives --> 139 * <key>smd-skip-sectoring</key> 140 * <false/> 141 * <!-- XXX better names for these properties --> 142 * <key>smd-mindist</key> 143 * <integer>...</integer> 144 * <key>smd-maxdist</key> 145 * <integer>...</integer> 146 * <key>smd-sdist</key> 147 * <integer>...</integer> 148 * 149 * <!-- additional information for ST506 drives --> 150 * <!-- XXX better names for these properties --> 151 * <key>st506-precompcyl</key> 152 * <integer>...</integer> 153 * <key>st506-gap3</key> 154 * <integer>...</integer> 155 * 156 * <!-- additional information for ATA drives --> 157 * <!-- XXX --> 158 * 159 * <!-- additional information for SCSI drives --> 160 * <!-- XXX --> 161 * </dict> 162 */ 163 164/* 165 * dkwedge_info: 166 * 167 * Information needed to configure (or query configuration of) a 168 * disk wedge. 169 */ 170struct dkwedge_info { 171 char dkw_devname[16];/* device-style name (e.g. "dk0") */ 172 uint8_t dkw_wname[128]; /* wedge name (Unicode, UTF-8) */ 173 char dkw_parent[16]; /* parent disk device name */ 174 daddr_t dkw_offset; /* LBA offset of wedge in parent */ 175 uint64_t dkw_size; /* size of wedge in blocks */ 176 char dkw_ptype[32]; /* partition type string */ 177}; 178 179/* 180 * dkwedge_list: 181 * 182 * Structure used to query a list of wedges. 183 */ 184struct dkwedge_list { 185 void *dkwl_buf; /* storage for dkwedge_info array */ 186 size_t dkwl_bufsize; /* size of that buffer */ 187 u_int dkwl_nwedges; /* total number of wedges */ 188 u_int dkwl_ncopied; /* number actually copied */ 189}; 190 191#ifdef _KERNEL 192/* 193 * dkwedge_discovery_method: 194 * 195 * Structure used to describe partition map parsing schemes 196 * used for wedge autodiscovery. 197 */ 198struct dkwedge_discovery_method { 199 /* link in wedge driver's list */ 200 LIST_ENTRY(dkwedge_discovery_method) ddm_list; 201 const char *ddm_name; /* name of this method */ 202 int ddm_priority; /* search priority */ 203 int (*ddm_discover)(struct disk *, struct vnode *); 204}; 205 206#define DKWEDGE_DISCOVERY_METHOD_DECL(name, prio, discover) \ 207static struct dkwedge_discovery_method name ## _ddm = { \ 208 { NULL, NULL }, \ 209 #name, \ 210 prio, \ 211 discover \ 212}; \ 213__link_set_add_data(dkwedge_methods, name ## _ddm) 214#endif /* _KERNEL */ 215 216/* Some common partition types */ 217#define DKW_PTYPE_UNKNOWN "" 218#define DKW_PTYPE_UNUSED "unused" 219#define DKW_PTYPE_SWAP "swap" 220#define DKW_PTYPE_V6 "v6" 221#define DKW_PTYPE_V7 "v7" 222#define DKW_PTYPE_SYSV "sysv" 223#define DKW_PTYPE_V71K "v71k" 224#define DKW_PTYPE_V8 "v8" 225#define DKW_PTYPE_FFS "ffs" 226#define DKW_PTYPE_FAT "msdos" 227#define DKW_PTYPE_LFS "lfs" 228#define DKW_PTYPE_OTHER "other" 229#define DKW_PTYPE_HPFS "hpfs" 230#define DKW_PTYPE_ISO9660 "cd9660" 231#define DKW_PTYPE_BOOT "boot" 232#define DKW_PTYPE_AMIGADOS "ados" 233#define DKW_PTYPE_HFS "hfs" 234#define DKW_PTYPE_FILECORE "filecore" 235#define DKW_PTYPE_EXT2FS "ext2fs" 236#define DKW_PTYPE_NTFS "ntfs" 237#define DKW_PTYPE_RAIDFRAME "raidframe" 238#define DKW_PTYPE_CCD "ccd" 239#define DKW_PTYPE_JFS2 "jfs2" 240#define DKW_PTYPE_APPLEUFS "appleufs" 241#define DKW_PTYPE_VINUM "vinum" 242#define DKW_PTYPE_UDF "udf" 243#define DKW_PTYPE_APPLEHFS "hfs" 244#define DKW_PTYPE_SYSVBFS "sysvbfs" 245#define DKW_PTYPE_EFS "efs" 246#define DKW_PTYPE_NILFS "nilfs" 247#define DKW_PTYPE_CGD "cgd" 248#define DKW_PTYPE_MINIXFS3 "minixfs3" 249 250/* 251 * Disk geometry dictionary. 252 * 253 * NOTE: Not all geometry information is relevant for every kind of disk. 254 * 255 * <dict> 256 * <key>sectors-per-unit</key> 257 * <integer>...</integer> 258 * <key>sector-size</key> 259 * <integer>...</integer> 260 * <key>sectors-per-track</key> 261 * <integer>...</integer> 262 * <key>tracks-per-cylinder</key> 263 * <integer>...</integer> 264 * <key>cylinders-per-unit</key> 265 * <integer>...</integer> 266 * <key>physical-cylinders-per-unit</key> 267 * <integer>...</integer> 268 * <key>spare-sectors-per-track</key> 269 * <integer>...</integer> 270 * <key>spare-sectors-per-cylinder</key> 271 * <integer>...</integer> 272 * <key>alternative-cylinders</key> 273 * <integer>...</integer> 274 * </dict> 275 * NOTE: Not all geometry information is relevant for every kind of disk. 276 */ 277 278struct disk_geom { 279 int64_t dg_secperunit; /* # of data sectors per unit */ 280 uint32_t dg_secsize; /* # of bytes per sector */ 281 uint32_t dg_nsectors; /* # of data sectors per track */ 282 uint32_t dg_ntracks; /* # of tracks per cylinder */ 283 uint32_t dg_ncylinders; /* # of data cylinders per unit */ 284 uint32_t dg_secpercyl; /* # of data sectors per cylinder */ 285 uint32_t dg_pcylinders; /* # of physical cylinders per unit */ 286 287 /* 288 * Spares (bad sector replacements) below are not counted in 289 * dg_nsectors or dg_secpercyl. Spare sectors are assumed to 290 * be physical sectors which occupy space at the end of each 291 * track and/or cylinder. 292 */ 293 uint32_t dg_sparespertrack; 294 uint32_t dg_sparespercyl; 295 /* 296 * Alternative cylinders include maintenance, replacement, 297 * configuration description areas, etc. 298 */ 299 uint32_t dg_acylinders; 300}; 301 302/* 303 * Disk partition dictionary. 304 * 305 * A partition is represented as a dictionary containing generic partition 306 * properties (such as starting block and block count), as well as information 307 * that is specific to individual partition map formats. 308 * 309 * <dict> 310 * <key>start-block</key> 311 * <integer>...</integer> 312 * <key>block-count</key> 313 * <integer>...</integer> 314 * <!-- DKW_PTYPE strings ("" or missing if unknown) --> 315 * <key>type</type> 316 * <string>...</string> 317 * <!-- optional --> 318 * <key>name</key> 319 * <string>...</string> 320 * 321 * <!-- these are valid for GPT partition maps --> 322 * <key>gpt-type-guid</key> 323 * <string>...</string> 324 * <key>gpt-partition-guid</key> 325 * <string>...</string> 326 * <key>gpt-platform-required</key> 327 * <false/> 328 * 329 * <!-- these are valid for 4.4BSD partition maps --> 330 * <key>bsd44-partition-type</key> 331 * <integer>...</integer> 332 * <key>bsd44-fs-fragment-size</key> 333 * <integer>...</integer> 334 * <key>bsd44-iso9660-session-offset</key> 335 * <integer>...</integer> 336 * <key>bsd44-ffs-cylinders-per-group</key> 337 * <integer>...</integer> 338 * <key>bsd44-lfs-segment-shift</key> 339 * <integer>...</integer> 340 * 341 * <!-- these are valid for NeXT partition maps --> 342 * <key>next-block-size</key> 343 * <integer>...</integer> 344 * <key>next-fs-fragment-size</key> 345 * <integer>...</integer> 346 * <key>next-fs-optimization</key> 347 * <string>...</string> <!-- "space" or "time" --> 348 * <key>next-fs-cylinders-per-group</key> 349 * <integer>...</integer> 350 * <key>next-bytes-per-inode-density</key> 351 * <integer>...</integer> 352 * <key>next-minfree-percentage</key> 353 * <integer>...</integer> 354 * <key>next-run-newfs-during-init</key> 355 * <false/> 356 * <key>next-mount-point</key> 357 * <string>...</string> 358 * <key>next-automount</key> 359 * <true/> 360 * <key>next-partition-type</key> 361 * <string>...</string> 362 * 363 * <!-- these are valid for MBR partition maps --> 364 * <key>mbr-start-head</key> 365 * <integer>...</integer> 366 * <key>mbr-start-sector</key> 367 * <integer>...</integer> 368 * <key>mbr-start-cylinder</key> 369 * <integer>...</integer> 370 * <key>mbr-partition-type</key> 371 * <integer>...</integer> 372 * <key>mbr-end-head</key> 373 * <integer>...</integer> 374 * <key>mbr-end-sector</key> 375 * <integer>...</integer> 376 * <key>mbr-end-cylinder</key> 377 * <integer>...</integer> 378 * <key>mbr-active-partition</key> 379 * <false/> 380 * 381 * <!-- these are valid for Apple partition maps --> 382 * <key>apple-partition-type</key> 383 * <string>...</string> 384 * <!-- XXX What else do we need? wrstuden? --> 385 * 386 * <!-- these are valid for RISCiX partition maps --> 387 * <key>riscix-partition-type</key> 388 * <integer>...</integer> 389 * 390 * <!-- these are valid for MIPS/SGI partition maps --> 391 * <key>mips-partition-type</key> 392 * <integer>...</integer> 393 * 394 * <!-- SunOS 4 partition maps have no specific 395 * additional information. Note, however, 396 * that SunOS 4 partitions must begin on 397 * cylinder boundaries. --> 398 * 399 * <!-- XXX Need Amiga partition map info --> 400 * 401 * <!-- these are valid for VTOC partition maps --> 402 * <key>vtoc-tag</key> 403 * <integer>...</integer> 404 * <key>vtoc-unmount</key> 405 * <false/> 406 * <key>vtoc-read-only</key> 407 * <false/> 408 * <!-- XXX is this really part of the partition info? --> 409 * <key>vtoc-timestamp</key> 410 * <integer>...</integer> 411 * 412 * <!-- mvme68k partition maps use 4.4BSD partition 413 * info stuffed into two different areas of the 414 * disk information label recognized by BUG. --> 415 * 416 * <!-- XXX What else? --> 417 * </dict> 418 */ 419 420struct disk { 421 TAILQ_ENTRY(disk) dk_link; /* link in global disklist */ 422 const char *dk_name; /* disk name */ 423 prop_dictionary_t dk_info; /* reference to disk-info dictionary */ 424 int dk_bopenmask; /* block devices open */ 425 int dk_copenmask; /* character devices open */ 426 int dk_openmask; /* composite (bopen|copen) */ 427 int dk_state; /* label state ### */ 428 int dk_blkshift; /* shift to convert DEV_BSIZE to blks */ 429 int dk_byteshift; /* shift to convert bytes to blks */ 430 431 /* 432 * Metrics data; note that some metrics may have no meaning 433 * on certain types of disks. 434 */ 435 struct io_stats *dk_stats; 436 437 const struct dkdriver *dk_driver; /* pointer to driver */ 438 439 /* 440 * Information required to be the parent of a disk wedge. 441 */ 442 kmutex_t dk_rawlock; /* lock on these fields */ 443 u_int dk_rawopens; /* # of openes of rawvp */ 444 struct vnode *dk_rawvp; /* vnode for the RAW_PART bdev */ 445 446 kmutex_t dk_openlock; /* lock on these and openmask */ 447 u_int dk_nwedges; /* # of configured wedges */ 448 /* all wedges on this disk */ 449 LIST_HEAD(, dkwedge_softc) dk_wedges; 450 451 /* 452 * Disk label information. Storage for the in-core disk label 453 * must be dynamically allocated, otherwise the size of this 454 * structure becomes machine-dependent. 455 */ 456 daddr_t dk_labelsector; /* sector containing label */ 457 struct disklabel *dk_label; /* label */ 458 struct cpu_disklabel *dk_cpulabel; 459}; 460 461struct dkdriver { 462 void (*d_strategy)(struct buf *); 463 void (*d_minphys)(struct buf *); 464#ifdef notyet 465 int (*d_open)(dev_t, int, int, struct proc *); 466 int (*d_close)(dev_t, int, int, struct proc *); 467 int (*d_ioctl)(dev_t, u_long, void *, int, struct proc *); 468 int (*d_dump)(dev_t); 469 void (*d_start)(struct buf *, daddr_t); 470 int (*d_mklabel)(struct disk *); 471#endif 472}; 473 474/* states */ 475#define DK_CLOSED 0 /* drive is closed */ 476#define DK_WANTOPEN 1 /* drive being opened */ 477#define DK_WANTOPENRAW 2 /* drive being opened */ 478#define DK_RDLABEL 3 /* label being read */ 479#define DK_OPEN 4 /* label read, drive open */ 480#define DK_OPENRAW 5 /* open without label */ 481 482/* 483 * Bad sector lists per fixed disk 484 */ 485struct disk_badsectors { 486 SLIST_ENTRY(disk_badsectors) dbs_next; 487 daddr_t dbs_min; /* min. sector number */ 488 daddr_t dbs_max; /* max. sector number */ 489 struct timeval dbs_failedat; /* first failure at */ 490}; 491 492struct disk_badsecinfo { 493 uint32_t dbsi_bufsize; /* size of region pointed to */ 494 uint32_t dbsi_skip; /* how many to skip past */ 495 uint32_t dbsi_copied; /* how many got copied back */ 496 uint32_t dbsi_left; /* remaining to copy */ 497 void * dbsi_buffer; /* region to copy disk_badsectors to */ 498}; 499 500#define DK_STRATEGYNAMELEN 32 501struct disk_strategy { 502 char dks_name[DK_STRATEGYNAMELEN]; /* name of strategy */ 503 char *dks_param; /* notyet; should be NULL */ 504 size_t dks_paramlen; /* notyet; should be 0 */ 505}; 506 507#define DK_BSIZE2BLKSHIFT(b) ((ffs((b) / DEV_BSIZE)) - 1) 508#define DK_BSIZE2BYTESHIFT(b) (ffs((b)) - 1) 509 510#ifdef _KERNEL 511extern int disk_count; /* number of disks in global disklist */ 512 513struct proc; 514 515void disk_attach(struct disk *); 516int disk_begindetach(struct disk *, int (*)(device_t), device_t, int); 517void disk_detach(struct disk *); 518void disk_init(struct disk *, const char *, const struct dkdriver *); 519void disk_destroy(struct disk *); 520void disk_busy(struct disk *); 521void disk_unbusy(struct disk *, long, int); 522bool disk_isbusy(struct disk *); 523void disk_blocksize(struct disk *, int); 524struct disk *disk_find(const char *); 525int disk_ioctl(struct disk *, u_long, void *, int, struct lwp *); 526 527void dkwedge_init(void); 528int dkwedge_add(struct dkwedge_info *); 529int dkwedge_del(struct dkwedge_info *); 530void dkwedge_delall(struct disk *); 531int dkwedge_list(struct disk *, struct dkwedge_list *, struct lwp *); 532void dkwedge_discover(struct disk *); 533int dkwedge_read(struct disk *, struct vnode *, daddr_t, void *, size_t); 534device_t dkwedge_find_by_wname(const char *); 535void dkwedge_print_wnames(void); 536device_t dkwedge_find_partition(device_t, daddr_t, uint64_t); 537#endif 538 539#endif /* _SYS_DISK_H_ */ 540