root/usr/src/uts/common/sys/scsi/impl/mode.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _SYS_SCSI_IMPL_MODE_H
#define _SYS_SCSI_IMPL_MODE_H

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * Defines and Structures for SCSI Mode Sense/Select data
 *
 * Implementation Specific variations
 */

/*
 * Variations to Sequential Access device mode header
 */
struct  modeheader_seq {
        uchar_t datalen;        /* sense data length */
        uchar_t mediumtype;     /* medium type */
#if defined(_BIT_FIELDS_LTOH)
        uchar_t speed   :4,     /* speed */
                bufm    :3,     /* buffered mode */
                wp      :1;     /* write protected */
#elif defined(_BIT_FIELDS_HTOL)
        uchar_t wp      :1,     /* write protected */
                bufm    :3,     /* buffered mode */
                speed   :4;     /* speed */
#else
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */
        uchar_t bd_len;         /* block length in bytes */
        struct  block_descriptor blk_desc;
};

/*
 * Variations to Direct Access device pages
 */

/*
 * Page 1: CCS error recovery page was a little different than SCSI-2/3
 */

#define PAGELENGTH_DAD_MODE_ERR_RECOV_CCS       0x06

struct mode_err_recov_ccs {
        struct  mode_page mode_page;    /* common mode page header */
#if defined(_BIT_FIELDS_LTOH)
        uchar_t         dcr     : 1,    /* disable correction */
                        dte     : 1,    /* disable transfer on error */
                        per     : 1,    /* post error */
                        eec     : 1,    /* enable early correction */
                        rc      : 1,    /* read continuous */
                        tb      : 1,    /* transfer block */
                        arre    : 1,    /* auto read realloc enabled */
                        awre    : 1;    /* auto write realloc enabled */
#elif defined(_BIT_FIELDS_HTOL)
        uchar_t         awre    : 1,    /* auto write realloc enabled */
                        arre    : 1,    /* auto read realloc enabled */
                        tb      : 1,    /* transfer block */
                        rc      : 1,    /* read continuous */
                        eec     : 1,    /* enable early correction */
                        per     : 1,    /* post error */
                        dte     : 1,    /* disable transfer on error */
                        dcr     : 1;    /* disable correction */
#else
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */
        uchar_t retry_count;
        uchar_t correction_span;
        uchar_t head_offset_count;
        uchar_t strobe_offset_count;
        uchar_t recovery_time_limit;
};

/*
 * Page 3: CCS Direct Access Device Format Parameters
 *
 * The 0x8 bit in the Drive Type byte is used in CCS
 * as an INHIBIT SAVE bit. This bit is not in SCSI-2/3.
 */

#define _reserved_ins   ins

/*
 * Page 8: SCSI-2 Cache page was a little different than SCSI-3
 */

#define PAGELENGTH_DAD_MODE_CACHE       0x0A

struct mode_cache {
        struct  mode_page mode_page;    /* common mode page header */
#if defined(_BIT_FIELDS_LTOH)
        uchar_t         rcd     : 1,    /* Read Cache Disable */
                        mf      : 1,    /* Multiplication Factor */
                        wce     : 1,    /* Write Cache Enable */
                                : 5;
        uchar_t write_reten_pri : 4,    /* Write Retention Priority */
                read_reten_pri  : 4;    /* Demand Read Retention Priority */
#elif defined(_BIT_FIELDS_HTOL)
        uchar_t                 : 5,
                        wce     : 1,    /* Write Cache Enable */
                        mf      : 1,    /* Multiplication Factor */
                        rcd     : 1;    /* Read Cache Disable */
        uchar_t read_reten_pri  : 4,    /* Demand Read Retention Priority */
                write_reten_pri : 4;    /* Write Retention Priority */
#else
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */
        ushort_t dis_prefetch_len;      /* Disable prefetch xfer length */
        ushort_t min_prefetch;          /* minimum prefetch length */
        ushort_t max_prefetch;          /* maximum prefetch length */
        ushort_t prefetch_ceiling;      /* max prefetch ceiling */
};

/*
 * Page 0x38 - This is the CCS Cache Page
 */

struct mode_cache_ccs {
        struct  mode_page mode_page;    /* common mode page header */
        uchar_t mode;                   /* Cache control and size */
        uchar_t threshold;              /* Prefetch threshold */
        uchar_t max_prefetch;           /* Max. prefetch */
        uchar_t max_multiplier;         /* Max. prefetch multiplier */
        uchar_t min_prefetch;           /* Min. prefetch */
        uchar_t min_multiplier;         /* Min. prefetch multiplier */
        uchar_t rsvd2[8];
};

/*
 * Page A: SCSI-2 control page was a little different than SCSI-3
 */

#define PAGELENGTH_MODE_CONTROL         0x06

struct mode_control {
        struct  mode_page mode_page;    /* common mode page header */
#if defined(_BIT_FIELDS_LTOH)
        uchar_t         rlec    : 1,    /* Report Log Exception bit */
                                : 7;
        uchar_t         qdisable: 1,    /* Queue disable */
                        que_err : 1,    /* Queue error */
                                : 2,
                        que_mod : 4;    /* Queue algorithm modifier */
        uchar_t         eanp    : 1,
                        uaaenp  : 1,
                        raenp   : 1,
                                : 4,
                        eeca    : 1;
#elif defined(_BIT_FIELDS_HTOL)
        uchar_t                 : 7,
                        rlec    : 1;    /* Report Log Exception bit */
        uchar_t         que_mod : 4,    /* Queue algorithm modifier */
                                : 2,
                        que_err : 1,    /* Queue error */
                        qdisable: 1;    /* Queue disable */
        uchar_t         eeca    : 1,
                                : 4,
                        raenp   : 1,
                        uaaenp  : 1,
                        eanp    : 1;
#else
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */
        uchar_t reserved;
        ushort_t ready_aen_holdoff;
};


/*
 * Emulex MD21 Unique Mode Select/Sense structure.
 * This is apparently not used, although the MD21
 * documentation refers to it.
 *
 * The medium_type in the mode header must be 0x80
 * to indicate a vendor unique format. There is then
 * a standard block descriptor page, which must be
 * zeros (although the block descriptor length is set
 * appropriately in the mode header).
 *
 * After this stuff, comes the vendor unique ESDI
 * format parameters for the MD21.
 *
 * Notes:
 *
 *      1) The logical number of sectors/track should be the
 *      number of physical sectors/track less the number spare
 *      sectors/track.
 *
 *      2) The logical number of cylinders should be the
 *      number of physical cylinders less three (3) reserved
 *      for use by the drive, and less any alternate cylinders
 *      allocated.
 *
 *      3) head skew- see MD21 manual.
 */

struct emulex_format_params {
        uchar_t alt_cyl;        /* number of alternate cylinders */
#if defined(_BIT_FIELDS_LTOH)
        uchar_t         : 1,
                sst     : 2,    /* spare sectors per track */
                ssz     : 1,    /* sector size. 1 == 256 bps, 0 == 512 bps */
                nheads  : 4;    /* number of heads */
#elif defined(_BIT_FIELDS_HTOL)
        uchar_t nheads  : 4,    /* number of heads */
                ssz     : 1,    /* sector size. 1 == 256 bps, 0 == 512 bps */
                sst     : 2,    /* spare sectors per track */
                        : 1;
#else
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */
        uchar_t nsect;          /* logical sectors/track */
        uchar_t ncyl_hi;        /* logical number of cylinders, msb */
        uchar_t ncyl_lo;        /* logical number of cylinders, lsb */
        uchar_t head_skew;      /* head skew */
        uchar_t reserved[3];
};

/*
 * Page 0x31: CD-ROM speed page
 */

#define CDROM_MODE_SPEED        0x31

struct mode_speed {
        struct  mode_page mode_page;    /* common mode page header */
        uchar_t speed;                  /* drive speed */
        uchar_t reserved;
};

/*
 * Definitions for drive speed supported are in cdio.h
 */

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_SCSI_IMPL_MODE_H */