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