File:  [DragonFly] / src / sys / dev / disk / ata / ata-raid.h
Revision 1.4: download - view: text, annotated - select for diffs
Wed May 19 22:52:40 2004 UTC (10 years, 3 months ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_Stable, DragonFly_Snap29Sep2004, DragonFly_Snap13Sep2004, DragonFly_RELEASE_1_4_Slip, DragonFly_RELEASE_1_4, DragonFly_RELEASE_1_2_Slip, DragonFly_RELEASE_1_2, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Device layer rollup commit.

* cdevsw_add() is now required.  cdevsw_add() and cdevsw_remove() may specify
  a mask/match indicating the range of supported minor numbers.  Multiple
  cdevsw_add()'s using the same major number, but distinctly different
  ranges, may be issued.  All devices that failed to call cdevsw_add() before
  now do.

* cdevsw_remove() now automatically marks all devices within its supported
  range as being destroyed.

* vnode->v_rdev is no longer resolved when the vnode is created.  Instead,
  only v_udev (a newly added field) is resolved.  v_rdev is resolved when
  the vnode is opened and cleared on the last close.

* A great deal of code was making rather dubious assumptions with regards
  to the validity of devices associated with vnodes, primarily due to
  the persistence of a device structure due to being indexed by (major, minor)
  instead of by (cdevsw, major, minor).  In particular, if you run a program
  which connects to a USB device and then you pull the USB device and plug
  it back in, the vnode subsystem will continue to believe that the device
  is open when, in fact, it isn't (because it was destroyed and recreated).

  In particular, note that all the VFS mount procedures now check devices
  via v_udev instead of v_rdev prior to calling VOP_OPEN(), since v_rdev
  is NULL prior to the first open.

* The disk layer's device interaction has been rewritten.  The disk layer
  (i.e. the slice and disklabel management layer) no longer overloads
  its data onto the device structure representing the underlying physical
  disk.  Instead, the disk layer uses the new cdevsw_add() functionality
  to register its own cdevsw using the underlying device's major number,
  and simply does NOT register the underlying device's cdevsw.  No
  confusion is created because the device hash is now based on
  (cdevsw,major,minor) rather then (major,minor).

  NOTE: This also means that underlying raw disk devices may use the entire
  device minor number instead of having to reserve the bits used by the disk
  layer, and also means that can we (theoretically) stack a fully
  disklabel-supported 'disk' on top of any block device.

* The new reference counting scheme prevents this by associating a device
  with a cdevsw and disconnecting the device from its cdevsw when the cdevsw
  is removed.  Additionally, all udev2dev() lookups run through the cdevsw
  mask/match and only successfully find devices still associated with an
  active cdevsw.

* Major work on MFS:  MFS no longer shortcuts vnode and device creation.  It
  now creates a real vnode and a real device and implements real open and
  close VOPs.  Additionally, due to the disk layer changes, MFS is no longer
  limited to 255 mounts.  The new limit is 16 million.  Since MFS creates a
  real device node, mount_mfs will now create a real /dev/mfs<PID> device
  that can be read from userland (e.g. so you can dump an MFS filesystem).

* BUF AND DEVICE STRATEGY changes.  The struct buf contains a b_dev field.
  In order to properly handle stacked devices we now require that the b_dev
  field be initialized before the device strategy routine is called.  This
  required some additional work in various VFS implementations.  To enforce
  this requirement, biodone() now sets b_dev to NODEV.  The new disk layer
  will adjust b_dev before forwarding a request to the actual physical
  device.

* A bug in the ISO CD boot sequence which resulted in a panic has been fixed.

Testing by: lots of people, but David Rhodus found the most aggregious bugs.

    1: /*-
    2:  * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer,
   10:  *    without modification, immediately at the beginning of the file.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  * 3. The name of the author may not be used to endorse or promote products
   15:  *    derived from this software without specific prior written permission.
   16:  *
   17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27:  *
   28:  * $FreeBSD: src/sys/dev/ata/ata-raid.h,v 1.2.2.8 2002/04/11 09:31:57 sos Exp $
   29:  * $DragonFly: src/sys/dev/disk/ata/ata-raid.h,v 1.4 2004/05/19 22:52:40 dillon Exp $
   30:  */
   31: 
   32: /* misc defines */
   33: #define MAX_ARRAYS	16
   34: #define MAX_DISKS	16
   35: #define AR_PROXIMITY	2048
   36: #define AR_READ		0x01
   37: #define AR_WRITE	0x02
   38: #define AR_WAIT		0x04
   39: #define AR_STRATEGY(x)	dev_dstrategy((x)->b_dev, x)
   40: #define AD_SOFTC(x)	((struct ad_softc *)(x.device->driver))
   41: #define ATA_MAGIC	"FreeBSD ATA driver RAID "
   42: 
   43: struct ar_disk {
   44:     struct ata_device	*device;
   45:     u_int64_t		disk_sectors;	/* sectors on this disk */
   46:     off_t		last_lba;	/* last lba used */
   47:     int			flags;
   48: #define AR_DF_PRESENT		0x00000001
   49: #define AR_DF_ASSIGNED		0x00000002
   50: #define AR_DF_SPARE		0x00000004
   51: #define AR_DF_ONLINE		0x00000008
   52: };
   53: 
   54: struct ar_softc {
   55:     int			lun;
   56:     int32_t		magic_0;	/* ident for this array */
   57:     int32_t		magic_1;	/* ident for this array */
   58:     int			flags;
   59: #define AR_F_RAID0		0x0001	/* STRIPE */
   60: #define AR_F_RAID1		0x0002	/* MIRROR */
   61: #define AR_F_SPAN		0x0004	/* SPAN */
   62: #define AR_F_READY		0x0100
   63: #define AR_F_DEGRADED		0x0200
   64: #define AR_F_REBUILDING		0x0400
   65: #define AR_F_PROMISE_RAID	0x1000
   66: #define AR_F_HIGHPOINT_RAID	0x2000
   67: #define AR_F_FREEBSD_RAID	0x4000
   68:     
   69:     int			total_disks;	/* number of disks in this array */
   70:     int			generation;	/* generation of this array */
   71:     struct ar_disk	disks[MAX_DISKS+1]; /* ptr to each disk in array */
   72:     int			width;		/* array width in disks */
   73:     u_int16_t		heads;
   74:     u_int16_t		sectors;
   75:     u_int32_t		cylinders;
   76:     u_int64_t		total_sectors;
   77:     int			interleave;	/* interleave in blocks */
   78:     int			reserved;	/* sectors that are NOT to be used */
   79:     int			offset;		/* offset from start of disk */
   80:     u_int64_t		lock_start;	/* start of locked area for rebuild */
   81:     u_int64_t		lock_end;	/* end of locked area for rebuild */
   82:     struct disk		disk;		/* disklabel/slice stuff */
   83:     struct proc		*pid;
   84:     dev_t		dev;		/* device place holder */
   85: };
   86: 
   87: struct ar_buf {
   88:     struct buf		bp;		/* must be first element! */
   89:     struct buf		*org;
   90:     struct ar_buf	*mirror;
   91:     int			drive;
   92:     int			flags;
   93: #define AB_F_DONE		0x01
   94: };
   95: 
   96: #define HPT_LBA			9
   97: 
   98: struct highpoint_raid_conf {
   99:     int8_t		filler1[32];
  100:     u_int32_t		magic;			/* 0x20 */
  101: #define HPT_MAGIC_OK		0x5a7816f0
  102: #define HPT_MAGIC_BAD		0x5a7816fd
  103: 
  104:     u_int32_t		magic_0;
  105:     u_int32_t		magic_1;
  106:     u_int32_t		order;
  107: #define HPT_O_RAID0		0x01
  108: #define HPT_O_RAID1		0x02
  109: #define HPT_O_OK		0x04
  110: 
  111:     u_int8_t		array_width;
  112:     u_int8_t		stripe_shift;
  113:     u_int8_t		type;
  114: #define HPT_T_RAID0		0x00
  115: #define HPT_T_RAID1		0x01
  116: #define HPT_T_RAID01_RAID0	0x02
  117: #define HPT_T_SPAN		0x03
  118: #define HPT_T_RAID_3		0x04
  119: #define HPT_T_RAID_5		0x05
  120: #define HPT_T_SINGLEDISK	0x06
  121: #define HPT_T_RAID01_RAID1	0x07
  122: 
  123:     u_int8_t		disk_number;
  124:     u_int32_t		total_sectors;
  125:     u_int32_t		disk_mode;
  126:     u_int32_t		boot_mode;
  127:     u_int8_t		boot_disk;
  128:     u_int8_t		boot_protect;
  129:     u_int8_t		error_log_entries;
  130:     u_int8_t		error_log_index;
  131:     struct {
  132: 	u_int32_t	timestamp;
  133: 	u_int8_t	reason;
  134: #define HPT_R_REMOVED		0xfe
  135: #define HPT_R_BROKEN		0xff
  136: 	
  137: 	u_int8_t	disk;
  138: 	u_int8_t	status;
  139: 	u_int8_t	sectors;
  140: 	u_int32_t	lba;
  141:     } errorlog[32];
  142:     int8_t		filler2[16];
  143:     u_int32_t		rebuild_lba;
  144:     u_int8_t		dummy_1;
  145:     u_int8_t		name_1[15];
  146:     u_int8_t		dummy_2;
  147:     u_int8_t		name_2[15];
  148:     int8_t		filler3[8];
  149: } __attribute__((packed));
  150: 
  151: 
  152: #define PR_LBA(adp) \
  153: 	(((adp->total_secs / (adp->heads * adp->sectors)) * \
  154: 	  adp->heads * adp->sectors) - adp->sectors)
  155: 
  156: struct promise_raid_conf {
  157:     char		promise_id[24];
  158: #define PR_MAGIC	"Promise Technology, Inc."
  159: 
  160:     u_int32_t		dummy_0;
  161:     u_int64_t		magic_0;
  162: #define PR_MAGIC0(x)	(x.device ? ((u_int64_t)x.device->channel->unit<<48) | \
  163: 			((u_int64_t)(x.device->unit != 0) << 56) : 0)
  164:     u_int16_t		magic_1;
  165:     u_int32_t		magic_2;
  166:     u_int8_t		filler1[470];
  167:     struct {
  168: 	u_int32_t	integrity;		/* 0x200 */
  169: #define PR_I_VALID		0x00000080
  170: 
  171: 	u_int8_t	flags;
  172: #define PR_F_VALID		0x00000001
  173: #define PR_F_ONLINE		0x00000002
  174: #define PR_F_ASSIGNED		0x00000004
  175: #define PR_F_SPARE		0x00000008
  176: #define PR_F_DUPLICATE		0x00000010
  177: #define PR_F_REDIR		0x00000020
  178: #define PR_F_DOWN		0x00000040
  179: #define PR_F_READY		0x00000080
  180: 
  181: 	u_int8_t	disk_number;
  182: 	u_int8_t	channel;
  183: 	u_int8_t	device;
  184: 	u_int64_t	magic_0 __attribute__((packed));
  185: 	u_int32_t	disk_offset;		/* 0x210 */
  186: 	u_int32_t	disk_sectors;
  187: 	u_int32_t	rebuild_lba;
  188: 	u_int16_t	generation;
  189: 	u_int8_t	status;
  190: #define PR_S_VALID		0x01
  191: #define PR_S_ONLINE		0x02
  192: #define PR_S_INITED		0x04
  193: #define PR_S_READY		0x08
  194: #define PR_S_DEGRADED		0x10
  195: #define PR_S_MARKED		0x20
  196: #define PR_S_FUNCTIONAL		0x80
  197: 
  198: 	u_int8_t	type;
  199: #define PR_T_RAID0		0x00
  200: #define PR_T_RAID1		0x01
  201: #define PR_T_RAID3		0x02
  202: #define PR_T_RAID5		0x04
  203: #define PR_T_SPAN		0x08
  204: 
  205: 	u_int8_t	total_disks;		/* 0x220 */
  206: 	u_int8_t	stripe_shift;
  207: 	u_int8_t	array_width;
  208: 	u_int8_t	array_number;
  209: 	u_int32_t	total_sectors;
  210: 	u_int16_t	cylinders;
  211: 	u_int8_t	heads;
  212: 	u_int8_t	sectors;
  213: 	int64_t		magic_1 __attribute__((packed));
  214: 	struct {				/* 0x240 */
  215: 	    u_int8_t	flags;
  216: 	    u_int8_t	dummy_0;
  217: 	    u_int8_t	channel;
  218: 	    u_int8_t	device;
  219: 	    u_int64_t	magic_0 __attribute__((packed));
  220: 	} disk[8];
  221:     } raid;
  222:     int32_t		filler2[346];
  223:     u_int32_t		checksum;
  224: } __attribute__((packed));
  225: 
  226: int ata_raiddisk_probe(struct ad_softc *);
  227: int ata_raiddisk_attach(struct ad_softc *);
  228: int ata_raiddisk_detach(struct ad_softc *);
  229: void ata_raid_attach(void);
  230: int ata_raid_create(struct raid_setup *);
  231: int ata_raid_delete(int);
  232: int ata_raid_status(int array, struct raid_status *);
  233: int ata_raid_rebuild(int);
  234: