table of contents
CAM_CDBPARSE(3) | Library Functions Manual | CAM_CDBPARSE(3) |
NAME¶
csio_build, csio_build_visit, csio_decode, csio_decode_visit, buff_decode, buff_decode_visit, csio_encode, csio_encode_visit, buff_encode_visit — CAM user library SCSI buffer parsing routinesLIBRARY¶
Common Access Method User Library (libcam, -lcam)SYNOPSIS¶
#include <stdio.h>#include <camlib.h> 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_decode(struct ccb_scsiio *csio, const char *fmt, ...); int
csio_decode_visit(struct ccb_scsiio *csio, const char *fmt, void (*arg_put)(void *hook, int letter, void *val, int count, char *name), void *puthook); int
buff_decode(u_int8_t *buff, size_t len, const char *fmt, ...); 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_encode(struct ccb_scsiio *csio, const char *fmt, ...); int
csio_encode_visit(struct ccb_scsiio *csio, const char *fmt, int (*arg_get)(void *hook, char *field_name), void *gethook); int
buff_encode_visit(u_int8_t *buff, size_t len, const char *fmt, int (*arg_get)(void *hook, char *field_name), void *gethook);
DESCRIPTION¶
The CAM buffer/CDB encoding and decoding routines provide a relatively easy migration path for userland SCSI applications written with the similarly-named scsireq_* functions from the old FreeBSD SCSI layer. These functions may be used in new applications, but users may find it easier to use the various SCSI CCB building functions included with the cam(3) library. (e.g. cam_fill_csio(), scsi_start_stop(), and scsi_read_write()) csio_build() builds up a ccb_scsiio structure based on the information provided in the variable argument list. It gracefully handles a NULL data_ptr argument passed to it. dxfer_len is the length of the data phase; the data transfer direction is determined by the flags argument. data_ptr is the data buffer used during the SCSI data phase. If no data is to be transferred for the SCSI command in question, this should be set to NULL. If there is data to transfer for the command, this buffer must be at least dxfer_len long. flags are the flags defined in <cam/cam_ccb.h>:/* Common CCB header */ /* CAM CCB flags */ typedef enum { CAM_CDB_POINTER = 0x00000001,/* The CDB field is a pointer */ CAM_QUEUE_ENABLE = 0x00000002,/* SIM queue actions are enabled */ CAM_CDB_LINKED = 0x00000004,/* CCB contains a linked CDB */ CAM_SCATTER_VALID = 0x00000010,/* Scatter/gather list is valid */ CAM_DIS_AUTOSENSE = 0x00000020,/* Disable autosense feature */ CAM_DIR_RESV = 0x00000000,/* Data direction (00:reserved) */ CAM_DIR_IN = 0x00000040,/* Data direction (01:DATA IN) */ CAM_DIR_OUT = 0x00000080,/* Data direction (10:DATA OUT) */ CAM_DIR_NONE = 0x000000C0,/* Data direction (11:no data) */ CAM_DIR_MASK = 0x000000C0,/* Data direction Mask */ CAM_SOFT_RST_OP = 0x00000100,/* Use Soft reset alternative */ CAM_ENG_SYNC = 0x00000200,/* Flush resid bytes on complete */ CAM_DEV_QFRZDIS = 0x00000400,/* Disable DEV Q freezing */ CAM_DEV_QFREEZE = 0x00000800,/* Freeze DEV Q on execution */ CAM_HIGH_POWER = 0x00001000,/* Command takes a lot of power */ CAM_SENSE_PTR = 0x00002000,/* Sense data is a pointer */ CAM_SENSE_PHYS = 0x00004000,/* Sense pointer is physical addr*/ CAM_TAG_ACTION_VALID = 0x00008000,/* Use the tag action in this ccb*/ CAM_PASS_ERR_RECOVER = 0x00010000,/* Pass driver does err. recovery*/ CAM_DIS_DISCONNECT = 0x00020000,/* Disable disconnect */ CAM_SG_LIST_PHYS = 0x00040000,/* SG list has physical addrs. */ CAM_MSG_BUF_PHYS = 0x00080000,/* Message buffer ptr is physical*/ CAM_SNS_BUF_PHYS = 0x00100000,/* Autosense data ptr is physical*/ CAM_DATA_PHYS = 0x00200000,/* SG/Buffer data ptrs are phys. */ CAM_CDB_PHYS = 0x00400000,/* CDB pointer is physical */ CAM_ENG_SGLIST = 0x00800000,/* SG list is for the HBA engine */ /* Phase cognizant mode flags */ CAM_DIS_AUTOSRP = 0x01000000,/* Disable autosave/restore ptrs */ CAM_DIS_AUTODISC = 0x02000000,/* Disable auto disconnect */ CAM_TGT_CCB_AVAIL = 0x04000000,/* Target CCB available */ CAM_TGT_PHASE_MODE = 0x08000000,/* The SIM runs in phase mode */ CAM_MSGB_VALID = 0x20000000,/* Message buffer valid */ CAM_STATUS_VALID = 0x40000000,/* Status buffer valid */ CAM_DATAB_VALID = 0x80000000,/* Data buffer valid */ /* Host target Mode flags */ CAM_TERM_IO = 0x20000000,/* Terminate I/O Message sup. */ CAM_DISCONNECT = 0x40000000,/* Disconnects are mandatory */ CAM_SEND_STATUS = 0x80000000,/* Send status after data phase */ } ccb_flags;
CAM_DIR_IN
- This indicates that the operation in question is a read operation. i.e., data is being read from the SCSI device to the user-supplied buffer.
CAM_DIR_OUT
- This indicates that the operation is a write operation. i.e., data is being written from the user-supplied buffer to the device.
CAM_DIR_NONE
- This indicates that there is no data to be transferred for this command.
CAM_DEV_QFRZDIS
- This flag disables device queue freezing as an error recovery mechanism.
CAM_PASS_ERR_RECOVER
- This flag tells the pass(4) driver to enable error recovery. The default is to not perform error recovery, which means that the retry count will not be honored without this flag, among other things.
CAM_DATA_PHYS
- This indicates that the address contained in data_ptr is a physical address, not a virtual address.
CAM_PASS_ERR_RECOVER
flag.
The timeout tells the kernel how long to wait for the
given command to complete. If the timeout expires and the command has not
completed, the CCB will be returned from the kernel with an appropriate error
status.
cmd_spec is a CDB format specifier used to build up the
SCSI CDB. This text string is made up of a list of field specifiers. Field
specifiers specify the value for each CDB field (including indicating that the
value be taken from the next argument in the variable argument list), the
width of the field in bits or bytes, and an optional name. White space is
ignored, and the pound sign ('#') introduces a comment that ends at the end of
the current line.
The optional name is the first part of a field specifier and is in curly braces.
The text in curly braces in this example are the names:
{PS} v:b1 {Reserved} 0:b1 {Page Code} v:b6 #
Mode select page
- gethook
- is passed into the arg_get() function at each invocation. This enables the arg_get() function to keep some state in between calls without using global or static variables.
- field_name
- is the field name supplied in fmt, if any.
- hook
- The "hook" is a mechanism to allow the arg_put() function to save state in between calls.
- letter
- is the letter describing the format of the argument being passed into the function.
- val
- is a void pointer to the value being passed into the function.
- count
- is the size of the value being passed into the arg_put() function. The argument format determines the unit of measure.
- name
- This is a text description of the field, if one was provided in the fmt.
RETURN VALUES¶
csio_build(), csio_build_visit(), csio_encode(), csio_encode_visit(), and buff_encode_visit() return the number of fields processed. csio_decode(), csio_decode_visit(), buff_decode(), and buff_decode_visit() return the number of assignments performed.SEE ALSO¶
cam(3), pass(4), camcontrol(8)HISTORY¶
The CAM versions of these functions are based upon similar functions implemented for the old FreeBSD SCSI layer. The encoding/decoding functions in the old SCSI code were written by Peter Dufault. Many systems have comparable interfaces to permit a user to construct a SCSI command in user space. The old scsireq data structure was almost identical to the SGI /dev/scsi data structure. If anyone knows the name of the authors it should go here; Peter Dufault first read about it in a 1989 Sun Expert magazine. The new CCB data structures are derived from the CAM-2 and CAM-3 specifications. Peter Dufault implemented a clone of SGI's interface in 386BSD that led to the original FreeBSD SCSI library and the related kernel ioctl. If anyone needs that for compatibility contact dufault@hda.com.AUTHORS¶
Kenneth Merry implemented the CAM versions of these encoding and decoding functions. This current work is based upon earlier work by Peter Dufault.BUGS¶
There should probably be a function that encodes both the CDB and the data buffer portions of a SCSI CCB. I discovered this while implementing the arbitrary command execution code in camcontrol(8), but I have not yet had time to implement such a function. Some of the CCB flag descriptions really do not belong here. Rather they belong in a generic CCB man page. Since that man page has not yet been written, the shorter descriptions here will have to suffice.October 13, 1998 | Debian |