freebsd-skq/sys/sys/disk.h
Justin T. Gibbs 416494d7c9 Plumb device physical path reporting from CAM devices, through GEOM and
DEVFS, and make it accessible via the diskinfo utility.

Extend GEOM's generic attribute query mechanism into generic disk consumers.
sys/geom/geom_disk.c:
sys/geom/geom_disk.h:
sys/cam/scsi/scsi_da.c:
sys/cam/ata/ata_da.c:
	- Allow disk providers to implement a new method which can override
	  the default BIO_GETATTR response, d_getattr(struct bio *).  This
	  function returns -1 if not handled, otherwise it returns 0 or an
	  errno to be passed to g_io_deliver().

sys/cam/scsi/scsi_da.c:
sys/cam/ata/ata_da.c:
	- Don't copy the serial number to dp->d_ident anymore, as the CAM XPT
	  is now responsible for returning this information via
	  d_getattr()->(a)dagetattr()->xpt_getatr().

sys/geom/geom_dev.c:
	- Implement a new ioctl, DIOCGPHYSPATH, which returns the GEOM
	  attribute "GEOM::physpath", if possible.  If the attribute request
	  returns a zero-length string, ENOENT is returned.

usr.sbin/diskinfo/diskinfo.c:
	- If the DIOCGPHYSPATH ioctl is successful, report physical path
	  data when diskinfo is executed with the '-v' option.

Submitted by:	will
Reviewed by:	gibbs
Sponsored by:	Spectra Logic Corporation

Add generic attribute change notification support to GEOM.

sys/sys/geom/geom.h:
	Add a new attrchanged method field to both g_class
	and g_geom.

sys/sys/geom/geom.h:
sys/geom/geom_event.c:
	- Provide the g_attr_changed() function that providers
	  can use to advertise attribute changes.
	- Perform delivery of attribute change notifications
	  from a thread context via the standard GEOM event
	  mechanism.

sys/geom/geom_subr.c:
	Inherit the attrchanged method from class to geom (class instance).

sys/geom/geom_disk.c:
	Provide disk_attr_changed() to provide g_attr_changed() access
	to consumers of the disk API.

sys/cam/scsi/scsi_pass.c:
sys/cam/scsi/scsi_da.c:
sys/geom/geom_dev.c:
sys/geom/geom_disk.c:
	Use attribute changed events to track updates to physical path
	information.

sys/cam/scsi/scsi_da.c:
	Add AC_ADVINFO_CHANGED to the registered asynchronous CAM
	events for this driver.  When this event occurs, and
	the updated buffer type references our physical path
	attribute, emit a GEOM attribute changed event via the
	disk_attr_changed() API.

sys/cam/scsi/scsi_pass.c:
	Add AC_ADVINFO_CHANGED to the registered asynchronous CAM
	events for this driver.  When this event occurs, update
	the physical patch devfs alias for this pass instance.

Submitted by:	gibbs
Sponsored by:	Spectra Logic Corporation
2011-06-14 17:10:32 +00:00

128 lines
4.3 KiB
C

/*-
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $FreeBSD$
*
*/
#ifndef _SYS_DISK_H_
#define _SYS_DISK_H_
#include <sys/ioccom.h>
#ifdef _KERNEL
#ifndef _SYS_CONF_H_
#include <sys/conf.h> /* XXX: temporary to avoid breakage */
#endif
void disk_err(struct bio *bp, const char *what, int blkdone, int nl);
#endif
#define DIOCGSECTORSIZE _IOR('d', 128, u_int)
/*
* Get the sector size of the device in bytes. The sector size is the
* smallest unit of data which can be transferred from this device.
* Usually this is a power of 2 but it might not be (i.e. CDROM audio).
*/
#define DIOCGMEDIASIZE _IOR('d', 129, off_t) /* Get media size in bytes */
/*
* Get the size of the entire device in bytes. This should be a
* multiple of the sector size.
*/
#define DIOCGFWSECTORS _IOR('d', 130, u_int) /* Get firmware's sectorcount */
/*
* Get the firmware's notion of number of sectors per track. This
* value is mostly used for compatibility with various ill designed
* disk label formats. Don't use it unless you have to.
*/
#define DIOCGFWHEADS _IOR('d', 131, u_int) /* Get firmware's headcount */
/*
* Get the firmwares notion of number of heads per cylinder. This
* value is mostly used for compatibility with various ill designed
* disk label formats. Don't use it unless you have to.
*/
#define DIOCSKERNELDUMP _IOW('d', 133, u_int) /* Set/Clear kernel dumps */
/*
* Enable/Disable (the argument is boolean) the device for kernel
* core dumps.
*/
#define DIOCGFRONTSTUFF _IOR('d', 134, off_t)
/*
* Many disk formats have some amount of space reserved at the
* start of the disk to hold bootblocks, various disklabels and
* similar stuff. This ioctl returns the number of such bytes
* which may apply to the device.
*/
#define DIOCGFLUSH _IO('d', 135) /* Flush write cache */
/*
* Flush write cache of the device.
*/
#define DIOCGDELETE _IOW('d', 136, off_t[2]) /* Delete data */
/*
* Mark data on the device as unused.
*/
#define DISK_IDENT_SIZE 256
#define DIOCGIDENT _IOR('d', 137, char[DISK_IDENT_SIZE])
/*-
* Get the ident of the given provider. Ident is (most of the time)
* a uniqe and fixed provider's identifier. Ident's properties are as
* follow:
* - ident value is preserved between reboots,
* - provider can be detached/attached and ident is preserved,
* - provider's name can change - ident can't,
* - ident value should not be based on on-disk metadata; in other
* words copying whole data from one disk to another should not
* yield the same ident for the other disk,
* - there could be more than one provider with the same ident, but
* only if they point at exactly the same physical storage, this is
* the case for multipathing for example,
* - GEOM classes that consumes single providers and provide single
* providers, like geli, gbde, should just attach class name to the
* ident of the underlying provider,
* - ident is an ASCII string (is printable),
* - ident is optional and applications can't relay on its presence.
*/
#define DIOCGPROVIDERNAME _IOR('d', 138, char[MAXPATHLEN])
/*
* Store the provider name, given a device path, in a buffer. The buffer
* must be at least MAXPATHLEN bytes long.
*/
#define DIOCGSTRIPESIZE _IOR('d', 139, off_t) /* Get stripe size in bytes */
/*
* Get the size of the device's optimal access block in bytes.
* This should be a multiple of the sector size.
*/
#define DIOCGSTRIPEOFFSET _IOR('d', 140, off_t) /* Get stripe offset in bytes */
/*
* Get the offset of the first device's optimal access block in bytes.
* This should be a multiple of the sector size.
*/
#define DIOCGPHYSPATH _IOR('d', 141, char[MAXPATHLEN])
/*
* Get a string defining the physical path for a given provider.
* This has similar rules to ident, but is intended to uniquely
* identify the physical location of the device, not the current
* occupant of that location.
*/
#endif /* _SYS_DISK_H_ */