The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/isp_tpublic.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: isp_tpublic.h,v 1.12 2003/12/04 13:57:30 keihan Exp $ */
    2 /*
    3  * This driver, which is contained in NetBSD in the files:
    4  *
    5  *      sys/dev/ic/isp.c
    6  *      sys/dev/ic/isp_inline.h
    7  *      sys/dev/ic/isp_netbsd.c
    8  *      sys/dev/ic/isp_netbsd.h
    9  *      sys/dev/ic/isp_target.c
   10  *      sys/dev/ic/isp_target.h
   11  *      sys/dev/ic/isp_tpublic.h
   12  *      sys/dev/ic/ispmbox.h
   13  *      sys/dev/ic/ispreg.h
   14  *      sys/dev/ic/ispvar.h
   15  *      sys/microcode/isp/asm_sbus.h
   16  *      sys/microcode/isp/asm_1040.h
   17  *      sys/microcode/isp/asm_1080.h
   18  *      sys/microcode/isp/asm_12160.h
   19  *      sys/microcode/isp/asm_2100.h
   20  *      sys/microcode/isp/asm_2200.h
   21  *      sys/pci/isp_pci.c
   22  *      sys/sbus/isp_sbus.c
   23  *
   24  * Is being actively maintained by Matthew Jacob (mjacob@NetBSD.org).
   25  * This driver also is shared source with FreeBSD, OpenBSD, Linux, Solaris,
   26  * Linux versions. This tends to be an interesting maintenance problem.
   27  *
   28  * Please coordinate with Matthew Jacob on changes you wish to make here.
   29  */
   30 /*
   31  * Qlogic ISP Host Adapter Public Target Interface Structures && Routines
   32  *---------------------------------------
   33  * Copyright (c) 2000 by Matthew Jacob
   34  * All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions, and the following disclaimer,
   41  *    without modification, immediately at the beginning of the file.
   42  * 2. The name of the author may not be used to endorse or promote products
   43  *    derived from this software without specific prior written permission.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   49  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  * 
   57  * Matthew Jacob
   58  * Feral Software
   59  * mjacob@feral.com
   60  */
   61 
   62 /*
   63  * Required software target mode message and event handling structures.
   64  *
   65  * The message and event structures are used by the MI layer
   66  * to propagate messages and events upstream.
   67  */
   68 
   69 #ifndef IN_MSGLEN
   70 #define IN_MSGLEN       8
   71 #endif
   72 typedef struct {
   73         void *          nt_hba;                 /* HBA tag */
   74         u_int64_t       nt_iid;                 /* inititator id */
   75         u_int64_t       nt_tgt;                 /* target id */
   76         u_int64_t       nt_lun;                 /* logical unit */
   77         u_int32_t       nt_tagval;              /* tag value */
   78         u_int8_t        nt_bus;                 /* bus */
   79         u_int8_t        nt_tagtype;             /* tag type */
   80         u_int8_t        nt_msg[IN_MSGLEN];      /* message content */
   81 } tmd_msg_t;
   82 
   83 typedef struct {
   84         void *          ev_hba;                 /* HBA tag */
   85         u_int32_t       ev_bus;                 /* bus */
   86         u_int32_t       ev_event;               /* type of async event */
   87 } tmd_event_t;
   88 
   89 /*
   90  * Suggested Software Target Mode Command Handling structure.
   91  *
   92  * A note about terminology:
   93  *
   94  *   MD stands for "Machine Dependent".
   95  *
   96  *    This driver is structured in three layers: Outer MD, core, and inner MD.
   97  *    The latter also is bus dependent (i.e., is cognizant of PCI bus issues
   98  *    as well as platform issues).
   99  *
  100  *
  101  *   "Outer Layer" means "Other Module"
  102  *
  103  *    Some additional module that actually implements SCSI target command
  104  *    policy is the recipient of incoming commands and the source of the
  105  *    disposition for them.
  106  *
  107  * The command structure below is one suggested possible MD command structure,
  108  * but since the handling of thbis is entirely in the MD layer, there is
  109  * no explicit or implicit requirement that it be used.
  110  *
  111  * The cd_private tag should be used by the MD layer to keep a free list
  112  * of these structures. Code outside of this driver can then use this
  113  * to identify it's own unit structures. That is, when not on the MD
  114  * layer's freelist, the MD layer should shove into it the identifier
  115  * that the outer layer has for it- passed in on an initial QIN_HBA_REG
  116  * call (see below).
  117  *
  118  * The cd_hba tag is a tag that uniquely identifies the HBA this target
  119  * mode command is coming from. The outer layer has to pass this back
  120  * unchanged to avoid chaos.
  121  *
  122  * The cd_iid, cd_tgt, cd_lun and cd_bus tags are used to identify the
  123  * id of the initiator who sent us a command, the target claim to be, the
  124  * lun on the target we claim to be, and the bus instance (for multiple
  125  * bus host adapters) that this applies to (consider it an extra Port
  126  * parameter). The iid, tgt and lun values are deliberately chosen to be
  127  * fat so that, for example, World Wide Names can be used instead of
  128  * the units that the Qlogic firmware uses (in the case where the MD
  129  * layer maintains a port database, for example).
  130  *
  131  * The cd_tagtype field specifies what kind of command tag has been
  132  * sent with the command. The cd_tagval is the tag's value (low 16
  133  * bits). It also contains (in the upper 16 bits) any command handle.
  134  *
  135  *
  136  * N.B.: when the MD layer sends this command to outside software
  137  * the outside software likely *MUST* return the same cd_tagval that
  138  * was in place because this value is likely what the Qlogic f/w uses
  139  * to identify a command.
  140  *
  141  * The cd_cdb contains storage for the passed in command descriptor block.
  142  * This is the maximum size we can get out of the Qlogic f/w. There's no
  143  * passed in length because whoever decodes the command to act upon it
  144  * will know what the appropriate length is.
  145  *
  146  * The tag cd_lflags are the flags set by the MD driver when it gets
  147  * command incoming or when it needs to inform any outside entities
  148  * that the last requested action failed.
  149  *
  150  * The tag cd_hflags should be set by any outside software to indicate
  151  * the validity of sense and status fields (defined below) and to indicate
  152  * the direction data is expected to move. It is an error to have both
  153  * CDFH_DATA_IN and CDFH_DATA_OUT set.
  154  *
  155  * If the CDFH_STSVALID flag is set, the command should be completed (after
  156  * sending any data and/or status). If CDFH_SNSVALID is set and the MD layer
  157  * can also handle sending the associated sense data (either back with an
  158  * FCP RESPONSE IU for Fibre Channel or otherwise automatically handling a
  159  * REQUEST SENSE from the initator for this target/lun), the MD layer will
  160  * set the CDFL_SENTSENSE flag on successful transmission of the sense data.
  161  * It is an error for the CDFH_SNSVALID bit to be set and CDFH_STSVALID not
  162  * to be set. It is an error for the CDFH_SNSVALID be set and the associated
  163  * SCSI status (cd_scsi_status) not be set to CHECK CONDITON.
  164  * 
  165  * The tag cd_data points to a data segment to either be filled or
  166  * read from depending on the direction of data movement. The tag
  167  * is undefined if no data direction is set. The MD layer and outer
  168  * layers must agree on the meaning of cd_data.
  169  *
  170  * The tag cd_totlen is the total data amount expected to be moved
  171  * over the life of the command. It *may* be set by the MD layer, possibly
  172  * from the datalen field of an FCP CMND IU unit. If it shows up in the outer
  173  * layers set to zero and the CDB indicates data should be moved, the outer
  174  * layer should set it to the amount expected to be moved.
  175  *
  176  * The tag cd_resid should be the total residual of data not transferred.
  177  * The outer layers need to set this at the beginning of command processing
  178  * to equal cd_totlen. As data is successfully moved, this value is decreased.
  179  * At the end of a command, any nonzero residual indicates the number of bytes
  180  * requested but not moved. XXXXXXXXXXXXXXXXXXXXXXX TOO VAGUE!!! 
  181  *
  182  * The tag cd_xfrlen is the length of the currently active data transfer.
  183  * This allows several interations between any outside software and the
  184  * MD layer to move data.
  185  *
  186  * The reason that total length and total residual have to be tracked
  187  * is that fibre channel FCP DATA IU units have to have a relative
  188  * offset field.
  189  *
  190  * N.B.: there is no necessary 1-to-1 correspondence between any one
  191  * data transfer segment and the number of CTIOs that will be generated
  192  * satisfy the current data transfer segment. It's not also possible to
  193  * predict how big a transfer can be before it will be 'too big'. Be
  194  * reasonable- a 64KB transfer is 'reasonable'. A 1MB transfer may not
  195  * be. A 32MB transfer is unreasonable. The problem here has to do with
  196  * how CTIOs can be used to map passed data pointers. In systems which
  197  * have page based scatter-gather requirements, each PAGESIZEd chunk will
  198  * consume one data segment descriptor- you get 3 or 4 of them per CTIO.
  199  * The size of the REQUEST QUEUE you drop a CTIO onto is finite (typically
  200  * it's 256, but on some systems it's even smaller, and note you have to
  201  * sure this queue with the initiator side of this driver).
  202  *
  203  * The tags cd_sense and cd_scsi_status are pretty obvious.
  204  *
  205  * The tag cd_error is to communicate between the MD layer and outer software
  206  * the current error conditions.
  207  *
  208  * The tag cd_lreserved, cd_hreserved are scratch areas for use for the MD
  209  * and outer layers respectively.
  210  * 
  211  */
  212 
  213 #ifndef TMD_CDBLEN
  214 #define TMD_CDBLEN      16
  215 #endif
  216 #ifndef TMD_SENSELEN
  217 #define TMD_SENSELEN    24
  218 #endif
  219 #ifndef QCDS
  220 #define QCDS    8
  221 #endif
  222 
  223 typedef struct tmd_cmd {
  224         void *                  cd_private;     /* private data pointer */
  225         void *                  cd_hba;         /* HBA tag */
  226         void *                  cd_data;        /* 'pointer' to data */
  227         u_int64_t               cd_iid;         /* initiator ID */
  228         u_int64_t               cd_tgt;         /* target id */
  229         u_int64_t               cd_lun;         /* logical unit */
  230         u_int32_t               cd_tagval;      /* tag value */
  231         u_int32_t               cd_lflags;      /* flags lower level sets */
  232         u_int32_t               cd_hflags;      /* flags higher level sets */
  233         u_int32_t               cd_totlen;      /* total data requirement */
  234         u_int32_t               cd_resid;       /* total data residual */
  235         u_int32_t               cd_xfrlen;      /* current data requirement */
  236         int32_t                 cd_error;       /* current error */
  237         u_int32_t
  238                 cd_scsi_status  : 16,   /* closing SCSI status */
  239                                 : 7,
  240                 cd_chan         : 1,    /* channel on card */
  241                                 : 2,
  242                 cd_tagtype      : 6;    /* tag type */
  243         u_int8_t                cd_senselen;
  244         u_int8_t                cd_cdblen;
  245         u_int8_t                cd_sense[TMD_SENSELEN];
  246         u_int8_t                cd_cdb[TMD_CDBLEN];     /* Command */
  247         union {
  248                 void *          ptrs[QCDS / sizeof (void *)];
  249                 u_int64_t       llongs[QCDS / sizeof (u_int64_t)];
  250                 u_int32_t       longs[QCDS / sizeof (u_int32_t)];
  251                 u_int16_t       shorts[QCDS / sizeof (u_int16_t)];
  252                 u_int8_t        bytes[QCDS];
  253         } cd_lreserved[2], cd_hreserved[2];
  254 } tmd_cmd_t;
  255 
  256 #ifndef TMD_SIZE
  257 #define TMD_SIZE        (sizeof (tmd_cmd_t))
  258 #endif
  259 
  260 /*
  261  * Note that NODISC (obviously) doesn't apply to non-SPI transport.
  262  *
  263  * Note that knowing the data direction and lengh at the time of receipt of
  264  * a command from the initiator is a feature only of Fibre Channel.
  265  *
  266  * The CDFL_BIDIR is in anticipation of the adoption of some newer
  267  * features required by OSD.
  268  *
  269  * The principle selector for MD layer to know whether data is to
  270  * be transferred in any QOUT_TMD_CONT call is cd_xfrlen- the
  271  * flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction.
  272  */
  273 #define CDFL_SNSVALID   0x01            /* sense data (from f/w) good */
  274 #define CDFL_SENTSTATUS 0x02            /* last action sent status */
  275 #define CDFL_DATA_IN    0x04            /* target (us) -> initiator (them) */
  276 #define CDFL_DATA_OUT   0x08            /* initiator (them) -> target (us) */
  277 #define CDFL_BIDIR      0x0C            /* bidirectional data */
  278 #define CDFL_ERROR      0x10            /* last action ended in error */
  279 #define CDFL_NODISC     0x20            /* disconnects disabled */
  280 #define CDFL_SENTSENSE  0x40            /* last action sent sense data */
  281 #define CDFL_BUSY       0x80            /* this command is not on a free list */
  282 #define CDFL_PRIVATE    0xFF000000      /* private layer flags */
  283 
  284 #define CDFH_SNSVALID   0x01            /* sense data (from outer layer) good */
  285 #define CDFH_STSVALID   0x02            /* status valid */
  286 #define CDFH_DATA_IN    0x04            /* target (us) -> initiator (them) */
  287 #define CDFH_DATA_OUT   0x08            /* initiator (them) -> target (us) */
  288 #define CDFH_DATA_MASK  0x0C            /* mask to cover data direction */
  289 #define CDFH_PRIVATE    0xFF000000      /* private layer flags */
  290 
  291 
  292 /*
  293  * Action codes set by the Qlogic MD target driver for
  294  * the external layer to figure out what to do with.
  295  */
  296 typedef enum {
  297         QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */
  298         QOUT_ENABLE,    /* the argument is a pointer to a enadis_t */
  299         QOUT_DISABLE,   /* the argument is a pointer to a enadis_t */
  300         QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
  301         QOUT_TMD_DONE,  /* the argument is a pointer to a tmd_cmd_t */
  302         QOUT_TEVENT,    /* the argument is a pointer to a tmd_event_t */
  303         QOUT_TMSG,      /* the argument is a pointer to a tmd_msg_t */
  304         QOUT_IOCTL,     /* the argument is a pointer to a ioctl_cmd_t */
  305         QOUT_HBA_UNREG  /* the argument is a pointer to a hba_register_t */
  306 } tact_e;
  307 
  308 /*
  309  * Action codes set by the external layer for the
  310  * MD Qlogic driver to figure out what to do with.
  311  */
  312 typedef enum {
  313         QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */
  314         QIN_ENABLE,     /* the argument is a pointer to a enadis_t */
  315         QIN_DISABLE,    /* the argument is a pointer to a enadis_t */
  316         QIN_TMD_CONT,   /* the argument is a pointer to a tmd_cmd_t */
  317         QIN_TMD_FIN,    /* the argument is a pointer to a tmd_cmd_t */
  318         QIN_IOCTL,      /* the argument is a pointer to a ioctl_cmd_t */
  319         QIN_HBA_UNREG,  /* the argument is a pointer to a hba_register_t */
  320 } qact_e;
  321 
  322 
  323 /*
  324  * A word about the START/CONT/DONE/FIN dance:
  325  *
  326  *      When the HBA is enabled for receiving commands, one may show up
  327  *      without notice. When that happens, the Qlogic target mode driver
  328  *      gets a tmd_cmd_t, fills it with the info that just arrived, and
  329  *      calls the outer layer with a QOUT_TMD_START code and pointer to
  330  *      the tmd_cmd_t.
  331  *
  332  *      The outer layer decodes the command, fetches data, prepares stuff,
  333  *      whatever, and starts by passing back the pointer with a QIN_TMD_CONT
  334  *      code which causes the Qlogic target mode driver to generate CTIOs to
  335  *      satisfy whatever action needs to be taken. When those CTIOs complete,
  336  *      the Qlogic target driver sends the pointer to the cmd_tmd_t back with
  337  *      a QOUT_TMD_DONE code. This repeats for as long as necessary.
  338  *
  339  *      The outer layer signals it wants to end the command by settings within
  340  *      the tmd_cmd_t itself. When the final QIN_TMD_CONT is reported completed,
  341  *      the outer layer frees the tmd_cmd_t by sending the pointer to it
  342  *      back with a QIN_TMD_FIN code.
  343  *
  344  *      The graph looks like:
  345  *
  346  *      QOUT_TMD_START -> [ QIN_TMD_CONT -> QOUT_TMD_DONE ] * -> QIN_TMD_FIN.
  347  *
  348  */
  349 
  350 /*
  351  * A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
  352  * with cd_hba, cd_iid, cd_chan, cd_tgt and cd_lun filled out.
  353  *
  354  * If an error occurs in either enabling or disabling the described lun
  355  * cd_error is set with an appropriate non-zero value.
  356  *
  357  * Logical unit zero must be the first enabled and the last disabled.
  358  */
  359 typedef struct {
  360         void *                  cd_private;     /* for outer layer usage */
  361         void *                  cd_hba;         /* HBA tag */
  362         u_int64_t               cd_iid;         /* initiator ID */
  363         u_int64_t               cd_tgt;         /* target id */
  364         u_int64_t               cd_lun;         /* logical unit */
  365         u_int8_t                cd_chan;        /* channel on card */
  366         int32_t                 cd_error;
  367 } enadis_t;
  368 
  369 /*
  370  * This structure is used to register to other software modules the
  371  * binding of an HBA identifier, driver name and instance and the
  372  * lun width capabilities of this target driver. It's up to each
  373  * platform to figure out how it wants to do this, but a typical
  374  * sequence would be for the MD layer to find some external module's
  375  * entry point and start by sending a QOUT_HBA_REG with info filled
  376  * in, and the external module to call back with a QIN_HBA_REG that
  377  * passes back the corresponding information.
  378  */
  379 #define QR_VERSION      1
  380 typedef struct {
  381         void *  r_identity;
  382         void   (*r_action)(qact_e, void *);
  383         char    r_name[8];
  384         int     r_inst;
  385         int     r_version;
  386         enum { R_FC, R_SCSI } r_type;
  387 } hba_register_t;
  388 
  389 /*
  390  * This structure is used to pass an encapsulated ioctl through to the
  391  * MD layer. In many implementations it's often convenient to open just
  392  * one device, but actions you want to take need to be taken on the
  393  * underlying HBA. Rather than invent a separate protocol for each action,
  394  * an ioctl passthrough seems simpler.
  395  *
  396  * In order to avoid cross domain copy problems, though, the caller will
  397  * be responsible for allocating and providing a staging area for all ioctl
  398  * related data. This, unavoidably, requires some ioctl decode capability
  399  * in the outer layer code.`
  400  *
  401  * And also, albeit being cheesy, we'll define a few internal ioctls here.
  402  */
  403 typedef struct {
  404         void *  i_identity;     /* HBA tag */
  405         void *  i_syncptr;      /* synchronization pointer */
  406         int     i_cmd;          /* ioctl command */
  407         void *  i_arg;          /* ioctl argument area */
  408         int     i_errno;        /* ioctl error return */
  409 } ioctl_cmd_t;
  410 
  411 #define QI_IOC  ('Q' << 8)
  412 #define QI_SCSI_TINI    QI_IOC|0
  413 #define QI_SCSI_CMD     QI_IOC|1
  414 #define QI_WWPN_XLT     QI_IOC|2
  415 
  416 /*
  417  * Target handler functions.
  418  *
  419  * The MD target handler function (the outer layer calls this)
  420  * should be be prototyped like:
  421  *
  422  *      void target_action(qact_e, void *arg)
  423  *
  424  * The outer layer target handler function (the MD layer calls this)
  425  * should be be prototyped like:
  426  *
  427  *      void system_target_handler(tact_e, void *arg)
  428  */
  429 

Cache object: 00394b66d5f0065a69d7ae087c00f10c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.