1
0
Files
irix-657m-src/irix/kern/sys/scsi.h
2022-09-29 17:59:04 +03:00

961 lines
36 KiB
C

#ifndef _NSCSI_
#define _NSCSI_
#ident "$Revision: 3.131 $"
/*
* Calls from high level driver to low level driver
*
* scsi_command() issues a SCSI command to the low level SCSI driver.
*
* If a contingent allegiance condition is entered (check condition
* command status), a request sense will be automatically performed.
* If the sr_sense field of the request is not null, the sense data
* will be copied to the sr_sense address, but not more than
* sr_senselen bytes.
*
* In addition, whenever there is a contingent allegiance or SCSI bus
* reset, all commands queued in the driver and on the device (except
* for the command causing or noticing the error) will be returned
* with the sr_status field set to SC_ATTN. New commands will continue
* to be returned with this status until the flag bit SRF_AEN_ACK is
* set in sr_flags.
*
* Before any command queueing is done, the device driver should do
* a mode sense on mode page 0xA (control mode page) to discover the
* QErr bit setting. Error handling will not work correctly in a
* queued environment unless the QErr bit is set.
*
* scsi_alloc() initializes a connection between a device level driver and
* a host adaptor driver for a given controller, target, and lun. It
* will cause the low level driver to initialize structures needed for
* communication if it has not already done so.
*
* The opt argument gives additional information about how the driver
* would like to talk to the device. Currently, three options are
* allowed.
* SCSIALLOC_EXCLUSIVE causes the device to be allocated
* exclusively for the use of the calling driver. If a device is
* allocated for exclusive use, no other driver may access it. Also,
* if a device is already in use by another driver, exclusive or not,
* an exclusive alloc will fail.
* SCSIALLOC_NOSYNC will prevent future synchronous negotiations from
* being attempted on this device (where possible; not all adapters
* support this capability); only applies when no other driver already
* has the device open. Also see the SRF_NEG_SYNC flag below.
* SCSIALLOC_QDEPTH is a mask for an eight bit value
* specifying how many commands a device driver would like to
* queue (that is, the low bits of opt are used to pass the max
* depth the upper layer driver will use). It is to be
* considered advice only; the depth used may be less, but will
* never be greater.
*
* The cb argument is used as a callback if a request sense was done
* as a result of a check condition from a command. If the cb
* argument is NULL, no callbacks will be done. Note that having
* a callback set may result in a driver seeing the error twice.
* The purpose of the callback is to give make sure that a given
* driver gets all sense data from a device, even if it is returned
* with a command issued by a different driver. Only one driver is
* allowed to have a callback. scsi_alloc() will fail if a callback
* is requested, and another driver currently has a callback
* registered.
*
* A return value of SCSIALLOCOK indicates success; any other value
* indicates an error. 0 indicates a generic error such as bad
* values for the adapter or target; values > 1 typically are an
* errno value from errno.h, indicating the cause of the error
* (such as EBUSY if SCSIALLOC_EXCLUSIVE is used, and the device
* is already allocated), or EINVAL, if a non-null callback is
* passed, but a callback is already registered for the device.
* Note that this is a change introduced in IRIX 5.1.1; previously
* any non-0 return value was success. The change was made to
* allow the upper level drivers to better handle errors.
*
* scsi_free() terminates a connection between a device level driver and
* the host adaptor driver. The host adaptor driver will free any
* structures that it does not need.
*
* The callback argument should be the same as that given to
* scsi_alloc(). If it does not match, the callback will not be
* freed up.
*
* scsi_info() issues an inquiry to the given controller, target, and lun,
* returning a pointer to the scsi_target_info structure. It should
* be used to see if the device is appropriate to the driver making
* the call.
*
* The si_maxq field in the scsi_target_info structure (returned by
* scsi_info()) will give queueing information.
*
* scsi_abort() aborts the request passed as an argument. If it is
* currently active, an abort message will be sent to the device.
* A non-zero return indicates that the abort was successful. Not
* all host adaptors support this function.
*
*
* The way this is implemented using the hwgraph is as follows.
* The controller vertex in the hwgraph has the scsi function pointers
* stored as a part of information associated with the vertex.
* Eg:- /hw/scsi_ctlr/#1/target/#2/lun/#3/...
*
* Let the controller vertex handle be cvhdl pointed to by #1 &
* let the pointer to info hanging off the controller vertex be cinfo.
* Now the scsi functions can be accessed as follows.
* cinfo = scsi_ctlr_info_get(cvhdl);
*
* scsi_alloc(..) SCI_ALLOC(cinfo)(..)
* scsi_command(..) SCI_COMMAND(cinfo)(..)
* scsi_free(..) SCI_FREE(cinfo)(..)
* scsi_dump(..) SCI_DUMP(cinfo)(..)
* scsi_info(..) SCI_INQ(cinfo)(..)
* scsi_ioctl(..) SCI_IOCTL(cinfo)(..)
* scsi_abort(..) SCI_ABORT(cinfo)(..)
*
* There are backward pointers which finally get to the controller
* info from the vertices below the controller.
* For example scsi_command function can be called from the lun vertex
* handle pointed to by #3 above as follows.
* lun_info = scsi_lun_info_get(lun_vhdl);
* SLI_COMMAND(lun_info)(...)
*
* Sample code for initializing the controller info with these
* function pointers follows:
*
* Allocate the controller info structure. This hangs off the
* controller vertex.
* scsi_ctlr_info_t *ctlr_info = scsi_ctlr_info_init();
* .
* .
* .
* Initialize the function pointers in addition to other initializations
*
* SCI_ALLOC(ctlr_info) = your_alloc;
* SCI_COMMAND(ctlr_info) = your_command;
* SCI_FREE(ctlr_info) = your_free;
* SCI_DUMP(ctlr_info) = your_dump;
* SCI_INQ(ctlr_info) = your_info;
* SCI_IOCTL(ctlr_info) = your_ioctl;
* .
* .
* .
* Hang the information off the controller vertex
*
* scsi_ctlr_info_put(ctlr_vhdl,ctlr_info);
*/
extern char *scsi_adaperrs_tab[];
#define SCSIALLOC_NOSYNC 0x200
#define SCSIALLOC_EXCLUSIVE 0x100
#define SCSIALLOC_QDEPTH 0x0FF
#define SCSIALLOCOK 1 /* succesful return value from scsi_alloc function */
#define SCSIDRIVER_NULL 0
/*
* Defines for number of SCSI buses
*/
#if defined(EVEREST)
#define SCSI_MAXCTLR 120
#define SCSI_MAXTARG 127
#else
#if defined(IP22) || defined(IP26) || defined(IP28)
#define SCSI_MAXCTLR 6
/* why 6? */
/* INDY (0 = base board, 2,3 = GIO/SCSI adapter) */
/* INDIGO2 (0,1 base board) */
/* CHAL. S (0 = base board, 2,3 GIO/SCSI adapter#1, 4,5 GIO/SCSI adapter#2) */
#define SCSI_MAXTARG 16 /* wide on Indigo2, narrow for Indy */
#else
#if defined(IP20)
#define SCSI_MAXTARG 8
#else
#if defined(IP30) || defined(SN)
#define SCSI_MAXTARG 127
#else
#if defined(IP32)
#define SCSI_MAXTARG 16
#endif /* IP32 */
#endif /* IP30 || SN0 */
#endif /* IP20 */
#endif /* IP22 || IP26 || IP28 */
#endif /* EVEREST */
#define SCSI_MAXLUN 64
#if defined(EVEREST)
/* used to convert internal ctlr number to external */
#define SCSI_CTLR_SLOTSHIFT 3
#define SCSI_EXT_CTLR(si) ((((si)>>SCSI_CTLR_SLOTSHIFT) * 10) + ((si) & 7))
#define SCSI_INT_CTLR(se) (((se) % 10) + (((se) / 10) << SCSI_CTLR_SLOTSHIFT))
#else
#define SCSI_EXT_CTLR(si) (si)
#define SCSI_INT_CTLR(se) (se)
#endif
/*
* SCSI sense defines and message external declarations
*/
#define SC_NUMSENSE 0x10 /* # of messages in scsi_key_msgtab */
#define SC_NUMADDSENSE 0x71 /* # of messages in scsi_addit_msgtab */
extern char *scsi_key_msgtab[], *scsi_addit_msgtab[];
/* base sense error codes */
#define SC_NOSENSE 0x0
#define SC_ERR_RECOVERED 0x1
#define SC_NOT_READY 0x2
#define SC_MEDIA_ERR 0x3
#define SC_HARDW_ERR 0x4
#define SC_ILLEGALREQ 0x5
#define SC_UNIT_ATTN 0x6
#define SC_DATA_PROT 0x7
#define SC_BLANKCHK 0x8
#define SC_VENDUNIQ 0x9
#define SC_COPY_ABORT 0xA
#define SC_CMD_ABORT 0xB
#define SC_EQUAL 0xC
#define SC_VOL_OVERFL 0xD
#define SC_MISCMP 0xE
/* some common extended sense error codes */
#define SC_NO_ADD 0x0 /* no extended sense code */
#define SC_NOINDEX 0x1
#define SC_NOSEEKCOMP 0x2
#define SC_WRITEFAULT 0x3
#define SC_NOTREADY 0x4
#define SC_NOTSEL 0x5
#define SC_ECC 0x10
#define SC_READERR 0x11
#define SC_NOADDRID 0x12
#define SC_NOADDRDATA 0x13
#define SC_DEFECT_ERR 0x19
#define SC_WRITEPROT 0x27
#define SC_RESET 0x29
#define SC_MEDIA_ABSENT 0x3a
/* Possible status bytes returned after a scsi command */
#define ST_GOOD 0
#define ST_CHECK 2
#define ST_COND_MET 4
#define ST_BUSY 8
#define ST_INT_GOOD 16
#define ST_INT_COND_MET 20
#define ST_RES_CONF 24
/* Size of different scsi command classes */
#define SC_CLASS0_SZ 6
#define SC_CLASS1_SZ 10
#define SC_CLASS2_SZ 12
/*
* SCSI host adapter independent target information structure
* This structure is used to pass information between the host adapter drivers
* and the device drivers (disk, tape, etc.).
*/
struct scsi_target_info
{
u_char *si_inq; /* inquiry data */
u_char *si_sense; /* sense data from last request sense */
u_char si_maxq; /* maximum queue depth for driver */
u_char si_qdepth; /* max queue depth so far */
u_char si_qlimit:1; /* boolean "max queue depth reached"? */
uint si_ha_status; /* SRH_* status bits, if supported */
};
typedef struct scsi_target_info scsi_target_info_t;
#define SCSI_INQUIRY_LEN 64
#define SCSI_SENSE_LEN 64
#define SCSI_MODESEL_PARAMLIST_LEN 12
/*
* Definitions for scsi_target_info.si_ha_status -- host adapter status bits
* Not all host adapter drivers will set or use these bits.
*/
#define SRH_CANTSYNC 0x01 /* sync xfer negotiations attempted, but
* device doesn't support sync; BADSYNC will be set if the negotation
* itself also failed */
#define SRH_SYNCXFR 0x02 /* sync xfer mode in effect; async if not set;
* async mode is the default for all devscsi devices. */
#define SRH_TRIEDSYNC 0x04 /* did sync negotations at some point. If
* SRH_CANTSYNC is not also set, the device supports sync mode. */
#define SRH_BADSYNC 0x08 /* device doesn't handle sync negotations
* correctly; SRH_CANTSYNC will normally be set whenever this bit
* is set */
#define SRH_NOADAPSYNC 0x10 /* scsi adapter doesn't handle sync
* negotations or system has been configured to not allow sync xfers
* on this target */
#define SRH_WIDE 0x20 /* scsi adapter supports wide SCSI */
#define SRH_DISC 0x40 /* scsi adapter supports disconnect and is configured
* for it */
#define SRH_TAGQ 0x80 /* scsi adapter supports tagged queuing and is
* configured for it */
#define SRH_MAPUSER 0x100 /* host adapter driver can map user addrs */
#define SRH_QERR0 0x200 /* host adapter supports QERR==0 */
#define SRH_QERR1 0x400 /* host adapter supports QERR==1 */
#define SRH_ALENLIST 0x800 /* host adapter understands alenlists */
/*
* SCSI request structure
* This structure is used by a SCSI device driver to make a request to a
* SCSI host adapter.
*
* Return values from the host adapter driver are in the fields sr_status,
* sr_scsi_status, sr_sensegotten, and sr_resid. The sr_status field
* indicates the success or failure in circumstances that are outside the
* traditional SCSI protocol (like HW errors, cable errors, DMA errors, etc.).
* The sr_scsi_status field contains the SCSI status byte. If the command
* generated a check condition, a request sense will be attempted. If it
* fails, the sr_status and sr_scsi_status fields will apply to the request
* sense command, and the sr_sensegotten field will be -1. If it succeeds,
* the sr_status and sr_scsi_status fields will be 0, and the sr_sensegotten
* will contain the number of bytes of sense data received. The sr_resid
* field will be the difference between the number of bytes of data expected
* (in the sr_buflen field) and the number actually transferred in executing
* the command.
*/
struct scsi_request
{
/*
* values filled in by device driver
*/
u_char sr_ctlr;
u_char sr_target;
u_char sr_lun;
u_char sr_tag; /* first byte of tag message */
vertex_hdl_t sr_lun_vhdl;
u_char *sr_command; /* scsi command */
ushort sr_cmdlen; /* length of scsi command */
ushort sr_flags; /* direction of data transfer */
uint sr_timeout; /* in HZ */
u_char *sr_buffer; /* location of data */
u_char *sr_sense; /* where to put sense data in case of CC */
uint sr_buflen; /* amount of data to transfer */
uint sr_senselen; /* size of buffer allocated for sense data */
void (*sr_notify)(struct scsi_request *); /* callback pointer */
void *sr_bp; /* usually a buf_t pointer */
/*
* fields used by device driver to reference structures at
* notify time or to keep track of retry counts, etc.
*/
vertex_hdl_t sr_dev_vhdl;
void *sr_dev;
/*
* spare fields used by host adapter driver
*/
void *sr_ha; /* usually used for linked list of req's */
void *sr_spare; /* used as spare pointer, int, etc. */
/*
* results filled in by host adapter driver
*/
uint sr_status; /* Status of command */
u_char sr_scsi_status; /* SCSI status byte */
u_char sr_ha_flags; /* flags used by host adaptor driver */
short sr_sensegotten; /* number of sense bytes received; -1 == err */
uint sr_resid; /* amount of sr_buflen not transferred */
};
typedef struct scsi_request scsi_request_t;
/*
* constants for scsirequest.sr_flags
*/
#define SRF_DIR_IN 0x0001 /* data xfer into memory (DMA write) if set */
#define SRF_FLUSH 0x0002 /* data writeback/inval required */
#define SRF_MAPUSER 0x0004 /* data must be "mapuser"ed */
#define SRF_MAP 0x0008 /* data must be mapped */
#define SRF_MAPBP 0x0010 /* data must be "mapbp"ed */
#define SRF_CONTINGENT_ALLEGIANCE_CLEAR \
0x0020 /* allow new command to be issued */
#define SRF_NEG_SYNC 0x0040 /* attempt to negotiate sync xfer mode on
* this command (if currently async; may be ignored by some
* adapter drivers, either always, or if the driver has previously
* failed to negotiate sync xfer mode with this target); this will
* override the SCSIALLOC_NOSYNC flag to scsi_alloc, if it was
* specified. */
#define SRF_NEG_ASYNC 0x0080 /* attempt to negotiate async xfer mode on
* this command (if currently using sync xfers). */
#define SRF_AEN_ACK SRF_CONTINGENT_ALLEGIANCE_CLEAR /* compatibility */
#define SRF_PRIORITY_REQUEST \
0x0100 /* "priority" scsi request */
#define SRF_ALENLIST 0x0200 /* Use alenlist provided in b_private */
/*
* constants for scsirequest.sr_status; corresponding text msgs in scsi.c
*/
#define SC_GOOD 0 /* No error */
#define SC_TIMEOUT 1 /* Timeout on scsi bus (no response to selection) */
#define SC_HARDERR 2 /* Hardware or scsi device error */
#define SC_PARITY 3 /* Parity error on the SCSI bus during xfer */
#define SC_MEMERR 4 /* Parity/ECC error on host memory */
#define SC_CMDTIME 5 /* the command timed out (did not complete) */
#define SC_ALIGN 6 /* i/o address wasn't properly aligned */
#define SC_ATTN 7 /* unit attention received on other command
* or new command received after a unit attn
* without SRF_AEN_ACK set in sr_flags. */
#define SC_REQUEST 8 /* error in request; malformed, for
* non-existent device; no alloc done,
* sr_notify not set, etc. */
#define NUM_ADAP_ERRS (SC_REQUEST+1)
/*
* constants for scsirequest.sr_tag
*/
#define SC_TAG_SIMPLE 0x20 /* Simple tag message */
#define SC_TAG_HEAD 0x21 /* Head of queue tag message */
#define SC_TAG_ORDERED 0x22 /* Ordered tag message */
/*
* Definitions for operations on a SCSI bus or FC loop
* These structures and #defines are used with the scsi_ioctl interface.
*/
struct scsi_ha_op
{
uint sb_opt; /* command option */
uint sb_arg; /* usually data count */
uintptr_t sb_addr; /* usually user address */
};
typedef struct scsi_ha_op scsi_ha_op_t;
/*
* Definition of structure filled in by SOP_GET_TARGET_PARMS
*/
struct scsi_parms
{
uint sp_selection_timeout; /* Bus selection timeout (in uS) */
ushort sp_scsi_host_id; /* Bus SCSI host ID */
ushort sp_is_diff:8, /* Bus is differential, low voltage diff, single ended */
:8;
struct scsi_target_parms {
ushort stp_is_present:1, /* Device present at this address */
:7,
stp_is_sync:1, /* Device has negotiated synchronous */
stp_is_wide:1; /* Device has negotiated wide */
ushort stp_sync_period; /* Synchronous period (in nS) if stp_is_sync */
ushort stp_sync_offset; /* Synchronous offset (in nS) if stp_is_sync */
} sp_target_parms[16];
};
typedef struct scsi_parms scsi_parms_t;
#define SCIO 's'
#define _SCIO(X) ((SCIO << 8) | (X))
/*
* SCSI bus and Fibrechannel loop commands:
* To download firmware, one would use the SOP_SENDDATA operation.
* To get operational statistics, use the SOP_GETDATA operation.
*/
#define SOP_RESET _SCIO(1) /* SCSI bus reset */
#define SOP_SCAN _SCIO(2) /* scan for devices (inquiry) */
#define SOP_QUIESCE _SCIO(3) /* queiece bus */
#define SOP_UN_QUIESCE _SCIO(4) /* release bus from quesce state */
#define SOP_QUIESCE_STATE _SCIO(5) /* get queisce state */
#define SOP_MAKE_CTL_ALIAS _SCIO(6) /* make controler HWG aliases */
#define SOP_GET_SCSI_PARMS _SCIO(7) /* get SCSI bus/target parameters */
#define SOP_SET_BEHAVE _SCIO(8) /* set various controller behaviours */
/* For DEBUGLEVEL, level is sb_arg */
#define SOP_DEBUGLEVEL _SCIO(11) /* set debug level in host adapter driver */
#define SOP_LIP _SCIO(21) /* initiate FC lip */
#define SOP_ENABLE_PBC _SCIO(22) /* Bypass a device -- turn on LRC */
#define SOP_LPB SOP_ENABLE_PBC /* Bypass a device -- turn on LRC */
#define SOP_DISABLE_PBC _SCIO(23) /* Unbypass a device -- turn off LRC */
#define SOP_LPE SOP_DISABLE_PBC /* Unbypass a device -- turn off LRC */
#define SOP_LPEALL _SCIO(24) /* Unbypass all devices on loop */
#define SOP_LIPRST _SCIO(25) /* LIP with selective device RESET */
/* SOP_QUIESCE_STATE ioctl write one of the following states to sb_addr */
#define NO_QUIESCE_IN_PROGRESS 0x1
#define QUIESCE_IN_PROGRESS 0x2
#define QUIESCE_IS_COMPLETE 0x4
/* SOP_SET_BEHAVE behaviour subcodes in sb_opt */
#define LUN_QERR 0x1
/*
* Encoding of sb_arg when sb_opt == LUN_QERR
* 00ttllqq tt = target number
* ll = lun number
* qq = 0/1 - QERR setting
*/
#define SOP_QERR_TARGET_SHFT 16
#define SOP_QERR_LUN_SHFT 8
#define SOP_QERR_VAL_SHFT 0
/*
* For GETDATA and SENDDATA:
* sb_opt is sub operation,
* sb_arg is count, and
* sb_addr is user address
*/
#define SOP_GETDATA 101 /* get data from host adapter driver */
#define SOP_SENDDATA 102 /* send data to host adapter driver */
#define SCSI_DISK_VOL_PARTITION 10 /* volume partition */
#define SCSI_DISK_VH_PARTITION 8 /* volume header partition */
#define SCSI_DISK_UNDEFINED '\0'
#define SMFD_DEFAULT "48"
#if _KERNEL && !_STANDALONE
extern void subchaninit(vertex_hdl_t, scsi_request_t *, uint);
extern int cdrom_inquiry_test(u_char *);
/* dev scsi driver prefix */
#define DS_PREFIX "ds"
/*
* some useful sprintf formats for getting locator strings in the hardware graph
*/
#define TARG_LUN_FORMAT "target/%d/lun/%d"
#define PART_FORMAT "%s/%d"
#define TARG_FORMAT "target"
#define TARG_NUM_FORMAT "target/%d"
#define NODE_PORT_NUM_FORMAT "node/%llx/port/%llx"
#define LUN_FORMAT "lun"
#define LUN_NUM_FORMAT "lun/%d"
#define SPRINTF_PART(part,loc_str) if (part == SCSI_DISK_VH_PARTITION) \
sprintf(loc_str, EDGE_LBL_VOLUME_HEADER); \
else if (part == SCSI_DISK_VOL_PARTITION) \
sprintf(loc_str, EDGE_LBL_VOLUME); \
else \
sprintf(loc_str,PART_FORMAT, EDGE_LBL_PARTITION, part);
/*
* useful for creating the existing partition
* vertices for scsi disk devices
*/
#define DKSC_PREFIX "dksc"
/* max. length of the locator string */
#define LOC_STR_MAX_LEN 50
#define VERTEX_FOUND 1
#define VERTEX_NOT_FOUND 0
typedef int ctlr_t; /* type for the adapter */
typedef int targ_t; /* type for the target */
typedef int lun_t; /* type for the lun */
typedef struct scsi_ctlr_info {
vertex_hdl_t sci_ctlr_vhdl; /* vertex handle of the controller */
/*
* scsi functional interface
*/
int (*sci_alloc)(vertex_hdl_t lun_vhdl,int,void (*cb)());
void (*sci_free)(vertex_hdl_t lun_vhdl,void (*cb)());
struct scsi_target_info * (*sci_inq)(vertex_hdl_t lun_vhdl);
int (*sci_dump)(vertex_hdl_t ctlr_vhdl);
int (*sci_ioctl)(vertex_hdl_t ctlr_vhdl,
unsigned int cmd,
struct scsi_ha_op *op);
void (*sci_command)(scsi_request_t *);
int (*sci_abort)(scsi_request_t *);
__uint64_t sci_initiator_id;
uchar_t sci_adap; /* adapter number */
void *sci_info; /* info maintained for the controller */
} scsi_ctlr_info_t;
/*
* macros associated with the controller info
*/
#define SCI_ADAP(p) (p->sci_adap) /* adapter number */
#define SCI_CTLR_VHDL(p) (p->sci_ctlr_vhdl) /* controller vertex handle */
#define SCI_ALLOC(p) (p->sci_alloc)
#define SCI_FREE(p) (p->sci_free)
#define SCI_INQ(p) (p->sci_inq)
#define SCI_DUMP(p) (p->sci_dump)
#define SCI_IOCTL(p) (p->sci_ioctl)
#define SCI_COMMAND(p) (p->sci_command)
#define SCI_ABORT(p) (p->sci_abort)
#define SCI_INFO(p) (p->sci_info)
/*
* information maintained for the scsi target vertex
*/
typedef struct scsi_targ_info {
vertex_hdl_t sti_targ_vhdl;
scsi_ctlr_info_t *sti_ctlr_info; /* scsi controller info */
targ_t sti_targ; /* unit number */
void *sti_info; /* info maintained for the target */
uint64_t sti_node; /* FC node name */
uint64_t sti_port; /* FC port name */
} scsi_targ_info_t;
/*
* macros associated with the target info
*/
#define STI_TARG_VHDL(p) (p->sti_targ_vhdl)
#define STI_CTLR_INFO(p) (p->sti_ctlr_info) /* controller info */
#define STI_TARG(p) (p->sti_targ) /* unit number */
#define STI_INFO(p) (p->sti_info) /* driver specific target info */
#define STI_NODE(p) (p->sti_node)
#define STI_PORT(p) (p->sti_port)
/*
* information associated with a scsi lun vertex
*/
typedef struct scsi_lun_info {
vertex_hdl_t sli_lun_vhdl; /* lun vertex handle */
scsi_targ_info_t *sli_targ_info; /* scsi target info */
lun_t sli_lun; /* lun */
void *sli_info; /* info maintained for the lun */
void *sli_fo_info; /* pointer to failover info */
} scsi_lun_info_t;
/*
* macros associated with the lun info
*/
#define SLI_LUN_VHDL(p) (p->sli_lun_vhdl) /* lun vhdl */
#define SLI_TARG_INFO(p) (p->sli_targ_info) /* target info */
#define SLI_LUN(p) (p->sli_lun) /* lun */
#define SLI_INFO(p) (p->sli_info)
#define SLI_FO_INFO(p) (p->sli_fo_info)
#define SLI_TARG(p) (STI_TARG(SLI_TARG_INFO(p))) /* unit number */
#define SLI_NODE(p) (STI_NODE(SLI_TARG_INFO(p)))
#define SLI_PORT(p) (STI_PORT(SLI_TARG_INFO(p)))
#define SLI_CTLR_INFO(p) (STI_CTLR_INFO(SLI_TARG_INFO(p))) /* controller info from
* lun info pointer
*/
#define SLI_CTLR_VHDL(p) (SCI_CTLR_VHDL(STI_CTLR_INFO(SLI_TARG_INFO(p))))
#define SLI_ADAP(p) (SCI_ADAP(STI_CTLR_INFO(SLI_TARG_INFO(p))))
/* controller number
* from lun info ptr
*/
#define SLI_INQ(p) (*(SCI_INQ(STI_CTLR_INFO(SLI_TARG_INFO(p)))))
#define SLI_ALLOC(p) (*(SCI_ALLOC(STI_CTLR_INFO(SLI_TARG_INFO(p)))))
#define SLI_FREE(p) (*(SCI_FREE(STI_CTLR_INFO(SLI_TARG_INFO(p)))))
#define SLI_COMMAND(p) (*(SCI_COMMAND(STI_CTLR_INFO(SLI_TARG_INFO(p)))))
#define SLI_IOCTL(p) (*(SCI_IOCTL(STI_CTLR_INFO(SLI_TARG_INFO(p)))))
/*
* information associated with an unit vertex
* Unit vertices are used by tpsc.
*/
typedef struct scsi_unit_info {
vertex_hdl_t sui_unit_vhdl;
int sui_sm_created; /* does the state machine exist for this tape */
u_char *sui_inv; /* inventory info */
void *sui_ctinfo; /* unit specific info */
mutex_t sui_opensema; /* semaphore to single thread opens on a unit */
scsi_lun_info_t *sui_lun_info; /* pointer to lun info */
} scsi_unit_info_t;
/* macros associated with the scsi unit info structure */
#define SUI_UNIT_VHDL(p) (p->sui_unit_vhdl)
#define SUI_SM_CREATED(p) (p->sui_sm_created)
#define SUI_INV(p) (p->sui_inv)
#define SUI_TYPE(p) (SUI_INV(p)[0] & 0x1f)
#define SUI_CTINFO(p) (p->sui_ctinfo)
#define SUI_OPENSEMA(p) (p->sui_opensema)
#define SUI_LUN_INFO(p) (p->sui_lun_info)
#define SUI_CTLR_VHDL(p) (SLI_CTLR_VHDL(SUI_LUN_INFO(p)))
#define SUI_ADAP(p) (SLI_ADAP(SUI_LUN_INFO(p)))
#define SUI_TARG(p) (SLI_TARG(SUI_LUN_INFO(p)))
#define SUI_LUN_VHDL(p) (SLI_LUN_VHDL(SUI_LUN_INFO(p)))
#define SUI_LUN(p) (SLI_LUN(SUI_LUN_INFO(p)))
#define SUI_NODE(p) (SLI_NODE(SUI_LUN_INFO(p)))
#define SUI_PORT(p) (SLI_PORT(SUI_LUN_INFO(p)))
#define SUI_ALLOC(p) (*(SCI_ALLOC(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/* alloc function pointer from unit info */
#define SUI_FREE(p) (*(SCI_FREE(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/* free function pointer from unit info */
#define SUI_DUMP(p) (*(SCI_DUMP(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/* dump function pointer from unit info */
#define SUI_INQ(p) (*(SCI_INQ(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/* info function pointer from unit info */
#define SUI_IOCTL(p) (*(SCI_IOCTL(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/* ioctl function pointer from unit info */
#define SUI_COMMAND(p) (*(SCI_COMMAND(STI_CTLR_INFO(SLI_TARG_INFO(SUI_LUN_INFO(p))))))
/*
* information associated with an devscsi vertex
*/
typedef struct scsi_dev_info {
scsi_lun_info_t *sdevi_lun_info;
void *sdevi_tds;
vertex_hdl_t sdevi_dev_vhdl;
mutex_t sdevi_tdslock;
} scsi_dev_info_t;
#define SDEVI_DEV_VHDL(p) (p->sdevi_dev_vhdl)
#define SDEVI_LUN_INFO(p) (p->sdevi_lun_info)
#define SDEVI_TDSLOCK(p) (p->sdevi_tdslock)
#define SDEVI_ADAP(p) (SLI_ADAP(SDEVI_LUN_INFO(p)))
#define SDEVI_TARG(p) (SLI_TARG(SDEVI_LUN_INFO(p)))
#define SDEVI_LUN(p) (SLI_LUN(SDEVI_LUN_INFO(p)))
#define SDEVI_LUN_VHDL(p) (SLI_LUN_VHDL(SDEVI_LUN_INFO(p)))
#define SDEVI_NODE(p) (SLI_NODE(SDEVI_LUN_INFO(p)))
#define SDEVI_PORT(p) (SLI_PORT(SDEVI_LUN_INFO(p)))
#define SDEVI_ALLOC(dev) (*(SCI_ALLOC(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* alloc function pointer from scsi info */
#define SDEVI_FREE(dev) (*(SCI_FREE(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* free function pointer from scsi info */
#define SDEVI_DUMP(dev) (*(SCI_DUMP(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* dump function pointer from scsi info */
#define SDEVI_INQ(dev) (*(SCI_INQ(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* info function pointer from scsi info */
#define SDEVI_IOCTL(dev) (*(SCI_IOCTL(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* ioctl function pointer from scsi info */
#define SDEVI_COMMAND(dev) (*(SCI_COMMAND(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
/* command function ptr from scsi info*/
#define SDEVI_ABORT(dev) (*(SCI_ABORT(STI_CTLR_INFO(SLI_TARG_INFO(SDEVI_LUN_INFO(scsi_dev_info_get(dev)))))))
#define SDEVI_TDS(dev) (scsi_dev_info_get(dev)->sdevi_tds)
/*
* information associated with a disk vertex
*/
typedef struct scsi_disk_info {
vertex_hdl_t sdi_disk_vhdl; /* disk vertex handle */
scsi_lun_info_t *sdi_lun_info; /* scsi lun info */
mutex_t sdi_dksema; /* general dksc semaphore */
void *sdi_dksoftc; /* driver specific info */
void *sdi_dkiotime; /* driver specific iotime */
} scsi_disk_info_t;
/*
* macros associated with this structure
*/
#define SDI_DISK_VHDL(p) (p->sdi_disk_vhdl) /* disk vertex handle */
#define SDI_LUN_INFO(p) (p->sdi_lun_info) /* lun info pointer from disk info */
#define SDI_DKSEMA(p) (p->sdi_dksema) /* semaphore from disk info */
#define SDI_DKSOFTC(p) (p->sdi_dksoftc) /* driver specific info */
#define SDI_DKIOTIME(p) (p->sdi_dkiotime) /* driver specific info */
#define SDI_LUN_VHDL(p) (SLI_LUN_VHDL(SDI_LUN_INFO(p)))
/* lun vertex handle from
* disk info
*/
#define SDI_CTLR_VHDL(p) (SCI_CTLR_VHDL(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p)))))
/* controller vertex handle from
* disk info
*/
#define SDI_ADAP(p) (SCI_ADAP(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p)))))
/* adapter from the disk info
*/
#define SDI_TARG(p) (SLI_TARG(SDI_LUN_INFO(p)))
/* target number from disk info */
#define SDI_NODE(p) (SLI_NODE(SDI_LUN_INFO(p)))
#define SDI_PORT(p) (SLI_PORT(SDI_LUN_INFO(p)))
#define SDI_LUN(p) (SLI_LUN(SDI_LUN_INFO(p)))
/* lun from disk info */
#define SDI_ALLOC(p) (*(SCI_ALLOC(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* alloc function pointer from disk info */
#define SDI_FREE(p) (*(SCI_FREE(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* free function pointer from disk info */
#define SDI_DUMP(p) (*(SCI_DUMP(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* dump function pointer from disk info */
#define SDI_INQ(p) (*(SCI_INQ(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* info function pointer from disk info */
#define SDI_IOCTL(p) (*(SCI_IOCTL(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* ioctl function pointer from disk info */
#define SDI_COMMAND(p) (*(SCI_COMMAND(STI_CTLR_INFO(SLI_TARG_INFO(SDI_LUN_INFO(p))))))
/* command function ptr from disk info*/
/*
* information associated with a disk partition vertex
*/
typedef struct scsi_part_info {
vertex_hdl_t spi_part_vhdl;
scsi_disk_info_t *spi_disk_info; /* scsi disk info */
uchar_t spi_part; /* partition number */
} scsi_part_info_t;
/*
* macros associated with fields in the part info
*/
#define SPI_PART_VHDL(p) (p->spi_part_vhdl)
#define SPI_DISK_INFO(p) (p->spi_disk_info) /* pointer to disk info */
#define SPI_PART(p) (p->spi_part) /* partition number */
#define SPI_DISK_VHDL(p) (SDI_DISK_VHDL(SPI_DISK_INFO(p)))
extern void scsi_device_update(u_char *, vertex_hdl_t);
extern scsi_ctlr_info_t *scsi_ctlr_info_init(void);
extern void scsi_ctlr_info_put(vertex_hdl_t,scsi_ctlr_info_t *);
extern scsi_ctlr_info_t *scsi_ctlr_info_get(vertex_hdl_t);
extern scsi_targ_info_t *scsi_targ_info_init(void);
extern void scsi_targ_info_put(vertex_hdl_t,scsi_targ_info_t *);
extern scsi_targ_info_t *scsi_targ_info_get(vertex_hdl_t);
extern scsi_lun_info_t *scsi_lun_info_init(void);
extern void scsi_lun_info_put(vertex_hdl_t,scsi_lun_info_t *);
extern scsi_lun_info_t *scsi_lun_info_get(vertex_hdl_t);
extern void scsi_unit_info_put(vertex_hdl_t,scsi_unit_info_t *);
extern scsi_unit_info_t *scsi_unit_info_get(vertex_hdl_t);
extern void scsi_dev_info_put(vertex_hdl_t,scsi_dev_info_t *);
extern scsi_dev_info_t *scsi_dev_info_get(vertex_hdl_t);
extern void scsi_dev_info_free(vertex_hdl_t);
extern scsi_disk_info_t *scsi_disk_info_init(void);
extern void scsi_disk_info_put(vertex_hdl_t,scsi_disk_info_t *);
extern scsi_disk_info_t *scsi_disk_info_get(vertex_hdl_t);
extern scsi_part_info_t *scsi_part_info_init(void);
extern void scsi_part_info_put(vertex_hdl_t,scsi_part_info_t *);
extern scsi_part_info_t *scsi_part_info_get(vertex_hdl_t);
extern void dk_namespace_remove(vertex_hdl_t);
extern void dk_base_namespace_add(vertex_hdl_t, boolean_t);
extern int scsi_targ_vertex_exist(vertex_hdl_t,targ_t,
vertex_hdl_t *);
extern int scsi_node_port_vertex_exist(vertex_hdl_t,
uint64_t, uint64_t, vertex_hdl_t *);
extern vertex_hdl_t scsi_targ_vertex_add(vertex_hdl_t,targ_t);
extern vertex_hdl_t scsi_node_port_vertex_add(vertex_hdl_t,
uint64_t, uint64_t);
extern vertex_hdl_t scsi_targ_vertex_remove(vertex_hdl_t,targ_t);
extern vertex_hdl_t scsi_node_port_vertex_remove(vertex_hdl_t,
uint64_t, uint64_t);
extern int scsi_lun_vertex_exist(vertex_hdl_t,lun_t,
vertex_hdl_t *);
extern vertex_hdl_t scsi_lun_vertex_add(vertex_hdl_t,lun_t);
extern vertex_hdl_t scsi_lun_vertex_remove(vertex_hdl_t,lun_t);
extern int scsi_disk_vertex_exist(vertex_hdl_t,
vertex_hdl_t *);
extern vertex_hdl_t scsi_disk_vertex_add(vertex_hdl_t,int);
extern void scsi_disk_vertex_remove(vertex_hdl_t);
extern int scsi_part_vertex_exist(vertex_hdl_t,uchar_t,
vertex_hdl_t *);
extern vertex_hdl_t scsi_part_vertex_add(vertex_hdl_t,uchar_t,boolean_t);
extern void scsi_part_vertex_remove(vertex_hdl_t,uchar_t );
extern void scsi_bus_create(vertex_hdl_t);
extern vertex_hdl_t scsi_lun_vhdl_get(vertex_hdl_t,targ_t,lun_t);
extern vertex_hdl_t scsi_fabric_lun_vhdl_get(vertex_hdl_t, uint64_t,
uint64_t, lun_t);
extern uint64_t fc_short_portname(uint64_t, uint64_t);
extern void scsi_alias_edge_remove(vertex_hdl_t, char *, char *, char *);
extern int scsi_driver_register(int,char *);
extern void scsi_driver_unregister(char *);
struct scsi_driver_reg {
char *sd_vendor_id;
char *sd_product_id;
char *sd_driver_prefix;
char *sd_pathname_prefix;
};
typedef struct scsi_driver_reg scsi_driver_reg_s;
typedef struct scsi_driver_reg *scsi_driver_reg_t;
struct scsi_type_reg {
char st_last;
scsi_driver_reg_t st_sdr;
};
typedef struct scsi_type_reg scsi_type_reg_s;
typedef struct scsi_type_reg *scsi_type_reg_t;
extern scsi_type_reg_s scsi_drivers[];
extern scsi_driver_reg_t scsi_device_driver_info_get(u_char *);
#define PREFIX_TO_KEY(_str_) (((uint_t)(_str_)[0] << 24) | \
((uint_t)(_str_)[1] << 16) | \
((uint_t)(_str_)[2] << 8) | \
((uint_t)(_str_)[0] << 0))
extern vertex_hdl_t scsi_device_add(vertex_hdl_t ctlr_vhdl,
targ_t targ,
lun_t lun);
extern void scsi_device_remove(vertex_hdl_t ctlr_vhdl,
targ_t targ,
lun_t lun);
typedef struct {
char *str;
u_char offset;
__psint_t arg;
} single_inq_str_s;
typedef single_inq_str_s *single_inq_str_t;
typedef struct {
char *str1;
u_char offset1;
char *str2;
u_char offset2;
__psint_t arg;
} double_inq_str_s;
typedef double_inq_str_s *double_inq_str_t;
/* Locking & Unlocking defines for the scsi_alias_mutex which controls
* mutual exclusion for all the scsi alias driectories under /hw.
*/
extern mutex_t scsi_alias_mutex;
#define SCSI_ALIAS_LOCK() mutex_lock(&scsi_alias_mutex, PRIBIO)
#define SCSI_ALIAS_UNLOCK() mutex_unlock(&scsi_alias_mutex)
#endif /* _KERNEL && !_STANDALONE */
#endif /* _NSCSI_ */