Home | History | Annotate | Download | only in linux
      1 #ifndef _LINUX_GENHD_H
      2 #define _LINUX_GENHD_H
      3 
      4 /*
      5  * 	genhd.h Copyright (C) 1992 Drew Eckhardt
      6  *	Generic hard disk header file by
      7  * 		Drew Eckhardt
      8  *
      9  *		<drew (at) colorado.edu>
     10  */
     11 
     12 #include <linux/types.h>
     13 
     14 enum {
     15 /* These three have identical behaviour; use the second one if DOS FDISK gets
     16    confused about extended/logical partitions starting past cylinder 1023. */
     17 	DOS_EXTENDED_PARTITION = 5,
     18 	LINUX_EXTENDED_PARTITION = 0x85,
     19 	WIN98_EXTENDED_PARTITION = 0x0f,
     20 
     21 	LINUX_SWAP_PARTITION = 0x82,
     22 	LINUX_RAID_PARTITION = 0xfd,	/* autodetect RAID partition */
     23 
     24 	SOLARIS_X86_PARTITION =	LINUX_SWAP_PARTITION,
     25 	NEW_SOLARIS_X86_PARTITION = 0xbf,
     26 
     27 	DM6_AUX1PARTITION = 0x51,	/* no DDO:  use xlated geom */
     28 	DM6_AUX3PARTITION = 0x53,	/* no DDO:  use xlated geom */
     29 	DM6_PARTITION =	0x54,		/* has DDO: use xlated geom & offset */
     30 	EZD_PARTITION =	0x55,		/* EZ-DRIVE */
     31 
     32 	FREEBSD_PARTITION = 0xa5,	/* FreeBSD Partition ID */
     33 	OPENBSD_PARTITION = 0xa6,	/* OpenBSD Partition ID */
     34 	NETBSD_PARTITION = 0xa9,	/* NetBSD Partition ID */
     35 	BSDI_PARTITION = 0xb7,		/* BSDI Partition ID */
     36 	MINIX_PARTITION = 0x81,		/* Minix Partition ID */
     37 	UNIXWARE_PARTITION = 0x63,	/* Same as GNU_HURD and SCO Unix */
     38 };
     39 
     40 #ifndef __KERNEL__
     41 
     42 struct partition {
     43 	unsigned char boot_ind;		/* 0x80 - active */
     44 	unsigned char head;		/* starting head */
     45 	unsigned char sector;		/* starting sector */
     46 	unsigned char cyl;		/* starting cylinder */
     47 	unsigned char sys_ind;		/* What partition type */
     48 	unsigned char end_head;		/* end head */
     49 	unsigned char end_sector;	/* end sector */
     50 	unsigned char end_cyl;		/* end cylinder */
     51 	unsigned int start_sect;	/* starting sector counting from 0 */
     52 	unsigned int nr_sects;		/* nr of sectors in partition */
     53 } __attribute__((packed));
     54 
     55 #endif
     56 
     57 #ifdef __KERNEL__
     58 #include <linux/major.h>
     59 #include <linux/device.h>
     60 #include <linux/smp.h>
     61 #include <linux/string.h>
     62 #include <linux/fs.h>
     63 
     64 struct partition {
     65 	unsigned char boot_ind;		/* 0x80 - active */
     66 	unsigned char head;		/* starting head */
     67 	unsigned char sector;		/* starting sector */
     68 	unsigned char cyl;		/* starting cylinder */
     69 	unsigned char sys_ind;		/* What partition type */
     70 	unsigned char end_head;		/* end head */
     71 	unsigned char end_sector;	/* end sector */
     72 	unsigned char end_cyl;		/* end cylinder */
     73 	__le32 start_sect;	/* starting sector counting from 0 */
     74 	__le32 nr_sects;		/* nr of sectors in partition */
     75 } __attribute__((packed));
     76 
     77 struct hd_struct {
     78 	sector_t start_sect;
     79 	sector_t nr_sects;
     80 	struct kobject kobj;
     81 	struct kobject *holder_dir;
     82 	unsigned ios[2], sectors[2];	/* READs and WRITEs */
     83 	int policy, partno;
     84 };
     85 
     86 #define GENHD_FL_REMOVABLE			1
     87 #define GENHD_FL_DRIVERFS			2
     88 #define GENHD_FL_CD				8
     89 #define GENHD_FL_UP				16
     90 #define GENHD_FL_SUPPRESS_PARTITION_INFO	32
     91 
     92 struct disk_stats {
     93 	unsigned long sectors[2];	/* READs and WRITEs */
     94 	unsigned long ios[2];
     95 	unsigned long merges[2];
     96 	unsigned long ticks[2];
     97 	unsigned long io_ticks;
     98 	unsigned long time_in_queue;
     99 };
    100 
    101 struct gendisk {
    102 	int major;			/* major number of driver */
    103 	int first_minor;
    104 	int minors;                     /* maximum number of minors, =1 for
    105                                          * disks that can't be partitioned. */
    106 	char disk_name[32];		/* name of major driver */
    107 	struct hd_struct **part;	/* [indexed by minor] */
    108 	int part_uevent_suppress;
    109 	struct block_device_operations *fops;
    110 	struct request_queue *queue;
    111 	void *private_data;
    112 	sector_t capacity;
    113 
    114 	int flags;
    115 	struct device *driverfs_dev;
    116 	struct kobject kobj;
    117 	struct kobject *holder_dir;
    118 	struct kobject *slave_dir;
    119 
    120 	struct timer_rand_state *random;
    121 	int policy;
    122 
    123 	atomic_t sync_io;		/* RAID */
    124 	unsigned long stamp;
    125 	int in_flight;
    126 #ifdef	CONFIG_SMP
    127 	struct disk_stats *dkstats;
    128 #else
    129 	struct disk_stats dkstats;
    130 #endif
    131 };
    132 
    133 /* Structure for sysfs attributes on block devices */
    134 struct disk_attribute {
    135 	struct attribute attr;
    136 	ssize_t (*show)(struct gendisk *, char *);
    137 	ssize_t (*store)(struct gendisk *, const char *, size_t);
    138 };
    139 
    140 /*
    141  * Macros to operate on percpu disk statistics:
    142  *
    143  * The __ variants should only be called in critical sections. The full
    144  * variants disable/enable preemption.
    145  */
    146 #ifdef	CONFIG_SMP
    147 #define __disk_stat_add(gendiskp, field, addnd) 	\
    148 	(per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd)
    149 
    150 #define disk_stat_read(gendiskp, field)					\
    151 ({									\
    152 	typeof(gendiskp->dkstats->field) res = 0;			\
    153 	int i;								\
    154 	for_each_possible_cpu(i)					\
    155 		res += per_cpu_ptr(gendiskp->dkstats, i)->field;	\
    156 	res;								\
    157 })
    158 
    159 static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)	{
    160 	int i;
    161 	for_each_possible_cpu(i)
    162 		memset(per_cpu_ptr(gendiskp->dkstats, i), value,
    163 				sizeof (struct disk_stats));
    164 }
    165 
    166 #else
    167 #define __disk_stat_add(gendiskp, field, addnd) \
    168 				(gendiskp->dkstats.field += addnd)
    169 #define disk_stat_read(gendiskp, field)	(gendiskp->dkstats.field)
    170 
    171 static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)	{
    172 	memset(&gendiskp->dkstats, value, sizeof (struct disk_stats));
    173 }
    174 #endif
    175 
    176 #define disk_stat_add(gendiskp, field, addnd)			\
    177 	do {							\
    178 		preempt_disable();				\
    179 		__disk_stat_add(gendiskp, field, addnd);	\
    180 		preempt_enable();				\
    181 	} while (0)
    182 
    183 #define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1)
    184 #define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1)
    185 
    186 #define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1)
    187 #define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1)
    188 
    189 #define __disk_stat_sub(gendiskp, field, subnd) \
    190 		__disk_stat_add(gendiskp, field, -subnd)
    191 #define disk_stat_sub(gendiskp, field, subnd) \
    192 		disk_stat_add(gendiskp, field, -subnd)
    193 
    194 
    195 /* Inlines to alloc and free disk stats in struct gendisk */
    196 #ifdef  CONFIG_SMP
    197 static inline int init_disk_stats(struct gendisk *disk)
    198 {
    199 	disk->dkstats = alloc_percpu(struct disk_stats);
    200 	if (!disk->dkstats)
    201 		return 0;
    202 	return 1;
    203 }
    204 
    205 static inline void free_disk_stats(struct gendisk *disk)
    206 {
    207 	free_percpu(disk->dkstats);
    208 }
    209 #else	/* CONFIG_SMP */
    210 static inline int init_disk_stats(struct gendisk *disk)
    211 {
    212 	return 1;
    213 }
    214 
    215 static inline void free_disk_stats(struct gendisk *disk)
    216 {
    217 }
    218 #endif	/* CONFIG_SMP */
    219 
    220 /* drivers/block/ll_rw_blk.c */
    221 extern void disk_round_stats(struct gendisk *disk);
    222 
    223 /* drivers/block/genhd.c */
    224 extern int get_blkdev_list(char *, int);
    225 extern void add_disk(struct gendisk *disk);
    226 extern void del_gendisk(struct gendisk *gp);
    227 extern void unlink_gendisk(struct gendisk *gp);
    228 extern struct gendisk *get_gendisk(dev_t dev, int *part);
    229 
    230 extern void set_device_ro(struct block_device *bdev, int flag);
    231 extern void set_disk_ro(struct gendisk *disk, int flag);
    232 
    233 /* drivers/char/random.c */
    234 extern void add_disk_randomness(struct gendisk *disk);
    235 extern void rand_initialize_disk(struct gendisk *disk);
    236 
    237 static inline sector_t get_start_sect(struct block_device *bdev)
    238 {
    239 	return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect;
    240 }
    241 static inline sector_t get_capacity(struct gendisk *disk)
    242 {
    243 	return disk->capacity;
    244 }
    245 static inline void set_capacity(struct gendisk *disk, sector_t size)
    246 {
    247 	disk->capacity = size;
    248 }
    249 
    250 #endif  /*  __KERNEL__  */
    251 
    252 #ifdef CONFIG_SOLARIS_X86_PARTITION
    253 
    254 #define SOLARIS_X86_NUMSLICE	8
    255 #define SOLARIS_X86_VTOC_SANE	(0x600DDEEEUL)
    256 
    257 struct solaris_x86_slice {
    258 	__le16 s_tag;		/* ID tag of partition */
    259 	__le16 s_flag;		/* permission flags */
    260 	__le32 s_start;		/* start sector no of partition */
    261 	__le32 s_size;		/* # of blocks in partition */
    262 };
    263 
    264 struct solaris_x86_vtoc {
    265 	unsigned int v_bootinfo[3];	/* info needed by mboot (unsupported) */
    266 	__le32 v_sanity;		/* to verify vtoc sanity */
    267 	__le32 v_version;		/* layout version */
    268 	char	v_volume[8];		/* volume name */
    269 	__le16	v_sectorsz;		/* sector size in bytes */
    270 	__le16	v_nparts;		/* number of partitions */
    271 	unsigned int v_reserved[10];	/* free space */
    272 	struct solaris_x86_slice
    273 		v_slice[SOLARIS_X86_NUMSLICE]; /* slice headers */
    274 	unsigned int timestamp[SOLARIS_X86_NUMSLICE]; /* timestamp (unsupported) */
    275 	char	v_asciilabel[128];	/* for compatibility */
    276 };
    277 
    278 #endif /* CONFIG_SOLARIS_X86_PARTITION */
    279 
    280 #ifdef CONFIG_BSD_DISKLABEL
    281 /*
    282  * BSD disklabel support by Yossi Gottlieb <yogo (at) math.tau.ac.il>
    283  * updated by Marc Espie <Marc.Espie (at) openbsd.org>
    284  */
    285 
    286 /* check against BSD src/sys/sys/disklabel.h for consistency */
    287 
    288 #define BSD_DISKMAGIC	(0x82564557UL)	/* The disk magic number */
    289 #define BSD_MAXPARTITIONS	16
    290 #define OPENBSD_MAXPARTITIONS	16
    291 #define BSD_FS_UNUSED		0	/* disklabel unused partition entry ID */
    292 struct bsd_disklabel {
    293 	__le32	d_magic;		/* the magic number */
    294 	__s16	d_type;			/* drive type */
    295 	__s16	d_subtype;		/* controller/d_type specific */
    296 	char	d_typename[16];		/* type name, e.g. "eagle" */
    297 	char	d_packname[16];			/* pack identifier */
    298 	__u32	d_secsize;		/* # of bytes per sector */
    299 	__u32	d_nsectors;		/* # of data sectors per track */
    300 	__u32	d_ntracks;		/* # of tracks per cylinder */
    301 	__u32	d_ncylinders;		/* # of data cylinders per unit */
    302 	__u32	d_secpercyl;		/* # of data sectors per cylinder */
    303 	__u32	d_secperunit;		/* # of data sectors per unit */
    304 	__u16	d_sparespertrack;	/* # of spare sectors per track */
    305 	__u16	d_sparespercyl;		/* # of spare sectors per cylinder */
    306 	__u32	d_acylinders;		/* # of alt. cylinders per unit */
    307 	__u16	d_rpm;			/* rotational speed */
    308 	__u16	d_interleave;		/* hardware sector interleave */
    309 	__u16	d_trackskew;		/* sector 0 skew, per track */
    310 	__u16	d_cylskew;		/* sector 0 skew, per cylinder */
    311 	__u32	d_headswitch;		/* head switch time, usec */
    312 	__u32	d_trkseek;		/* track-to-track seek, usec */
    313 	__u32	d_flags;		/* generic flags */
    314 #define NDDATA 5
    315 	__u32	d_drivedata[NDDATA];	/* drive-type specific information */
    316 #define NSPARE 5
    317 	__u32	d_spare[NSPARE];	/* reserved for future use */
    318 	__le32	d_magic2;		/* the magic number (again) */
    319 	__le16	d_checksum;		/* xor of data incl. partitions */
    320 
    321 			/* filesystem and partition information: */
    322 	__le16	d_npartitions;		/* number of partitions in following */
    323 	__le32	d_bbsize;		/* size of boot area at sn0, bytes */
    324 	__le32	d_sbsize;		/* max size of fs superblock, bytes */
    325 	struct	bsd_partition {		/* the partition table */
    326 		__le32	p_size;		/* number of sectors in partition */
    327 		__le32	p_offset;	/* starting sector */
    328 		__le32	p_fsize;	/* filesystem basic fragment size */
    329 		__u8	p_fstype;	/* filesystem type, see below */
    330 		__u8	p_frag;		/* filesystem fragments per block */
    331 		__le16	p_cpg;		/* filesystem cylinders per group */
    332 	} d_partitions[BSD_MAXPARTITIONS];	/* actually may be more */
    333 };
    334 
    335 #endif	/* CONFIG_BSD_DISKLABEL */
    336 
    337 #ifdef CONFIG_UNIXWARE_DISKLABEL
    338 /*
    339  * Unixware slices support by Andrzej Krzysztofowicz <ankry (at) mif.pg.gda.pl>
    340  * and Krzysztof G. Baranowski <kgb (at) knm.org.pl>
    341  */
    342 
    343 #define UNIXWARE_DISKMAGIC     (0xCA5E600DUL)	/* The disk magic number */
    344 #define UNIXWARE_DISKMAGIC2    (0x600DDEEEUL)	/* The slice table magic nr */
    345 #define UNIXWARE_NUMSLICE      16
    346 #define UNIXWARE_FS_UNUSED     0		/* Unused slice entry ID */
    347 
    348 struct unixware_slice {
    349 	__le16   s_label;	/* label */
    350 	__le16   s_flags;	/* permission flags */
    351 	__le32   start_sect;	/* starting sector */
    352 	__le32   nr_sects;	/* number of sectors in slice */
    353 };
    354 
    355 struct unixware_disklabel {
    356 	__le32   d_type;               	/* drive type */
    357 	__le32   d_magic;                /* the magic number */
    358 	__le32   d_version;              /* version number */
    359 	char    d_serial[12];           /* serial number of the device */
    360 	__le32   d_ncylinders;           /* # of data cylinders per device */
    361 	__le32   d_ntracks;              /* # of tracks per cylinder */
    362 	__le32   d_nsectors;             /* # of data sectors per track */
    363 	__le32   d_secsize;              /* # of bytes per sector */
    364 	__le32   d_part_start;           /* # of first sector of this partition */
    365 	__le32   d_unknown1[12];         /* ? */
    366  	__le32	d_alt_tbl;              /* byte offset of alternate table */
    367  	__le32	d_alt_len;              /* byte length of alternate table */
    368  	__le32	d_phys_cyl;             /* # of physical cylinders per device */
    369  	__le32	d_phys_trk;             /* # of physical tracks per cylinder */
    370  	__le32	d_phys_sec;             /* # of physical sectors per track */
    371  	__le32	d_phys_bytes;           /* # of physical bytes per sector */
    372  	__le32	d_unknown2;             /* ? */
    373 	__le32   d_unknown3;             /* ? */
    374 	__le32	d_pad[8];               /* pad */
    375 
    376 	struct unixware_vtoc {
    377 		__le32	v_magic;		/* the magic number */
    378 		__le32	v_version;		/* version number */
    379 		char	v_name[8];		/* volume name */
    380 		__le16	v_nslices;		/* # of slices */
    381 		__le16	v_unknown1;		/* ? */
    382 		__le32	v_reserved[10];		/* reserved */
    383 		struct unixware_slice
    384 			v_slice[UNIXWARE_NUMSLICE];	/* slice headers */
    385 	} vtoc;
    386 
    387 };  /* 408 */
    388 
    389 #endif /* CONFIG_UNIXWARE_DISKLABEL */
    390 
    391 #ifdef CONFIG_MINIX_SUBPARTITION
    392 #   define MINIX_NR_SUBPARTITIONS  4
    393 #endif /* CONFIG_MINIX_SUBPARTITION */
    394 
    395 #ifdef __KERNEL__
    396 
    397 char *disk_name (struct gendisk *hd, int part, char *buf);
    398 
    399 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
    400 extern void add_partition(struct gendisk *, int, sector_t, sector_t);
    401 extern void delete_partition(struct gendisk *, int);
    402 
    403 extern struct gendisk *alloc_disk_node(int minors, int node_id);
    404 extern struct gendisk *alloc_disk(int minors);
    405 extern struct kobject *get_disk(struct gendisk *disk);
    406 extern void put_disk(struct gendisk *disk);
    407 
    408 extern void blk_register_region(dev_t dev, unsigned long range,
    409 			struct module *module,
    410 			struct kobject *(*probe)(dev_t, int *, void *),
    411 			int (*lock)(dev_t, void *),
    412 			void *data);
    413 extern void blk_unregister_region(dev_t dev, unsigned long range);
    414 
    415 static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
    416 {
    417 	return bdget(MKDEV(disk->major, disk->first_minor) + index);
    418 }
    419 
    420 #endif
    421 
    422 #endif
    423