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/mps/mpsvar.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 /*-
    2  * Copyright (c) 2009 Yahoo! Inc.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  * 
   26  * $FreeBSD: releng/9.0/sys/dev/mps/mpsvar.h 219036 2011-02-25 17:30:25Z ken $
   27  */
   28 
   29 #ifndef _MPSVAR_H
   30 #define _MPSVAR_H
   31 
   32 #define MPS_DB_MAX_WAIT         2500
   33 
   34 #define MPS_REQ_FRAMES          1024
   35 #define MPS_EVT_REPLY_FRAMES    32
   36 #define MPS_REPLY_FRAMES        MPS_REQ_FRAMES
   37 #define MPS_CHAIN_FRAMES        2048
   38 #define MPS_SENSE_LEN           SSD_FULL_SIZE
   39 #define MPS_MSI_COUNT           1
   40 #define MPS_SGE64_SIZE          12
   41 #define MPS_SGE32_SIZE          8
   42 #define MPS_SGC_SIZE            8
   43 
   44 #define MPS_PERIODIC_DELAY      1       /* 1 second heartbeat/watchdog check */
   45 
   46 struct mps_softc;
   47 struct mps_command;
   48 struct mpssas_softc;
   49 struct mpssas_target;
   50 
   51 MALLOC_DECLARE(M_MPT2);
   52 
   53 typedef void mps_evt_callback_t(struct mps_softc *, uintptr_t,
   54     MPI2_EVENT_NOTIFICATION_REPLY *reply);
   55 typedef void mps_command_callback_t(struct mps_softc *, struct mps_command *cm);
   56 
   57 struct mps_chain {
   58         TAILQ_ENTRY(mps_chain)          chain_link;
   59         MPI2_SGE_IO_UNION               *chain;
   60         uint32_t                        chain_busaddr;
   61 };
   62 
   63 /*
   64  * This needs to be at least 2 to support SMP passthrough.
   65  */
   66 #define MPS_IOVEC_COUNT 2
   67 
   68 struct mps_command {
   69         TAILQ_ENTRY(mps_command)        cm_link;
   70         struct mps_softc                *cm_sc;
   71         void                            *cm_data;
   72         u_int                           cm_length;
   73         struct uio                      cm_uio;
   74         struct iovec                    cm_iovec[MPS_IOVEC_COUNT];
   75         u_int                           cm_max_segs;
   76         u_int                           cm_sglsize;
   77         MPI2_SGE_IO_UNION               *cm_sge;
   78         uint8_t                         *cm_req;
   79         uint8_t                         *cm_reply;
   80         uint32_t                        cm_reply_data;
   81         mps_command_callback_t          *cm_complete;
   82         void                            *cm_complete_data;
   83         struct mpssas_target            *cm_targ;
   84         MPI2_REQUEST_DESCRIPTOR_UNION   cm_desc;
   85         u_int                           cm_flags;
   86 #define MPS_CM_FLAGS_POLLED             (1 << 0)
   87 #define MPS_CM_FLAGS_COMPLETE           (1 << 1)
   88 #define MPS_CM_FLAGS_SGE_SIMPLE         (1 << 2)
   89 #define MPS_CM_FLAGS_DATAOUT            (1 << 3)
   90 #define MPS_CM_FLAGS_DATAIN             (1 << 4)
   91 #define MPS_CM_FLAGS_WAKEUP             (1 << 5)
   92 #define MPS_CM_FLAGS_ACTIVE             (1 << 6)
   93 #define MPS_CM_FLAGS_USE_UIO            (1 << 7)
   94 #define MPS_CM_FLAGS_SMP_PASS           (1 << 8)
   95 #define MPS_CM_FLAGS_CHAIN_FAILED       (1 << 9)
   96 #define MPS_CM_FLAGS_ERROR_MASK         MPS_CM_FLAGS_CHAIN_FAILED
   97         u_int                           cm_state;
   98 #define MPS_CM_STATE_FREE               0
   99 #define MPS_CM_STATE_BUSY               1
  100 #define MPS_CM_STATE_TIMEDOUT           2
  101         bus_dmamap_t                    cm_dmamap;
  102         struct scsi_sense_data          *cm_sense;
  103         TAILQ_HEAD(, mps_chain)         cm_chain_list;
  104         uint32_t                        cm_req_busaddr;
  105         uint32_t                        cm_sense_busaddr;
  106         struct callout                  cm_callout;
  107 };
  108 
  109 struct mps_event_handle {
  110         TAILQ_ENTRY(mps_event_handle)   eh_list;
  111         mps_evt_callback_t              *callback;
  112         void                            *data;
  113         uint8_t                         mask[16];
  114 };
  115 
  116 struct mps_softc {
  117         device_t                        mps_dev;
  118         struct cdev                     *mps_cdev;
  119         u_int                           mps_flags;
  120 #define MPS_FLAGS_INTX          (1 << 0)
  121 #define MPS_FLAGS_MSI           (1 << 1)
  122 #define MPS_FLAGS_BUSY          (1 << 2)
  123 #define MPS_FLAGS_SHUTDOWN      (1 << 3)
  124 #define MPS_FLAGS_ATTACH_DONE   (1 << 4)
  125         u_int                           mps_debug;
  126         u_int                           allow_multiple_tm_cmds;
  127         int                             tm_cmds_active;
  128         int                             io_cmds_active;
  129         int                             io_cmds_highwater;
  130         int                             chain_free;
  131         int                             chain_free_lowwater;
  132         uint64_t                        chain_alloc_fail;
  133         struct sysctl_ctx_list          sysctl_ctx;
  134         struct sysctl_oid               *sysctl_tree;
  135         struct mps_command              *commands;
  136         struct mps_chain                *chains;
  137         struct callout                  periodic;
  138 
  139         struct mpssas_softc             *sassc;
  140 
  141         TAILQ_HEAD(, mps_command)       req_list;
  142         TAILQ_HEAD(, mps_chain)         chain_list;
  143         TAILQ_HEAD(, mps_command)       tm_list;
  144         TAILQ_HEAD(, mps_command)       io_list;
  145         int                             replypostindex;
  146         int                             replyfreeindex;
  147 
  148         struct resource                 *mps_regs_resource;
  149         bus_space_handle_t              mps_bhandle;
  150         bus_space_tag_t                 mps_btag;
  151         int                             mps_regs_rid;
  152 
  153         bus_dma_tag_t                   mps_parent_dmat;
  154         bus_dma_tag_t                   buffer_dmat;
  155 
  156         MPI2_IOC_FACTS_REPLY            *facts;
  157         MPI2_PORT_FACTS_REPLY           *pfacts;
  158         int                             num_reqs;
  159         int                             num_replies;
  160         int                             fqdepth;        /* Free queue */
  161         int                             pqdepth;        /* Post queue */
  162 
  163         uint8_t                         event_mask[16];
  164         TAILQ_HEAD(, mps_event_handle)  event_list;
  165         struct mps_event_handle         *mps_log_eh;
  166 
  167         struct mtx                      mps_mtx;
  168         struct intr_config_hook         mps_ich;
  169         struct resource                 *mps_irq[MPS_MSI_COUNT];
  170         void                            *mps_intrhand[MPS_MSI_COUNT];
  171         int                             mps_irq_rid[MPS_MSI_COUNT];
  172 
  173         uint8_t                         *req_frames;
  174         bus_addr_t                      req_busaddr;
  175         bus_dma_tag_t                   req_dmat;
  176         bus_dmamap_t                    req_map;
  177 
  178         uint8_t                         *reply_frames;
  179         bus_addr_t                      reply_busaddr;
  180         bus_dma_tag_t                   reply_dmat;
  181         bus_dmamap_t                    reply_map;
  182 
  183         struct scsi_sense_data          *sense_frames;
  184         bus_addr_t                      sense_busaddr;
  185         bus_dma_tag_t                   sense_dmat;
  186         bus_dmamap_t                    sense_map;
  187 
  188         uint8_t                         *chain_frames;
  189         bus_addr_t                      chain_busaddr;
  190         bus_dma_tag_t                   chain_dmat;
  191         bus_dmamap_t                    chain_map;
  192 
  193         MPI2_REPLY_DESCRIPTORS_UNION    *post_queue;
  194         bus_addr_t                      post_busaddr;
  195         uint32_t                        *free_queue;
  196         bus_addr_t                      free_busaddr;
  197         bus_dma_tag_t                   queues_dmat;
  198         bus_dmamap_t                    queues_map;
  199 };
  200 
  201 struct mps_config_params {
  202         MPI2_CONFIG_EXT_PAGE_HEADER_UNION       hdr;
  203         u_int           action;
  204         u_int           page_address;   /* Attributes, not a phys address */
  205         u_int           status;
  206         void            *buffer;
  207         u_int           length;
  208         int             timeout;
  209         void            (*callback)(struct mps_softc *, struct mps_config_params *);
  210         void            *cbdata;
  211 };
  212 
  213 static __inline uint32_t
  214 mps_regread(struct mps_softc *sc, uint32_t offset)
  215 {
  216         return (bus_space_read_4(sc->mps_btag, sc->mps_bhandle, offset));
  217 }
  218 
  219 static __inline void
  220 mps_regwrite(struct mps_softc *sc, uint32_t offset, uint32_t val)
  221 {
  222         bus_space_write_4(sc->mps_btag, sc->mps_bhandle, offset, val);
  223 }
  224 
  225 static __inline void
  226 mps_free_reply(struct mps_softc *sc, uint32_t busaddr)
  227 {
  228 
  229         if (++sc->replyfreeindex >= sc->fqdepth)
  230                 sc->replyfreeindex = 0;
  231         sc->free_queue[sc->replyfreeindex] = busaddr;
  232         mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex);
  233 }
  234 
  235 static __inline struct mps_chain *
  236 mps_alloc_chain(struct mps_softc *sc)
  237 {
  238         struct mps_chain *chain;
  239 
  240         if ((chain = TAILQ_FIRST(&sc->chain_list)) != NULL) {
  241                 TAILQ_REMOVE(&sc->chain_list, chain, chain_link);
  242                 sc->chain_free--;
  243                 if (sc->chain_free < sc->chain_free_lowwater)
  244                         sc->chain_free_lowwater = sc->chain_free;
  245         } else
  246                 sc->chain_alloc_fail++;
  247         return (chain);
  248 }
  249 
  250 static __inline void
  251 mps_free_chain(struct mps_softc *sc, struct mps_chain *chain)
  252 {
  253 #if 0
  254         bzero(chain->chain, 128);
  255 #endif
  256         sc->chain_free++;
  257         TAILQ_INSERT_TAIL(&sc->chain_list, chain, chain_link);
  258 }
  259 
  260 static __inline void
  261 mps_free_command(struct mps_softc *sc, struct mps_command *cm)
  262 {
  263         struct mps_chain *chain, *chain_temp;
  264 
  265         if (cm->cm_reply != NULL) {
  266                 mps_free_reply(sc, cm->cm_reply_data);
  267                 cm->cm_reply = NULL;
  268         }
  269         cm->cm_flags = 0;
  270         cm->cm_complete = NULL;
  271         cm->cm_complete_data = NULL;
  272         cm->cm_targ = 0;
  273         cm->cm_max_segs = 0;
  274         cm->cm_state = MPS_CM_STATE_FREE;
  275         TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, chain_temp) {
  276                 TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
  277                 mps_free_chain(sc, chain);
  278         }
  279         TAILQ_INSERT_TAIL(&sc->req_list, cm, cm_link);
  280 }
  281 
  282 static __inline struct mps_command *
  283 mps_alloc_command(struct mps_softc *sc)
  284 {
  285         struct mps_command *cm;
  286 
  287         cm = TAILQ_FIRST(&sc->req_list);
  288         if (cm == NULL)
  289                 return (NULL);
  290 
  291         TAILQ_REMOVE(&sc->req_list, cm, cm_link);
  292         KASSERT(cm->cm_state == MPS_CM_STATE_FREE, ("mps: Allocating busy command\n"));
  293         cm->cm_state = MPS_CM_STATE_BUSY;
  294         return (cm);
  295 }
  296 
  297 static __inline void
  298 mps_lock(struct mps_softc *sc)
  299 {
  300         mtx_lock(&sc->mps_mtx);
  301 }
  302 
  303 static __inline void
  304 mps_unlock(struct mps_softc *sc)
  305 {
  306         mtx_unlock(&sc->mps_mtx);
  307 }
  308 
  309 #define MPS_INFO        (1 << 0)
  310 #define MPS_TRACE       (1 << 1)
  311 #define MPS_FAULT       (1 << 2)
  312 #define MPS_EVENT       (1 << 3)
  313 #define MPS_LOG         (1 << 4)
  314 
  315 #define mps_printf(sc, args...)                         \
  316         device_printf((sc)->mps_dev, ##args)
  317 
  318 #define mps_dprint(sc, level, msg, args...)             \
  319 do {                                                    \
  320         if (sc->mps_debug & level)                      \
  321                 device_printf(sc->mps_dev, msg, ##args);        \
  322 } while (0)
  323 
  324 #define mps_dprint_field(sc, level, msg, args...)               \
  325 do {                                                            \
  326         if (sc->mps_debug & level)                              \
  327                 printf("\t" msg, ##args);                       \
  328 } while (0)
  329 
  330 #define MPS_PRINTFIELD_START(sc, tag...)        \
  331         mps_dprint((sc), MPS_INFO, ##tag);      \
  332         mps_dprint_field((sc), MPS_INFO, ":\n")
  333 #define MPS_PRINTFIELD_END(sc, tag)             \
  334         mps_dprint((sc), MPS_INFO, tag "\n")
  335 #define MPS_PRINTFIELD(sc, facts, attr, fmt)    \
  336         mps_dprint_field((sc), MPS_INFO, #attr ": " #fmt "\n", (facts)->attr)
  337 
  338 #define MPS_EVENTFIELD_START(sc, tag...)        \
  339         mps_dprint((sc), MPS_EVENT, ##tag);     \
  340         mps_dprint_field((sc), MPS_EVENT, ":\n")
  341 #define MPS_EVENTFIELD(sc, facts, attr, fmt)    \
  342         mps_dprint_field((sc), MPS_EVENT, #attr ": " #fmt "\n", (facts)->attr)
  343 
  344 static __inline void
  345 mps_from_u64(uint64_t data, U64 *mps)
  346 {
  347         (mps)->High = (uint32_t)((data) >> 32);
  348         (mps)->Low = (uint32_t)((data) & 0xffffffff);
  349 }
  350 
  351 static __inline uint64_t
  352 mps_to_u64(U64 *data)
  353 {
  354 
  355         return (((uint64_t)data->High << 32) | data->Low);
  356 }
  357 
  358 static __inline void
  359 mps_mask_intr(struct mps_softc *sc)
  360 {
  361         uint32_t mask;
  362 
  363         mask = mps_regread(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET);
  364         mask |= MPI2_HIM_REPLY_INT_MASK;
  365         mps_regwrite(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET, mask);
  366 }
  367 
  368 static __inline void
  369 mps_unmask_intr(struct mps_softc *sc)
  370 {
  371         uint32_t mask;
  372 
  373         mask = mps_regread(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET);
  374         mask &= ~MPI2_HIM_REPLY_INT_MASK;
  375         mps_regwrite(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET, mask);
  376 }
  377 
  378 int mps_pci_setup_interrupts(struct mps_softc *);
  379 int mps_attach(struct mps_softc *sc);
  380 int mps_free(struct mps_softc *sc);
  381 void mps_intr(void *);
  382 void mps_intr_msi(void *);
  383 void mps_intr_locked(void *);
  384 int mps_register_events(struct mps_softc *, uint8_t *, mps_evt_callback_t *,
  385     void *, struct mps_event_handle **);
  386 int mps_update_events(struct mps_softc *, struct mps_event_handle *, uint8_t *);
  387 int mps_deregister_events(struct mps_softc *, struct mps_event_handle *);
  388 int mps_request_polled(struct mps_softc *sc, struct mps_command *cm);
  389 void mps_enqueue_request(struct mps_softc *, struct mps_command *);
  390 int mps_push_sge(struct mps_command *, void *, size_t, int);
  391 int mps_add_dmaseg(struct mps_command *, vm_paddr_t, size_t, u_int, int);
  392 int mps_attach_sas(struct mps_softc *sc);
  393 int mps_detach_sas(struct mps_softc *sc);
  394 int mps_map_command(struct mps_softc *sc, struct mps_command *cm);
  395 int mps_read_config_page(struct mps_softc *, struct mps_config_params *);
  396 int mps_write_config_page(struct mps_softc *, struct mps_config_params *);
  397 void mps_memaddr_cb(void *, bus_dma_segment_t *, int , int );
  398 void mpi_init_sge(struct mps_command *cm, void *req, void *sge);
  399 int mps_attach_user(struct mps_softc *);
  400 void mps_detach_user(struct mps_softc *);
  401 
  402 SYSCTL_DECL(_hw_mps);
  403 
  404 #endif
  405 

Cache object: d024dd2d77ebe7592cb2d93d519235ee


[ 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.