code:
/* $FreeBSD: release/9.0.0/sys/cam/scsi/scsi_ses.h 222339 2011-05-27 03:44:47Z mav $ */
/*-
 * Copyright (c) 2000 by Matthew Jacob
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification, immediately at the beginning of the file.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * the GNU Public License ("GPL").
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#define	SESIOC			('s' - 040)
#define	SESIOC_GETNOBJ		_IO(SESIOC, 1)
#define	SESIOC_GETOBJMAP	_IO(SESIOC, 2)
#define	SESIOC_GETENCSTAT	_IO(SESIOC, 3)
#define	SESIOC_SETENCSTAT	_IO(SESIOC, 4)
#define	SESIOC_GETOBJSTAT	_IO(SESIOC, 5)
#define	SESIOC_SETOBJSTAT	_IO(SESIOC, 6)
#define	SESIOC_GETTEXT		_IO(SESIOC, 7)
#define	SESIOC_INIT		_IO(SESIOC, 8)

/*
 * Platform Independent Definitions for SES devices.
 */
/*
 * SCSI Based Environmental Services Application Defines
 *
 * Based almost entirely on SCSI-3 SES Revision 8A specification,
 * but slightly abstracted as the underlying device may in fact
 * be a SAF-TE or vendor unique device.
 */
/*
 * SES Driver Operations:
 * (The defines themselves are platform and access method specific)
 *
 * SESIOC_GETNOBJ
 * SESIOC_GETOBJMAP
 * SESIOC_GETENCSTAT
 * SESIOC_SETENCSTAT
 * SESIOC_GETOBJSTAT
 * SESIOC_SETOBJSTAT
 * SESIOC_INIT
 *
 *
 * An application finds out how many objects an SES instance
 * is managing by performing a SESIOC_GETNOBJ operation. It then
 * performs a SESIOC_GETOBJMAP to get the map that contains the
 * object identifiers for all objects (see ses_object below).
 * This information is static.
 *
 * The application may perform SESIOC_GETOBJSTAT operations to retrieve
 * status on an object (see the ses_objstat structure below), SESIOC_SETOBJSTAT
 * operations to set status for an object.
 *
 * Similarly overall enclosure status me be fetched or set via
 * SESIOC_GETENCSTAT or  SESIOC_SETENCSTAT operations (see ses_encstat below).
 *
 * Readers should note that there is nothing that requires either a set
 * or a clear operation to actually latch and do anything in the target.
 *
 * A SESIOC_INIT operation causes the enclosure to be initialized.
 */

typedef struct {
	unsigned int	obj_id;		/* Object Identifier */
	unsigned char	subencid;	/* SubEnclosure ID */
	unsigned char	object_type;	/* Object Type */
} ses_object;

/* Object Types */
#define	SESTYP_UNSPECIFIED	0x00
#define	SESTYP_DEVICE		0x01
#define	SESTYP_POWER		0x02
#define	SESTYP_FAN		0x03
#define	SESTYP_THERM		0x04
#define	SESTYP_DOORLOCK		0x05
#define	SESTYP_ALARM		0x06
#define	SESTYP_ESCC		0x07	/* Enclosure SCC */
#define	SESTYP_SCC		0x08	/* SCC */
#define	SESTYP_NVRAM		0x09
#define	SESTYP_UPS		0x0b
#define	SESTYP_DISPLAY		0x0c
#define	SESTYP_KEYPAD		0x0d
#define	SESTYP_ENCLOSURE	0x0e
#define	SESTYP_SCSIXVR		0x0f
#define	SESTYP_LANGUAGE		0x10
#define	SESTYP_COMPORT		0x11
#define	SESTYP_VOM		0x12
#define	SESTYP_AMMETER		0x13
#define	SESTYP_SCSI_TGT		0x14
#define	SESTYP_SCSI_INI		0x15
#define	SESTYP_SUBENC		0x16
#define	SESTYP_ARRAY		0x17
#define	SESTYP_SASEXPANDER	0x18
#define	SESTYP_SASCONNECTOR	0x19

/*
 * Overall Enclosure Status
 */
typedef unsigned char ses_encstat;
#define	SES_ENCSTAT_UNRECOV		0x1
#define	SES_ENCSTAT_CRITICAL		0x2
#define	SES_ENCSTAT_NONCRITICAL		0x4
#define	SES_ENCSTAT_INFO		0x8

/*
 * Object Status
 */
typedef struct {
	unsigned int	obj_id;
	unsigned char	cstat[4];
} ses_objstat;

/* Summary SES Status Defines, Common Status Codes */
#define	SES_OBJSTAT_UNSUPPORTED		0
#define	SES_OBJSTAT_OK			1
#define	SES_OBJSTAT_CRIT		2
#define	SES_OBJSTAT_NONCRIT		3
#define	SES_OBJSTAT_UNRECOV		4
#define	SES_OBJSTAT_NOTINSTALLED	5
#define	SES_OBJSTAT_UNKNOWN		6
#define	SES_OBJSTAT_NOTAVAIL		7

/*
 * For control pages, cstat[0] is the same for the
 * enclosure and is common across all device types.
 *
 * If SESCTL_CSEL is set, then PRDFAIL, DISABLE and RSTSWAP
 * are checked, otherwise bits that are specific to the device
 * type in the other 3 bytes of cstat or checked.
 */
#define	SESCTL_CSEL		0x80
#define	SESCTL_PRDFAIL		0x40
#define	SESCTL_DISABLE		0x20
#define	SESCTL_RSTSWAP		0x10

/* Control bits, Device Elements, byte 2 */
#define	SESCTL_DRVLCK	0x40	/* "DO NOT REMOVE" */
#define	SESCTL_RQSINS	0x08	/* RQST INSERT */
#define	SESCTL_RQSRMV	0x04	/* RQST REMOVE */
#define	SESCTL_RQSID	0x02	/* RQST IDENT */
/* Control bits, Device Elements, byte 3 */
#define	SESCTL_RQSFLT	0x20	/* RQST FAULT */
#define	SESCTL_DEVOFF	0x10	/* DEVICE OFF */

/* Control bits, Generic, byte 3 */
#define	SESCTL_RQSTFAIL	0x40
#define	SESCTL_RQSTON	0x20

/*
 * Getting text for an object type is a little
 * trickier because it's string data that can
 * go up to 64 KBytes. Build this union and
 * fill the obj_id with the id of the object who's
 * help text you want, and if text is available,
 * obj_text will be filled in, null terminated.
 */

typedef union {
	unsigned int obj_id;
	char obj_text[1];
} ses_hlptxt;


code:
/*
 * Structures and definitions for SCSI commands to the SG passthrough device.
 *
 * $FreeBSD: release/9.0.0/sys/cam/scsi/scsi_sg.h 168598 2007-04-10 20:03:42Z scottl $
 */

#ifndef _SCSI_SG_H
#define _SCSI_SG_H

#define SGIOC	'"'
#define SG_SET_TIMEOUT		_IO(SGIOC, 0x01)
#define SG_GET_TIMEOUT		_IO(SGIOC, 0x02)
#define SG_EMULATED_HOST	_IO(SGIOC, 0x03)
#define SG_SET_TRANSFORM	_IO(SGIOC, 0x04)
#define SG_GET_TRANSFORM	_IO(SGIOC, 0x05)
#define SG_GET_COMMAND_Q	_IO(SGIOC, 0x70)
#define SG_SET_COMMAND_Q	_IO(SGIOC, 0x71)
#define SG_GET_RESERVED_SIZE	_IO(SGIOC, 0x72)
#define SG_SET_RESERVED_SIZE	_IO(SGIOC, 0x75)
#define SG_GET_SCSI_ID		_IO(SGIOC, 0x76)
#define SG_SET_FORCE_LOW_DMA	_IO(SGIOC, 0x79)
#define SG_GET_LOW_DMA		_IO(SGIOC, 0x7a)
#define SG_SET_FORCE_PACK_ID	_IO(SGIOC, 0x7b)
#define SG_GET_PACK_ID		_IO(SGIOC, 0x7c)
#define SG_GET_NUM_WAITING	_IO(SGIOC, 0x7d)
#define SG_SET_DEBUG		_IO(SGIOC, 0x7e)
#define SG_GET_SG_TABLESIZE	_IO(SGIOC, 0x7f)
#define SG_GET_VERSION_NUM	_IO(SGIOC, 0x82)
#define SG_NEXT_CMD_LEN		_IO(SGIOC, 0x83)
#define SG_SCSI_RESET		_IO(SGIOC, 0x84)
#define SG_IO			_IO(SGIOC, 0x85)
#define SG_GET_REQUEST_TABLE	_IO(SGIOC, 0x86)
#define SG_SET_KEEP_ORPHAN	_IO(SGIOC, 0x87)
#define SG_GET_KEEP_ORPHAN	_IO(SGIOC, 0x88)
#define SG_GET_ACCESS_COUNT	_IO(SGIOC, 0x89)

struct sg_io_hdr {
	int		interface_id;
	int		dxfer_direction;
	u_char		cmd_len;
	u_char		mx_sb_len;
	u_short		iovec_count;
	u_int		dxfer_len;
	void		*dxferp;
	u_char		*cmdp;
	u_char		*sbp;
	u_int		timeout;
	u_int		flags;
	int		pack_id;
	void		*usr_ptr;
	u_char		status;
	u_char		masked_status;
	u_char		msg_status;
	u_char		sb_len_wr;
	u_short		host_status;
	u_short		driver_status;
	int		resid;
	u_int		duration;
	u_int		info;
};

#define SG_DXFER_NONE		-1
#define SG_DXFER_TO_DEV		-2
#define SG_DXFER_FROM_DEV	-3
#define SG_DXFER_TO_FROM_DEV	-4
#define SG_DXFER_UNKNOWN	-5

#define SG_MAX_SENSE 16
struct sg_header {
	int		pack_len;
	int		reply_len;
	int		pack_id;
	int		result;
	u_int		twelve_byte:1;
	u_int		target_status:5;
	u_int		host_status:8;
	u_int		driver_status:8;
	u_int		other_flags:10;
	u_char		sense_buffer[SG_MAX_SENSE];
};

struct sg_scsi_id {
	int		host_no;
	int		channel;
	int		scsi_id;
	int		lun;
	int		scsi_type;
	short		h_cmd_per_lun;
	short		d_queue_depth;
	int		unused[2];
};

struct scsi_idlun {
	uint32_t	dev_id;
	uint32_t	host_unique_id;
};

/*
 * Host codes
 */
#define DID_OK		0x00	/* OK */
#define DID_NO_CONNECT	0x01	/* timeout during connect */
#define DID_BUS_BUSY	0x02	/* timeout during command */
#define DID_TIME_OUT	0x03	/* other timeout */
#define DID_BAD_TARGET	0x04	/* bad target */
#define DID_ABORT	0x05	/* abort */
#define DID_PARITY	0x06	/* parity error */
#define DID_ERROR	0x07	/* internal error */
#define DID_RESET	0x08	/* reset by somebody */
#define DID_BAD_INTR	0x09	/* unexpected interrupt */
#define DID_PASSTHROUGH	0x0a	/* passthrough */
#define DID_SOFT_ERROR	0x0b	/* low driver wants retry */
#define DID_IMM_RETRY	0x0c	/* retry without decreasing retrycnt */

/*
 * Driver codes
 */
#define DRIVER_OK	0x00
#define DRIVER_BUSY	0x01
#define DRIVER_SOFT	0x02
#define DRIVER_MEDIA	0x03
#define DRIVER_ERROR	0x04

#define DRIVER_INVALID	0x05
#define DRIVER_TIMEOUT	0x06
#define DRIVER_HARD	0x07
#define DRIVER_SENSE	0x08

#define SUGGEST_RETRY	0x10
#define SUGGEST_ABORT	0x20
#define SUGGEST_REMAP	0x30
#define SUGGEST_DIE	0x40
#define SUGGEST_SENSE	0x80
#define SUGGEST_IS_OK	0xff

#define DRIVER_MASK	0x0f
#define SUGGEST_MASK	0xf0

/* Other definitions */
/* HZ isn't always available, so simulate it */
#define SG_DEFAULT_HZ		1000
#define SG_DEFAULT_TIMEOUT	(60*SG_DEFAULT_HZ)

#endif /* !_SCSI_SG_H */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Ioctl definitions for the SCSI Target Driver
 *
 * Copyright (c) 2002 Nate Lawson.
 * Copyright (c) 1998 Justin T. Gibbs.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification, immediately at the beginning of the file.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/cam/scsi/scsi_targetio.h 139743 2005-01-05 22:34:37Z imp $
 */

#ifndef _CAM_SCSI_SCSI_TARGETIO_H_
#define _CAM_SCSI_SCSI_TARGETIO_H_
#ifndef _KERNEL
#include <sys/types.h>
#endif
#include <sys/ioccom.h>

#include <cam/cam.h>
#include <cam/cam_ccb.h>

/*
 * CCBs (ATIO, CTIO, INOT, REL_SIMQ) are sent to the kernel driver
 * by writing one or more pointers.  The user receives notification
 * of CCB completion through poll/select/kqueue and then calls
 * read(2) which outputs pointers to the completed CCBs.
 */

/*
 * Enable and disable a target mode instance.  For enabling, the path_id,
 * target_id, and lun_id fields must be set.  The grp6/7_len fields
 * specify the length of vendor-specific CDBs the target expects and
 * should normally be set to 0.  On successful completion
 * of enable, the specified target instance will answer selection.
 * Disable causes the target instance to abort any outstanding commands
 * and stop accepting new ones.  The aborted CCBs will be returned to
 * the user via read(2) or discarded if the user closes the device.
 * The user can then re-enable the device for a new path.
 */
struct ioc_enable_lun {
	path_id_t	path_id;
	target_id_t	target_id;
	lun_id_t	lun_id;
	int		grp6_len;
	int		grp7_len;
};
#define TARGIOCENABLE	_IOW('C', 5, struct ioc_enable_lun)
#define TARGIOCDISABLE	 _IO('C', 6)

/*
 * Set/clear debugging for this target mode instance
 */
#define	TARGIOCDEBUG	_IOW('C', 7, int)

TAILQ_HEAD(ccb_queue, ccb_hdr);

#endif /* _CAM_SCSI_SCSI_TARGETIO_H_ */


code:
/*-
 * Copyright (c) 2010 Spectra Logic Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * $Id: //depot/users/kenm/FreeBSD-test/sys/cam/scsi/smp_all.h#4 $
 * $FreeBSD: release/9.0.0/sys/cam/scsi/smp_all.h 216088 2010-11-30 22:39:46Z ken $
 */

/*
 * Serial Management Protocol definitions.
 */

#ifndef	_SCSI_SMP_ALL_H
#define	_SCSI_SMP_ALL_H	1

#define	SMP_FRAME_TYPE_REQUEST	0x40
#define	SMP_FRAME_TYPE_RESPONSE	0x41
#define	SMP_WORD_LEN		4
#define	SMP_CRC_LEN		4

/*
 * SMP Functions (current as of SPL Revision 7)
 */
/* 0x00 to 0x7f: SMP input functions */
/* 0x00 to 0x0f: General SMP input functions */
#define	SMP_FUNC_REPORT_GENERAL		0x00
#define	SMP_FUNC_REPORT_MANUF_INFO	0x01
#define	SMP_FUNC_REPORT_SC_STATUS	0x03
#define	SMP_FUNC_REPORT_ZONE_PERM_TBL	0x04
#define	SMP_FUNC_REPORT_ZONE_MAN_PWD	0x05
#define	SMP_FUNC_REPORT_BROADCAST	0x06

/* 0x10 to 0x1f: Phy-based SMP input functions */
#define	SMP_FUNC_DISCOVER		0x10
#define	SMP_FUNC_REPORT_PHY_ERR_LOG	0x11
#define	SMP_FUNC_REPORT_PHY_SATA	0x12
#define	SMP_FUNC_REPORT_ROUTE_INFO	0x13
#define	SMP_FUNC_REPORT_PHY_EVENT	0x14

/* 0x20 to 0x2f: Descriptor list-based SMP input functions */
#define	SMP_FUNC_DISCOVER_LIST		0x20
#define	SMP_FUNC_REPORT_PHY_EVENT_LIST	0x21
#define	SMP_FUNC_REPORT_EXP_RTL		0x22

/* 0x30 to 0x3f: Reserved for SMP input functions */
/* 0x40 to 0x7f: Vendor specific */

/* 0x80 to 0xff: SMP output functions */
/* 0x80 to 0x8f: General SMP output functions */
#define	SMP_FUNC_CONFIG_GENERAL		0x80
#define	SMP_FUNC_ENABLE_DISABLE_ZONING	0x81
#define	SMP_FUNC_ZONED_BROADCAST	0x85
#define	SMP_FUNC_ZONE_LOCK		0x86
#define	SMP_FUNC_ZONE_ACTIVATE		0x87
#define	SMP_FUNC_ZONE_UNLOCK		0x88
#define	SMP_FUNC_CONFIG_ZM_PWD		0x89
#define	SMP_FUNC_CONFIG_ZONE_PHY_INFO	0x8a
#define	SMP_FUNC_CONFIG_ZONE_PERM_TBL	0x8b

/* 0x90 to 0x9f: Phy-based SMP output functions */
#define	SMP_FUNC_CONFIG_ROUTE_INFO	0x90
#define	SMP_FUNC_PHY_CONTROL		0x91
#define	SMP_FUNC_PHY_TEST_FUNC		0x92
#define	SMP_FUNC_CONFIG_PHY_EVENT	0x93

/* 0xa0 to 0xbf: Reserved for SMP output functions */
/* 0xc0 to 0xff: Vendor specific */

/*
 * Function Results (current as of SPL Revision 7)
 */
#define	SMP_FR_ACCEPTED			0x00
#define	SMP_FR_UNKNOWN_FUNC		0x01
#define	SMP_FR_FUNCTION_FAILED		0x02
#define	SMP_FR_INVALID_REQ_FRAME_LEN	0x03
#define	SMP_FR_INVALID_EXP_CHG_CNT	0x04
#define	SMP_FR_BUSY			0x05
#define	SMP_FR_INCOMPLETE_DESC_LIST	0x06
#define	SMP_FR_PHY_DOES_NOT_EXIST	0x10
#define	SMP_FR_INDEX_DOES_NOT_EXIST	0x11
#define	SMP_FR_PHY_DOES_NOT_SUP_SATA	0x12
#define	SMP_FR_UNKNOWN_PHY_OP		0x13
#define	SMP_FR_UNKNOWN_PHY_TEST_FUNC	0x14
#define	SMP_FR_PHY_TEST_FUNC_INPROG	0x15
#define	SMP_FR_PHY_VACANT		0x16
#define	SMP_FR_UNKNOWN_PHY_EVENT_SRC	0x17
#define	SMP_FR_UNKNOWN_DESC_TYPE	0x18
#define	SMP_FR_UNKNOWN_PHY_FILTER	0x19
#define	SMP_FR_AFFILIATION_VIOLATION	0x1a
#define	SMP_FR_SMP_ZONE_VIOLATION	0x20
#define	SMP_FR_NO_MGMT_ACCESS_RIGHTS	0x21
#define	SMP_FR_UNKNOWN_ED_ZONING_VAL	0x22
#define	SMP_FR_ZONE_LOCK_VIOLATION	0x23
#define	SMP_FR_NOT_ACTIVATED		0x24
#define	SMP_FR_ZG_OUT_OF_RANGE		0x25
#define	SMP_FR_NO_PHYS_PRESENCE		0x26
#define	SMP_FR_SAVING_NOT_SUP		0x27
#define	SMP_FR_SRC_ZONE_DNE		0x28
#define	SMP_FR_DISABLED_PWD_NOT_SUP	0x29

/*
 * REPORT GENERAL request and response, current as of SPL Revision 7.
 */
struct smp_report_general_request
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	response_len;
	uint8_t	request_len;
	uint8_t	crc[4];
};

struct smp_report_general_response
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	function_result;
	uint8_t	response_len;
#define	SMP_RG_RESPONSE_LEN		0x11
	uint8_t	expander_change_count[2];
	uint8_t	expander_route_indexes[2];
	uint8_t	long_response;
#define	SMP_RG_LONG_RESPONSE		0x80
	uint8_t	num_phys;
	uint8_t	config_bits0;
#define	SMP_RG_TABLE_TO_TABLE_SUP	0x80
#define	SMP_RG_ZONE_CONFIGURING		0x40
#define	SMP_RG_SELF_CONFIGURING		0x20
#define	SMP_RG_STP_CONTINUE_AWT		0x10
#define	SMP_RG_OPEN_REJECT_RETRY_SUP	0x08
#define	SMP_RG_CONFIGURES_OTHERS	0x04
#define	SMP_RG_CONFIGURING		0x02
#define	SMP_RG_EXT_CONFIG_ROUTE_TABLE	0x01
	uint8_t	reserved0;
	uint8_t	encl_logical_id[8];
	uint8_t	reserved1[8];
	uint8_t	reserved2[2];
	uint8_t	stp_bus_inact_time_limit[2];
	uint8_t	stp_max_conn_time_limit[2];
	uint8_t	stp_smp_it_nexus_loss_time[2];
	uint8_t	config_bits1;
#define	SMP_RG_NUM_ZONE_GROUPS_MASK	0xc0
#define	SMP_RG_NUM_ZONE_GROUPS_SHIFT	6
#define	SMP_RG_ZONE_LOCKED		0x10
#define	SMP_RG_PP_SUPPORTED		0x08
#define	SMP_RG_PP_ASSERTED		0x04
#define	SMP_RG_ZONING_SUPPORTED		0x02
#define	SMP_RG_ZONING_ENABLED		0x01
	uint8_t	config_bits2;
#define	SMP_RG_SAVING			0x10
#define	SMP_RG_SAVING_ZM_PWD_SUP	0x08
#define	SMP_RG_SAVING_PHY_INFO_SUP	0x04
#define	SMP_RG_SAVING_ZPERM_TAB_SUP	0x02
#define	SMP_RG_SAVING_ZENABLED_SUP	0x01
	uint8_t	max_num_routed_addrs[2];
	uint8_t	active_zm_address[8];
	uint8_t	zone_lock_inact_time_limit[2];
	uint8_t	reserved3[2];
	uint8_t	reserved4;
	uint8_t	first_encl_conn_el_index;
	uint8_t	num_encl_conn_el_indexes;
	uint8_t	reserved5;
	uint8_t	reduced_functionality;
#define	SMP_RG_REDUCED_FUNCTIONALITY	0x80
	uint8_t	time_to_reduced_func;
	uint8_t	initial_time_to_reduced_func;
	uint8_t	max_reduced_func_time;
	uint8_t	last_sc_stat_desc_index[2];
	uint8_t	max_sc_stat_descs[2];
	uint8_t	last_phy_evl_desc_index[2];
	uint8_t	max_stored_pel_descs[2];
	uint8_t	stp_reject_to_open_limit[2];
	uint8_t	reserved6[2];
	uint8_t	crc[4];
};

/*
 * REPORT MANUFACTURER INFORMATION request and response, current as of SPL
 * Revision 7.
 */
struct smp_report_manuf_info_request
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	response_len;
	uint8_t	request_len;
#define	SMP_RMI_REQUEST_LEN		0x00
	uint8_t	crc[4];
};

struct smp_report_manuf_info_response
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	function_result;
	uint8_t	response_len;
#define	SMP_RMI_RESPONSE_LEN		0x0e
	uint8_t	expander_change_count[2];
	uint8_t	reserved0[2];
	uint8_t	sas_11_format;
#define	SMP_RMI_SAS11_FORMAT		0x01
	uint8_t	reserved1[3];
	uint8_t	vendor[8];
	uint8_t	product[16];
	uint8_t	revision[4];
	uint8_t	comp_vendor[8];
	uint8_t	comp_id[2];
	uint8_t	comp_revision;
	uint8_t	reserved2;
	uint8_t	vendor_specific[8];
	uint8_t	crc[4];
};

/*
 * DISCOVER request and response, current as of SPL Revision 7.
 */
struct smp_discover_request
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t response_len;
	uint8_t request_len;
#define	SMP_DIS_REQUEST_LEN		0x02
	uint8_t reserved0[4];
	uint8_t	ignore_zone_group;
#define	SMP_DIS_IGNORE_ZONE_GROUP	0x01
	uint8_t	phy;
	uint8_t	reserved1[2];
	uint8_t	crc[4];
};

struct smp_discover_response
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	function_result;
	uint8_t	response_len;
#define	SMP_DIS_RESPONSE_LEN		0x20
	uint8_t	expander_change_count[2];
	uint8_t	reserved0[3];
	uint8_t	phy;
	uint8_t	reserved1[2];
	uint8_t	attached_device;
#define	SMP_DIS_AD_TYPE_MASK		0x70
#define	SMP_DIS_AD_TYPE_NONE		0x00
#define	SMP_DIS_AD_TYPE_SAS_SATA	0x10
#define	SMP_DIS_AD_TYPE_EXP		0x20
#define	SMP_DIS_AD_TYPE_EXP_OLD		0x30
#define	SMP_DIS_ATTACH_REASON_MASK	0x0f
	uint8_t	neg_logical_link_rate;
#define	SMP_DIS_LR_MASK			0x0f
#define	SMP_DIS_LR_DISABLED		0x01
#define	SMP_DIS_LR_PHY_RES_PROB		0x02
#define	SMP_DIS_LR_SPINUP_HOLD		0x03
#define	SMP_DIS_LR_PORT_SEL		0x04
#define	SMP_DIS_LR_RESET_IN_PROG	0x05
#define	SMP_DIS_LR_UNSUP_PHY_ATTACHED	0x06
#define	SMP_DIS_LR_G1_15GBPS		0x08
#define	SMP_DIS_LR_G2_30GBPS		0x09
#define	SMP_DIS_LR_G3_60GBPS		0x0a
	uint8_t	config_bits0;
#define	SMP_DIS_ATTACHED_SSP_INIT	0x08
#define	SMP_DIS_ATTACHED_STP_INIT	0x04
#define	SMP_DIS_ATTACHED_SMP_INIT	0x02
#define	SMP_DIS_ATTACHED_SATA_HOST	0x01
	uint8_t	config_bits1;
#define	SMP_DIS_ATTACHED_SATA_PORTSEL	0x80
#define	SMP_DIS_STP_BUFFER_TOO_SMALL	0x10
#define	SMP_DIS_ATTACHED_SSP_TARG	0x08
#define	SMP_DIS_ATTACHED_STP_TARG	0x04
#define	SMP_DIS_ATTACHED_SMP_TARG	0x02
#define	SMP_DIS_ATTACHED_SATA_DEV	0x01
	uint8_t	sas_address[8];
	uint8_t	attached_sas_address[8];
	uint8_t	attached_phy_id;
	uint8_t	config_bits2;
#define	SMP_DIS_ATT_SLUMB_CAP		0x10
#define	SMP_DIS_ATT_PAR_CAP		0x08
#define	SMP_DIS_ATT_IN_ZPSDS_PER	0x04
#define	SMP_DIS_ATT_REQ_IN_ZPSDS	0x02
#define	SMP_DIS_ATT_BREAK_RPL_CAP	0x01
	uint8_t	reserved2[6];
	uint8_t	link_rate0;
#define	SMP_DIS_PROG_MIN_LR_MASK	0xf0
#define	SMP_DIS_PROG_MIN_LR_SHIFT	4
#define	SMP_DIS_HARD_MIN_LR_MASK	0x0f
	uint8_t	link_rate1;
#define	SMP_DIS_PROG_MAX_LR_MAX		0xf0
#define	SMP_DIS_PROG_MAX_LR_SHIFT	4
#define	SMP_DIS_HARD_MAX_LR_MASK	0x0f
	uint8_t	phy_change_count;
	uint8_t	pp_timeout;
#define	SMP_DIS_VIRTUAL_PHY		0x80
#define	SMP_DIS_PP_TIMEOUT_MASK		0x0f
	uint8_t	routing_attr;
	uint8_t	conn_type;
	uint8_t	conn_el_index;
	uint8_t	conn_phys_link;
	uint8_t	config_bits3;
#define	SMP_DIS_PHY_POW_COND_MASK	0xc0
#define	SMP_DIS_PHY_POW_COND_SHIFT	6
#define	SMP_DIS_SAS_SLUMB_CAP		0x08
#define	SMP_DIS_SAS_PART_CAP		0x04
#define	SMP_DIS_SATA_SLUMB_CAP		0x02
#define	SMP_DIS_SATA_PART_CAP		0x01
	uint8_t	config_bits4;
#define	SMP_DIS_SAS_SLUMB_ENB		0x08
#define	SMP_DIS_SAS_PART_ENB		0x04
#define	SMP_DIS_SATA_SLUMB_ENB		0x02
#define	SMP_DIS_SATA_PART_ENB		0x01
	uint8_t	vendor_spec[2];
	uint8_t	attached_dev_name[8];
	uint8_t	config_bits5;
#define	SMP_DIS_REQ_IN_ZPSDS_CHG	0x40
#define	SMP_DIS_IN_ZPSDS_PER		0x20
#define	SMP_DIS_REQ_IN_ZPSDS		0x10
#define	SMP_DIS_ZG_PER			0x04
#define	SMP_DIS_IN_ZPSDS		0x02
#define	SMP_DIS_ZONING_ENB		0x01
	uint8_t	reserved3[2];
	uint8_t	zone_group;
	uint8_t	self_config_status;
	uint8_t	self_config_levels_comp;
	uint8_t	reserved4[2];
	uint8_t	self_config_sas_addr[8];
	uint8_t	prog_phy_cap[4];
	uint8_t	current_phy_cap[4];
	uint8_t	attached_phy_cap[4];
	uint8_t	reserved5[6];
	uint8_t	neg_phys_link_rate;
#define	SMP_DIS_REASON_MASK		0xf0
#define	SMP_DIS_REASON_SHIFT		4
#define	SMP_DIS_PHYS_LR_MASK		0x0f
	uint8_t	config_bits6;
#define	SMP_DIS_OPTICAL_MODE_ENB	0x04
#define	SMP_DIS_NEG_SSC			0x02
#define	SMP_DIS_HW_MUX_SUP		0x01
	uint8_t	config_bits7;
#define	SMP_DIS_DEF_IN_ZPSDS_PER	0x20
#define	SMP_DIS_DEF_REQ_IN_ZPSDS	0x10
#define	SMP_DIS_DEF_ZG_PER		0x04
#define	SMP_DIS_DEF_ZONING_ENB		0x01
	uint8_t	reserved6;
	uint8_t	reserved7;
	uint8_t	default_zone_group;
	uint8_t	config_bits8;
#define	SMP_DIS_SAVED_IN_ZPSDS_PER	0x20
#define	SMP_DIS_SAVED_REQ_IN_SPSDS	0x10
#define	SMP_DIS_SAVED_ZG_PER		0x04
#define	SMP_DIS_SAVED_ZONING_ENB	0x01
	uint8_t	reserved8;
	uint8_t	reserved9;
	uint8_t	saved_zone_group;
	uint8_t	config_bits9;
#define	SMP_DIS_SHADOW_IN_ZPSDS_PER	0x20
#define	SMP_DIS_SHADOW_IN_REQ_IN_ZPSDS	0x10
#define	SMP_DIS_SHADOW_ZG_PER		0x04
	uint8_t reserved10;
	uint8_t reserved11;
	uint8_t	shadow_zone_group;
	uint8_t	device_slot_num;
	uint8_t	device_slot_group_num;
	uint8_t	device_slot_group_out_conn[6];
	uint8_t	stp_buffer_size[2];
	uint8_t	reserved12;
	uint8_t	reserved13;
	uint8_t	crc[4];
};

/*
 * PHY CONTROL request and response.  Current as of SPL Revision 7.
 */
struct smp_phy_control_request
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t response_len;
#define	SMP_PC_RESPONSE_LEN		0x00
	uint8_t request_len;
#define	SMP_PC_REQUEST_LEN		0x09
	uint8_t expected_exp_chg_cnt[2];
	uint8_t reserved0[3];
	uint8_t phy;
	uint8_t phy_operation;
#define	SMP_PC_PHY_OP_NOP		0x00
#define	SMP_PC_PHY_OP_LINK_RESET	0x01
#define	SMP_PC_PHY_OP_HARD_RESET	0x02
#define	SMP_PC_PHY_OP_DISABLE		0x03
#define	SMP_PC_PHY_OP_CLEAR_ERR_LOG	0x05
#define	SMP_PC_PHY_OP_CLEAR_AFFILIATON	0x06
#define	SMP_PC_PHY_OP_TRANS_SATA_PSS	0x07
#define	SMP_PC_PHY_OP_CLEAR_STP_ITN_LS	0x08
#define	SMP_PC_PHY_OP_SET_ATT_DEV_NAME	0x09
	uint8_t update_pp_timeout;
#define	SMP_PC_UPDATE_PP_TIMEOUT	0x01
	uint8_t reserved1[12];
	uint8_t attached_device_name[8];
	uint8_t prog_min_phys_link_rate;
#define	SMP_PC_PROG_MIN_PL_RATE_MASK	0xf0
#define	SMP_PC_PROG_MIN_PL_RATE_SHIFT	4
	uint8_t prog_max_phys_link_rate;
#define	SMP_PC_PROG_MAX_PL_RATE_MASK	0xf0
#define	SMP_PC_PROG_MAX_PL_RATE_SHIFT	4
	uint8_t	config_bits0;
#define	SMP_PC_SP_NC			0x00
#define	SMP_PC_SP_DISABLE		0x02
#define	SMP_PC_SP_ENABLE		0x01
#define	SMP_PC_SAS_SLUMBER_NC		0x00
#define	SMP_PC_SAS_SLUMBER_DISABLE	0x80
#define	SMP_PC_SAS_SLUMBER_ENABLE	0x40
#define	SMP_PC_SAS_SLUMBER_MASK		0xc0
#define	SMP_PC_SAS_SLUMBER_SHIFT	6
#define	SMP_PC_SAS_PARTIAL_NC		0x00
#define	SMP_PC_SAS_PARTIAL_DISABLE	0x20
#define	SMP_PC_SAS_PARTIAL_ENABLE	0x10
#define	SMP_PC_SAS_PARTIAL_MASK		0x30
#define	SMP_PC_SAS_PARTIAL_SHIFT	4
#define	SMP_PC_SATA_SLUMBER_NC		0x00
#define	SMP_PC_SATA_SLUMBER_DISABLE	0x08
#define	SMP_PC_SATA_SLUMBER_ENABLE	0x04
#define	SMP_PC_SATA_SLUMBER_MASK	0x0c
#define	SMP_PC_SATA_SLUMBER_SHIFT	2
#define	SMP_PC_SATA_PARTIAL_NC		0x00
#define	SMP_PC_SATA_PARTIAL_DISABLE	0x02
#define	SMP_PC_SATA_PARTIAL_ENABLE	0x01
#define	SMP_PC_SATA_PARTIAL_MASK	0x03
#define	SMP_PC_SATA_PARTIAL_SHIFT	0
	uint8_t	reserved2;
	uint8_t	pp_timeout_value;
#define	SMP_PC_PP_TIMEOUT_MASK		0x0f
	uint8_t reserved3[3];
	uint8_t	crc[4];
};

struct smp_phy_control_response
{
	uint8_t	frame_type;
	uint8_t	function;
	uint8_t	function_result;
	uint8_t	response_len;
#define	SMP_PC_RESPONSE_LEN		0x00
	uint8_t crc[4];
};

__BEGIN_DECLS

const char *smp_error_desc(int function_result);
const char *smp_command_desc(uint8_t cmd_num);
void smp_command_decode(uint8_t *smp_request, int request_len, struct sbuf *sb,
			char *line_prefix, int first_line_len, int line_len);
void smp_command_sbuf(struct ccb_smpio *smpio, struct sbuf *sb,
		      char *line_prefix, int first_line_len, int line_len);

#ifdef _KERNEL
void smp_error_sbuf(struct ccb_smpio *smpio, struct sbuf *sb);
#else /* !_KERNEL*/
void smp_error_sbuf(struct cam_device *device, struct ccb_smpio *smpio,
		    struct sbuf *sb);
#endif /* _KERNEL/!_KERNEL */

void smp_report_general_sbuf(struct smp_report_general_response *response,
			     int response_len, struct sbuf *sb);

void smp_report_manuf_info_sbuf(struct smp_report_manuf_info_response *response,
				int response_len, struct sbuf *sb);

void smp_report_general(struct ccb_smpio *smpio, uint32_t retries,
			void (*cbfcnp)(struct cam_periph *, union ccb *),
			struct smp_report_general_request *request,
			int request_len, uint8_t *response, int response_len,
			int long_response, uint32_t timeout);

void smp_discover(struct ccb_smpio *smpio, uint32_t retries,
		  void (*cbfcnp)(struct cam_periph *, union ccb *),
		  struct smp_discover_request *request, int request_len,
		  uint8_t *response, int response_len, int long_response,
		  int ignore_zone_group, int phy, uint32_t timeout);

void smp_report_manuf_info(struct ccb_smpio *smpio, uint32_t retries,
			   void (*cbfcnp)(struct cam_periph *, union ccb *),
			   struct smp_report_manuf_info_request *request,
			   int request_len, uint8_t *response, int response_len,
			   int long_response, uint32_t timeout);

void smp_phy_control(struct ccb_smpio *smpio, uint32_t retries,
		     void (*cbfcnp)(struct cam_periph *, union ccb *),
		     struct smp_phy_control_request *request, int request_len,
		     uint8_t *response, int response_len, int long_response,
		     uint32_t expected_exp_change_count, int phy, int phy_op,
		     int update_pp_timeout_val, uint64_t attached_device_name,
		     int prog_min_prl, int prog_max_prl, int slumber_partial,
		     int pp_timeout_value, uint32_t timeout);
__END_DECLS

#endif /*_SCSI_SMP_ALL_H*/


code:
/*
 * Copyright (c) 1997, 1998 Kenneth D. Merry.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/lib/libcam/camlib.h 95331 2002-04-23 23:58:20Z obrien $
 */
/*
 * Buffer encoding/decoding routines taken from the original FreeBSD SCSI
 * library and slightly modified.  The original header file had the following
 * copyright:
 */
/* Copyright (c) 1994 HD Associates (hd@world.std.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 * This product includes software developed by HD Associates
 * 4. Neither the name of the HD Associaates nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _CAMLIB_H
#define _CAMLIB_H

#include <sys/cdefs.h>
#include <sys/param.h>

#include <cam/cam.h>
#include <cam/cam_ccb.h>

#define CAM_ERRBUF_SIZE 2048	/* sizeof the CAM libarary error string  */

/*
 * Right now we hard code the transport layer device, but this will change
 * if we ever get more than one transport layer.
 */
#define XPT_DEVICE	"/dev/xpt0"

extern char cam_errbuf[];

struct cam_device {
	char 		device_path[MAXPATHLEN];/*
						   * Pathname of the device
						   * given by the user. This
						   * may be null if the
						   * user states the device
						   * name and unit number
						   * separately.
						   */
	char		given_dev_name[DEV_IDLEN+1];/*
						     * Device name given by
						     * the user.
						     */
	u_int32_t	given_unit_number;	    /*
						     * Unit number given by
						     * the user.
						     */
	char		device_name[DEV_IDLEN+1];/*
						  * Name of the device,
						  * e.g. 'pass'
						  */
	u_int32_t	dev_unit_num;	/* Unit number of the passthrough
					 * device associated with this
					 * particular device.
					 */

	char		sim_name[SIM_IDLEN+1]; /* Controller name, e.g. 'ahc' */
	u_int32_t	sim_unit_number; /* Controller unit number */
	u_int32_t	bus_id;		 /* Controller bus number */
	lun_id_t	target_lun;	 /* Logical Unit Number */
	target_id_t	target_id;	 /* Target ID */
	path_id_t	path_id;	 /* System SCSI bus number */
	u_int16_t	pd_type;	 /* type of peripheral device */
	struct scsi_inquiry_data inq_data;  /* SCSI Inquiry data */
	u_int8_t	serial_num[252]; /* device serial number */
	u_int8_t	serial_num_len;  /* length of the serial number */
	u_int8_t	sync_period;	 /* Negotiated sync period */
	u_int8_t	sync_offset;	 /* Negotiated sync offset */
	u_int8_t	bus_width;	 /* Negotiated bus width */
	int		fd;		 /* file descriptor for device */
};

__BEGIN_DECLS
/* Basic utility commands */
struct cam_device *	cam_open_device(const char *path, int flags);
void			cam_close_device(struct cam_device *dev);
void			cam_close_spec_device(struct cam_device *dev);
struct cam_device *	cam_open_spec_device(const char *dev_name,
					     int unit, int flags,
					     struct cam_device *device);
struct cam_device *	cam_open_btl(path_id_t path_id, target_id_t target_id,
				     lun_id_t target_lun, int flags,
				     struct cam_device *device);
struct cam_device *	cam_open_pass(const char *path, int flags,
				      struct cam_device *device);
union ccb *		cam_getccb(struct cam_device *dev);
void			cam_freeccb(union ccb *ccb);
int			cam_send_ccb(struct cam_device *device, union ccb *ccb);
char *			cam_path_string(struct cam_device *dev, char *str,
					int len);
struct cam_device *	cam_device_dup(struct cam_device *device);
void			cam_device_copy(struct cam_device *src,
					struct cam_device *dst);
int			cam_get_device(const char *path, char *dev_name,
				       int devnamelen, int *unit);

/*
 * Buffer encoding/decoding routines, from the old SCSI library.
 */
int csio_decode(struct ccb_scsiio *csio, const char *fmt, ...)
		__printflike(2, 3);
int csio_decode_visit(struct ccb_scsiio *csio, const char *fmt,
		      void (*arg_put)(void *, int, void *, int, char *),
		      void *puthook);
int buff_decode(u_int8_t *buff, size_t len, const char *fmt, ...)
		__printflike(3, 4);
int buff_decode_visit(u_int8_t *buff, size_t len, const char *fmt,
		      void (*arg_put)(void *, int, void *, int, char *),
		      void *puthook);
int csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr,
	       u_int32_t dxfer_len, u_int32_t flags, int retry_count,
	       int timeout, const char *cmd_spec, ...);
int csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr,
		     u_int32_t dxfer_len, u_int32_t flags, int retry_count,
		     int timeout, const char *cmd_spec,
		     int (*arg_get)(void *hook, char *field_name),
		     void *gethook);
int csio_encode(struct ccb_scsiio *csio, const char *fmt, ...)
		__printflike(2, 3);
int buff_encode_visit(u_int8_t *buff, size_t len, const char *fmt,
		      int (*arg_get)(void *hook, char *field_name),
		      void *gethook);
int csio_encode_visit(struct ccb_scsiio *csio, const char *fmt,
		      int (*arg_get)(void *hook, char *field_name),
		      void *gethook);
__END_DECLS

#endif /* _CAMLIB_H */