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