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  * Copyright (c) 2011, 2012 LSI Corp.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * LSI MPT-Fusion Host Adapter FreeBSD
   28  *
   29  * $FreeBSD: releng/8.4/sys/dev/mps/mpsvar.h 237877 2012-07-01 05:23:59Z ken $
   30  */
   31 
   32 #ifndef _MPSVAR_H
   33 #define _MPSVAR_H
   34 
   35 #define MPS_DRIVER_VERSION      "14.00.00.01-fbsd"
   36 
   37 #define MPS_DB_MAX_WAIT         2500
   38 
   39 #define MPS_REQ_FRAMES          1024
   40 #define MPS_EVT_REPLY_FRAMES    32
   41 #define MPS_REPLY_FRAMES        MPS_REQ_FRAMES
   42 #define MPS_CHAIN_FRAMES        2048
   43 #define MPS_SENSE_LEN           SSD_FULL_SIZE
   44 #define MPS_MSI_COUNT           1
   45 #define MPS_SGE64_SIZE          12
   46 #define MPS_SGE32_SIZE          8
   47 #define MPS_SGC_SIZE            8
   48 
   49 #define  CAN_SLEEP                      1
   50 #define  NO_SLEEP                       0
   51 
   52 #define MPS_PERIODIC_DELAY      1       /* 1 second heartbeat/watchdog check */
   53 
   54 #define MPS_SCSI_RI_INVALID_FRAME       (0x00000002)
   55 #define MPS_STRING_LENGTH               64
   56 
   57 #include <sys/endian.h>
   58 
   59 /*
   60  * host mapping related macro definitions
   61  */
   62 #define MPS_MAPTABLE_BAD_IDX    0xFFFFFFFF
   63 #define MPS_DPM_BAD_IDX         0xFFFF
   64 #define MPS_ENCTABLE_BAD_IDX    0xFF
   65 #define MPS_MAX_MISSING_COUNT   0x0F
   66 #define MPS_DEV_RESERVED        0x20000000
   67 #define MPS_MAP_IN_USE          0x10000000
   68 #define MPS_RAID_CHANNEL        1
   69 #define MPS_MAP_BAD_ID          0xFFFFFFFF
   70 
   71 /*
   72  * WarpDrive controller
   73  */
   74 #define MPS_CHIP_WD_DEVICE_ID   0x007E
   75 #define MPS_WD_LSI_OEM          0x80
   76 #define MPS_WD_HIDE_EXPOSE_MASK 0x03
   77 #define MPS_WD_HIDE_ALWAYS      0x00
   78 #define MPS_WD_EXPOSE_ALWAYS    0x01
   79 #define MPS_WD_HIDE_IF_VOLUME   0x02
   80 #define MPS_WD_RETRY            0x01
   81 #define MPS_MAN_PAGE10_SIZE     0x5C    /* Hardcode for now */
   82 #define MPS_MAX_DISKS_IN_VOL    10
   83 
   84 /*
   85  * WarpDrive Event Logging
   86  */
   87 #define MPI2_WD_LOG_ENTRY       0x8002
   88 #define MPI2_WD_SSD_THROTTLING  0x0041
   89 #define MPI2_WD_DRIVE_LIFE_WARN 0x0043
   90 #define MPI2_WD_DRIVE_LIFE_DEAD 0x0044
   91 #define MPI2_WD_RAIL_MON_FAIL   0x004D
   92 
   93 typedef uint8_t u8;
   94 typedef uint16_t u16;
   95 typedef uint32_t u32;
   96 typedef uint64_t u64;
   97 
   98 /**
   99  * struct dev_mapping_table - device mapping information
  100  * @physical_id: SAS address for drives or WWID for RAID volumes
  101  * @device_info: bitfield provides detailed info about the device
  102  * @phy_bits: bitfields indicating controller phys
  103  * @dpm_entry_num: index of this device in device persistent map table
  104  * @dev_handle: device handle for the device pointed by this entry
  105  * @channel: target channel
  106  * @id: target id
  107  * @missing_count: number of times the device not detected by driver
  108  * @hide_flag: Hide this physical disk/not (foreign configuration)
  109  * @init_complete: Whether the start of the day checks completed or not
  110  */
  111 struct dev_mapping_table {
  112         u64     physical_id;
  113         u32     device_info;
  114         u32     phy_bits;
  115         u16     dpm_entry_num;
  116         u16     dev_handle;
  117         u8      reserved1;
  118         u8      channel;
  119         u16     id;
  120         u8      missing_count;
  121         u8      init_complete;
  122         u8      TLR_bits;
  123         u8      reserved2;
  124 };
  125 
  126 /**
  127  * struct enc_mapping_table -  mapping information about an enclosure
  128  * @enclosure_id: Logical ID of this enclosure
  129  * @start_index: index to the entry in dev_mapping_table
  130  * @phy_bits: bitfields indicating controller phys
  131  * @dpm_entry_num: index of this enclosure in device persistent map table
  132  * @enc_handle: device handle for the enclosure pointed by this entry
  133  * @num_slots: number of slots in the enclosure
  134  * @start_slot: Starting slot id
  135  * @missing_count: number of times the device not detected by driver
  136  * @removal_flag: used to mark the device for removal
  137  * @skip_search: used as a flag to include/exclude enclosure for search
  138  * @init_complete: Whether the start of the day checks completed or not
  139  */
  140 struct enc_mapping_table {
  141         u64     enclosure_id;
  142         u32     start_index;
  143         u32     phy_bits;
  144         u16     dpm_entry_num;
  145         u16     enc_handle;
  146         u16     num_slots;
  147         u16     start_slot;
  148         u8      missing_count;
  149         u8      removal_flag;
  150         u8      skip_search;
  151         u8      init_complete;
  152 };
  153 
  154 /**
  155  * struct map_removal_table - entries to be removed from mapping table
  156  * @dpm_entry_num: index of this device in device persistent map table
  157  * @dev_handle: device handle for the device pointed by this entry
  158  */
  159 struct map_removal_table{
  160         u16     dpm_entry_num;
  161         u16     dev_handle;
  162 };
  163 
  164 typedef struct mps_fw_diagnostic_buffer {
  165         size_t          size;
  166         uint8_t         extended_type;
  167         uint8_t         buffer_type;
  168         uint8_t         force_release;
  169         uint32_t        product_specific[23];
  170         uint8_t         immediate;
  171         uint8_t         enabled;
  172         uint8_t         valid_data;
  173         uint8_t         owned_by_firmware;
  174         uint32_t        unique_id;
  175 } mps_fw_diagnostic_buffer_t;
  176 
  177 struct mps_softc;
  178 struct mps_command;
  179 struct mpssas_softc;
  180 union ccb;
  181 struct mpssas_target;
  182 struct mps_column_map;
  183 
  184 MALLOC_DECLARE(M_MPT2);
  185 
  186 typedef void mps_evt_callback_t(struct mps_softc *, uintptr_t,
  187     MPI2_EVENT_NOTIFICATION_REPLY *reply);
  188 typedef void mps_command_callback_t(struct mps_softc *, struct mps_command *cm);
  189 
  190 struct mps_chain {
  191         TAILQ_ENTRY(mps_chain)          chain_link;
  192         MPI2_SGE_IO_UNION               *chain;
  193         uint32_t                        chain_busaddr;
  194 };
  195 
  196 /*
  197  * This needs to be at least 2 to support SMP passthrough.
  198  */
  199 #define       MPS_IOVEC_COUNT 2
  200 
  201 struct mps_command {
  202         TAILQ_ENTRY(mps_command)        cm_link;
  203         TAILQ_ENTRY(mps_command)        cm_recovery;
  204         struct mps_softc                *cm_sc;
  205         union ccb                       *cm_ccb;
  206         void                            *cm_data;
  207         u_int                           cm_length;
  208         u_int                           cm_out_len;
  209         struct uio                      cm_uio;
  210         struct iovec                    cm_iovec[MPS_IOVEC_COUNT];
  211         u_int                           cm_max_segs;
  212         u_int                           cm_sglsize;
  213         MPI2_SGE_IO_UNION               *cm_sge;
  214         uint8_t                         *cm_req;
  215         uint8_t                         *cm_reply;
  216         uint32_t                        cm_reply_data;
  217         mps_command_callback_t          *cm_complete;
  218         void                            *cm_complete_data;
  219         struct mpssas_target            *cm_targ;
  220         MPI2_REQUEST_DESCRIPTOR_UNION   cm_desc;
  221         u_int                           cm_lun;
  222         u_int                           cm_flags;
  223 #define MPS_CM_FLAGS_POLLED             (1 << 0)
  224 #define MPS_CM_FLAGS_COMPLETE           (1 << 1)
  225 #define MPS_CM_FLAGS_SGE_SIMPLE         (1 << 2)
  226 #define MPS_CM_FLAGS_DATAOUT            (1 << 3)
  227 #define MPS_CM_FLAGS_DATAIN             (1 << 4)
  228 #define MPS_CM_FLAGS_WAKEUP             (1 << 5)
  229 #define MPS_CM_FLAGS_DD_IO              (1 << 6)
  230 #define MPS_CM_FLAGS_USE_UIO            (1 << 7)
  231 #define MPS_CM_FLAGS_SMP_PASS           (1 << 8)
  232 #define MPS_CM_FLAGS_CHAIN_FAILED       (1 << 9)
  233 #define MPS_CM_FLAGS_ERROR_MASK         MPS_CM_FLAGS_CHAIN_FAILED
  234         u_int                           cm_state;
  235 #define MPS_CM_STATE_FREE               0
  236 #define MPS_CM_STATE_BUSY               1
  237 #define MPS_CM_STATE_TIMEDOUT           2
  238         bus_dmamap_t                    cm_dmamap;
  239         struct scsi_sense_data          *cm_sense;
  240         TAILQ_HEAD(, mps_chain)         cm_chain_list;
  241         uint32_t                        cm_req_busaddr;
  242         uint32_t                        cm_sense_busaddr;
  243         struct callout                  cm_callout;
  244 };
  245 
  246 struct mps_column_map {
  247         uint16_t                        dev_handle;
  248         uint8_t                         phys_disk_num;
  249 };
  250 
  251 struct mps_event_handle {
  252         TAILQ_ENTRY(mps_event_handle)   eh_list;
  253         mps_evt_callback_t              *callback;
  254         void                            *data;
  255         u32                             mask[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
  256 };
  257 
  258 struct mps_softc {
  259         device_t                        mps_dev;
  260         struct cdev                     *mps_cdev;
  261         u_int                           mps_flags;
  262 #define MPS_FLAGS_INTX          (1 << 0)
  263 #define MPS_FLAGS_MSI           (1 << 1)
  264 #define MPS_FLAGS_BUSY          (1 << 2)
  265 #define MPS_FLAGS_SHUTDOWN      (1 << 3)
  266 #define MPS_FLAGS_DIAGRESET     (1 << 4)
  267 #define MPS_FLAGS_ATTACH_DONE   (1 << 5)
  268 #define MPS_FLAGS_WD_AVAILABLE  (1 << 6)
  269         u_int                           mps_debug;
  270         u_int                           disable_msix;
  271         u_int                           disable_msi;
  272         int                             tm_cmds_active;
  273         int                             io_cmds_active;
  274         int                             io_cmds_highwater;
  275         int                             chain_free;
  276         int                             max_chains;
  277         int                             chain_free_lowwater;
  278 #if __FreeBSD_version >= 900030
  279         uint64_t                        chain_alloc_fail;
  280 #endif
  281         struct sysctl_ctx_list          sysctl_ctx;
  282         struct sysctl_oid               *sysctl_tree;
  283         char                            fw_version[16];
  284         struct mps_command              *commands;
  285         struct mps_chain                *chains;
  286         struct callout                  periodic;
  287 
  288         struct mpssas_softc             *sassc;
  289         char            tmp_string[MPS_STRING_LENGTH];
  290         TAILQ_HEAD(, mps_command)       req_list;
  291         TAILQ_HEAD(, mps_command)       high_priority_req_list;
  292         TAILQ_HEAD(, mps_chain)         chain_list;
  293         TAILQ_HEAD(, mps_command)       tm_list;
  294         int                             replypostindex;
  295         int                             replyfreeindex;
  296 
  297         struct resource                 *mps_regs_resource;
  298         bus_space_handle_t              mps_bhandle;
  299         bus_space_tag_t                 mps_btag;
  300         int                             mps_regs_rid;
  301 
  302         bus_dma_tag_t                   mps_parent_dmat;
  303         bus_dma_tag_t                   buffer_dmat;
  304 
  305         MPI2_IOC_FACTS_REPLY            *facts;
  306         MPI2_PORT_FACTS_REPLY           *pfacts;
  307         int                             num_reqs;
  308         int                             num_replies;
  309         int                             fqdepth;        /* Free queue */
  310         int                             pqdepth;        /* Post queue */
  311 
  312         u32             event_mask[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
  313         TAILQ_HEAD(, mps_event_handle)  event_list;
  314         struct mps_event_handle         *mps_log_eh;
  315 
  316         struct mtx                      mps_mtx;
  317         struct intr_config_hook         mps_ich;
  318         struct resource                 *mps_irq[MPS_MSI_COUNT];
  319         void                            *mps_intrhand[MPS_MSI_COUNT];
  320         int                             mps_irq_rid[MPS_MSI_COUNT];
  321 
  322         uint8_t                         *req_frames;
  323         bus_addr_t                      req_busaddr;
  324         bus_dma_tag_t                   req_dmat;
  325         bus_dmamap_t                    req_map;
  326 
  327         uint8_t                         *reply_frames;
  328         bus_addr_t                      reply_busaddr;
  329         bus_dma_tag_t                   reply_dmat;
  330         bus_dmamap_t                    reply_map;
  331 
  332         struct scsi_sense_data          *sense_frames;
  333         bus_addr_t                      sense_busaddr;
  334         bus_dma_tag_t                   sense_dmat;
  335         bus_dmamap_t                    sense_map;
  336 
  337         uint8_t                         *chain_frames;
  338         bus_addr_t                      chain_busaddr;
  339         bus_dma_tag_t                   chain_dmat;
  340         bus_dmamap_t                    chain_map;
  341 
  342         MPI2_REPLY_DESCRIPTORS_UNION    *post_queue;
  343         bus_addr_t                      post_busaddr;
  344         uint32_t                        *free_queue;
  345         bus_addr_t                      free_busaddr;
  346         bus_dma_tag_t                   queues_dmat;
  347         bus_dmamap_t                    queues_map;
  348 
  349         uint8_t                         *fw_diag_buffer;
  350         bus_addr_t                      fw_diag_busaddr;
  351         bus_dma_tag_t                   fw_diag_dmat;
  352         bus_dmamap_t                    fw_diag_map;
  353 
  354         uint8_t                         ir_firmware;
  355 
  356         /* static config pages */
  357         Mpi2IOCPage8_t                  ioc_pg8;
  358 
  359         /* host mapping support */
  360         struct dev_mapping_table        *mapping_table;
  361         struct enc_mapping_table        *enclosure_table;
  362         struct map_removal_table        *removal_table;
  363         uint8_t                         *dpm_entry_used;
  364         uint8_t                         *dpm_flush_entry;
  365         Mpi2DriverMappingPage0_t        *dpm_pg0;
  366         uint16_t                        max_devices;
  367         uint16_t                        max_enclosures;
  368         uint16_t                        max_expanders;
  369         uint8_t                         max_volumes;
  370         uint8_t                         num_enc_table_entries;
  371         uint8_t                         num_rsvd_entries;
  372         uint8_t                         num_channels;
  373         uint16_t                        max_dpm_entries;
  374         uint8_t                         is_dpm_enable;
  375         uint8_t                         track_mapping_events;
  376         uint32_t                        pending_map_events;
  377         uint8_t                         mt_full_retry;
  378         uint8_t                         mt_add_device_failed;
  379 
  380         /* FW diag Buffer List */
  381         mps_fw_diagnostic_buffer_t
  382                                 fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_COUNT];
  383 
  384         /* Event Recording IOCTL support */
  385         uint32_t                        events_to_record[4];
  386         mps_event_entry_t               recorded_events[MPS_EVENT_QUEUE_SIZE];
  387         uint8_t                         event_index;
  388         uint32_t                        event_number;
  389 
  390         /* EEDP and TLR support */
  391         uint8_t                         eedp_enabled;
  392         uint8_t                         control_TLR;
  393 
  394         /* Shutdown Event Handler */
  395         eventhandler_tag                shutdown_eh;
  396 
  397         /* To track topo events during reset */
  398 #define MPS_DIAG_RESET_TIMEOUT  300000
  399         uint8_t                         wait_for_port_enable;
  400         uint8_t                         port_enable_complete;
  401         uint8_t                         msleep_fake_chan;
  402 
  403         /* WD controller */
  404         uint8_t             WD_available;
  405         uint8_t                         WD_valid_config;
  406         uint8_t                         WD_hide_expose;
  407 
  408         /* Direct Drive for WarpDrive */
  409         uint8_t                         DD_num_phys_disks;
  410         uint16_t                        DD_dev_handle;
  411         uint32_t                        DD_stripe_size;
  412         uint32_t                        DD_stripe_exponent;
  413         uint32_t                        DD_block_size;
  414         uint16_t                        DD_block_exponent;
  415         uint64_t                        DD_max_lba;
  416         struct mps_column_map           DD_column_map[MPS_MAX_DISKS_IN_VOL];
  417 };
  418 
  419 struct mps_config_params {
  420         MPI2_CONFIG_EXT_PAGE_HEADER_UNION       hdr;
  421         u_int           action;
  422         u_int           page_address;   /* Attributes, not a phys address */
  423         u_int           status;
  424         void            *buffer;
  425         u_int           length;
  426         int             timeout;
  427         void            (*callback)(struct mps_softc *, struct mps_config_params *);
  428         void            *cbdata;
  429 };
  430 
  431 struct scsi_read_capacity_eedp
  432 {
  433         uint8_t addr[8];
  434         uint8_t length[4];
  435         uint8_t protect;
  436 };
  437 
  438 static __inline uint32_t
  439 mps_regread(struct mps_softc *sc, uint32_t offset)
  440 {
  441         return (bus_space_read_4(sc->mps_btag, sc->mps_bhandle, offset));
  442 }
  443 
  444 static __inline void
  445 mps_regwrite(struct mps_softc *sc, uint32_t offset, uint32_t val)
  446 {
  447         bus_space_write_4(sc->mps_btag, sc->mps_bhandle, offset, val);
  448 }
  449 
  450 /* free_queue must have Little Endian address 
  451  * TODO- cm_reply_data is unwanted. We can remove it.
  452  * */
  453 static __inline void
  454 mps_free_reply(struct mps_softc *sc, uint32_t busaddr)
  455 {
  456         if (++sc->replyfreeindex >= sc->fqdepth)
  457                 sc->replyfreeindex = 0;
  458         sc->free_queue[sc->replyfreeindex] = htole32(busaddr);
  459         mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex);
  460 }
  461 
  462 static __inline struct mps_chain *
  463 mps_alloc_chain(struct mps_softc *sc)
  464 {
  465         struct mps_chain *chain;
  466 
  467         if ((chain = TAILQ_FIRST(&sc->chain_list)) != NULL) {
  468                 TAILQ_REMOVE(&sc->chain_list, chain, chain_link);
  469                 sc->chain_free--;
  470                 if (sc->chain_free < sc->chain_free_lowwater)
  471                         sc->chain_free_lowwater = sc->chain_free;
  472         }
  473 #if __FreeBSD_version >= 900030
  474         else
  475                 sc->chain_alloc_fail++;
  476 #endif
  477         return (chain);
  478 }
  479 
  480 static __inline void
  481 mps_free_chain(struct mps_softc *sc, struct mps_chain *chain)
  482 {
  483 #if 0
  484         bzero(chain->chain, 128);
  485 #endif
  486         sc->chain_free++;
  487         TAILQ_INSERT_TAIL(&sc->chain_list, chain, chain_link);
  488 }
  489 
  490 static __inline void
  491 mps_free_command(struct mps_softc *sc, struct mps_command *cm)
  492 {
  493         struct mps_chain *chain, *chain_temp;
  494 
  495         if (cm->cm_reply != NULL)
  496                 mps_free_reply(sc, cm->cm_reply_data);
  497         cm->cm_reply = NULL;
  498         cm->cm_flags = 0;
  499         cm->cm_complete = NULL;
  500         cm->cm_complete_data = NULL;
  501         cm->cm_ccb = NULL;
  502         cm->cm_targ = NULL;
  503         cm->cm_max_segs = 0;
  504         cm->cm_lun = 0;
  505         cm->cm_state = MPS_CM_STATE_FREE;
  506         cm->cm_data = NULL;
  507         cm->cm_length = 0;
  508         cm->cm_out_len = 0;
  509         cm->cm_sglsize = 0;
  510         cm->cm_sge = NULL;
  511 
  512         TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, chain_temp) {
  513                 TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
  514                 mps_free_chain(sc, chain);
  515         }
  516         TAILQ_INSERT_TAIL(&sc->req_list, cm, cm_link);
  517 }
  518 
  519 static __inline struct mps_command *
  520 mps_alloc_command(struct mps_softc *sc)
  521 {
  522         struct mps_command *cm;
  523 
  524         cm = TAILQ_FIRST(&sc->req_list);
  525         if (cm == NULL)
  526                 return (NULL);
  527 
  528         TAILQ_REMOVE(&sc->req_list, cm, cm_link);
  529         KASSERT(cm->cm_state == MPS_CM_STATE_FREE, ("mps: Allocating busy command\n"));
  530         cm->cm_state = MPS_CM_STATE_BUSY;
  531         return (cm);
  532 }
  533 
  534 static __inline void
  535 mps_free_high_priority_command(struct mps_softc *sc, struct mps_command *cm)
  536 {
  537         struct mps_chain *chain, *chain_temp;
  538 
  539         if (cm->cm_reply != NULL)
  540                 mps_free_reply(sc, cm->cm_reply_data);
  541         cm->cm_reply = NULL;
  542         cm->cm_flags = 0;
  543         cm->cm_complete = NULL;
  544         cm->cm_complete_data = NULL;
  545         cm->cm_ccb = NULL;
  546         cm->cm_targ = NULL;
  547         cm->cm_lun = 0;
  548         cm->cm_state = MPS_CM_STATE_FREE;
  549         TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, chain_temp) {
  550                 TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
  551                 mps_free_chain(sc, chain);
  552         }
  553         TAILQ_INSERT_TAIL(&sc->high_priority_req_list, cm, cm_link);
  554 }
  555 
  556 static __inline struct mps_command *
  557 mps_alloc_high_priority_command(struct mps_softc *sc)
  558 {
  559         struct mps_command *cm;
  560 
  561         cm = TAILQ_FIRST(&sc->high_priority_req_list);
  562         if (cm == NULL)
  563                 return (NULL);
  564 
  565         TAILQ_REMOVE(&sc->high_priority_req_list, cm, cm_link);
  566         KASSERT(cm->cm_state == MPS_CM_STATE_FREE, ("mps: Allocating busy command\n"));
  567         cm->cm_state = MPS_CM_STATE_BUSY;
  568         return (cm);
  569 }
  570 
  571 static __inline void
  572 mps_lock(struct mps_softc *sc)
  573 {
  574         mtx_lock(&sc->mps_mtx);
  575 }
  576 
  577 static __inline void
  578 mps_unlock(struct mps_softc *sc)
  579 {
  580         mtx_unlock(&sc->mps_mtx);
  581 }
  582 
  583 #define MPS_INFO        (1 << 0)
  584 #define MPS_TRACE       (1 << 1)
  585 #define MPS_FAULT       (1 << 2)
  586 #define MPS_EVENT       (1 << 3)
  587 #define MPS_LOG         (1 << 4)
  588 
  589 #define mps_printf(sc, args...)                         \
  590         device_printf((sc)->mps_dev, ##args)
  591 
  592 #define mps_vprintf(sc, args...)                        \
  593 do {                                                    \
  594         if (bootverbose)                                \
  595                 mps_printf(sc, ##args);                 \
  596 } while (0)
  597 
  598 #define mps_dprint(sc, level, msg, args...)             \
  599 do {                                                    \
  600         if (sc->mps_debug & level)                      \
  601                 device_printf(sc->mps_dev, msg, ##args);        \
  602 } while (0)
  603 
  604 #define mps_dprint_field(sc, level, msg, args...)               \
  605 do {                                                            \
  606         if (sc->mps_debug & level)                              \
  607                 printf("\t" msg, ##args);                       \
  608 } while (0)
  609 
  610 #define MPS_PRINTFIELD_START(sc, tag...)        \
  611         mps_dprint((sc), MPS_INFO, ##tag);      \
  612         mps_dprint_field((sc), MPS_INFO, ":\n")
  613 #define MPS_PRINTFIELD_END(sc, tag)             \
  614         mps_dprint((sc), MPS_INFO, tag "\n")
  615 #define MPS_PRINTFIELD(sc, facts, attr, fmt)    \
  616         mps_dprint_field((sc), MPS_INFO, #attr ": " #fmt "\n", (facts)->attr)
  617 
  618 #define MPS_EVENTFIELD_START(sc, tag...)        \
  619         mps_dprint((sc), MPS_EVENT, ##tag);     \
  620         mps_dprint_field((sc), MPS_EVENT, ":\n")
  621 #define MPS_EVENTFIELD(sc, facts, attr, fmt)    \
  622         mps_dprint_field((sc), MPS_EVENT, #attr ": " #fmt "\n", (facts)->attr)
  623 
  624 #define  CAN_SLEEP                      1
  625 #define  NO_SLEEP                       0
  626 
  627 static __inline void
  628 mps_from_u64(uint64_t data, U64 *mps)
  629 {
  630         (mps)->High = (uint32_t)((data) >> 32);
  631         (mps)->Low = (uint32_t)((data) & 0xffffffff);
  632 }
  633 
  634 static __inline uint64_t
  635 mps_to_u64(U64 *data)
  636 {
  637 
  638         return (((uint64_t)data->High << 32) | data->Low);
  639 }
  640 
  641 static __inline void
  642 mps_mask_intr(struct mps_softc *sc)
  643 {
  644         uint32_t mask;
  645 
  646         mask = mps_regread(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET);
  647         mask |= MPI2_HIM_REPLY_INT_MASK;
  648         mps_regwrite(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET, mask);
  649 }
  650 
  651 static __inline void
  652 mps_unmask_intr(struct mps_softc *sc)
  653 {
  654         uint32_t mask;
  655 
  656         mask = mps_regread(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET);
  657         mask &= ~MPI2_HIM_REPLY_INT_MASK;
  658         mps_regwrite(sc, MPI2_HOST_INTERRUPT_MASK_OFFSET, mask);
  659 }
  660 
  661 int mps_pci_setup_interrupts(struct mps_softc *sc);
  662 int mps_pci_restore(struct mps_softc *sc);
  663 
  664 int mps_attach(struct mps_softc *sc);
  665 int mps_free(struct mps_softc *sc);
  666 void mps_intr(void *);
  667 void mps_intr_msi(void *);
  668 void mps_intr_locked(void *);
  669 int mps_register_events(struct mps_softc *, u32 *, mps_evt_callback_t *,
  670     void *, struct mps_event_handle **);
  671 int mps_restart(struct mps_softc *);
  672 int mps_update_events(struct mps_softc *, struct mps_event_handle *, u32 *);
  673 void mps_deregister_events(struct mps_softc *, struct mps_event_handle *);
  674 int mps_push_sge(struct mps_command *, void *, size_t, int);
  675 int mps_add_dmaseg(struct mps_command *, vm_paddr_t, size_t, u_int, int);
  676 int mps_attach_sas(struct mps_softc *sc);
  677 int mps_detach_sas(struct mps_softc *sc);
  678 int mps_read_config_page(struct mps_softc *, struct mps_config_params *);
  679 int mps_write_config_page(struct mps_softc *, struct mps_config_params *);
  680 void mps_memaddr_cb(void *, bus_dma_segment_t *, int , int );
  681 void mpi_init_sge(struct mps_command *cm, void *req, void *sge);
  682 int mps_attach_user(struct mps_softc *);
  683 void mps_detach_user(struct mps_softc *);
  684 void mpssas_record_event(struct mps_softc *sc,
  685     MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
  686 
  687 int mps_map_command(struct mps_softc *sc, struct mps_command *cm);
  688 int mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout);
  689 int mps_request_polled(struct mps_softc *sc, struct mps_command *cm);
  690 
  691 int mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t
  692     *mpi_reply, Mpi2BiosPage3_t *config_page);
  693 int mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
  694     *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address);
  695 int mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *,
  696     Mpi2IOCPage8_t *);
  697 int mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply);
  698 int mps_config_get_sas_device_pg0(struct mps_softc *, Mpi2ConfigReply_t *,
  699     Mpi2SasDevicePage0_t *, u32 , u16 );
  700 int mps_config_get_dpm_pg0(struct mps_softc *, Mpi2ConfigReply_t *,
  701     Mpi2DriverMappingPage0_t *, u16 );
  702 int mps_config_get_raid_volume_pg1(struct mps_softc *sc,
  703     Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
  704     u16 handle);
  705 int mps_config_get_volume_wwid(struct mps_softc *sc, u16 volume_handle,
  706     u64 *wwid);
  707 int mps_config_get_raid_pd_pg0(struct mps_softc *sc,
  708     Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page,
  709     u32 page_address);
  710 void mpssas_ir_shutdown(struct mps_softc *sc);
  711 
  712 int mps_reinit(struct mps_softc *sc);
  713 void mpssas_handle_reinit(struct mps_softc *sc);
  714 
  715 void mps_base_static_config_pages(struct mps_softc *sc);
  716 void mps_wd_config_pages(struct mps_softc *sc);
  717 
  718 int mps_mapping_initialize(struct mps_softc *);
  719 void mps_mapping_topology_change_event(struct mps_softc *,
  720     Mpi2EventDataSasTopologyChangeList_t *);
  721 int mps_mapping_is_reinit_required(struct mps_softc *);
  722 void mps_mapping_free_memory(struct mps_softc *sc);
  723 int mps_config_set_dpm_pg0(struct mps_softc *, Mpi2ConfigReply_t *,
  724     Mpi2DriverMappingPage0_t *, u16 );
  725 void mps_mapping_exit(struct mps_softc *);
  726 void mps_mapping_check_devices(struct mps_softc *, int);
  727 int mps_mapping_allocate_memory(struct mps_softc *sc);
  728 unsigned int mps_mapping_get_sas_id(struct mps_softc *, uint64_t , u16);
  729 unsigned int mps_mapping_get_sas_id_from_handle(struct mps_softc *sc,
  730     u16 handle);
  731 unsigned int mps_mapping_get_raid_id(struct mps_softc *sc, u64 wwid,
  732     u16 handle);
  733 unsigned int mps_mapping_get_raid_id_from_handle(struct mps_softc *sc,
  734     u16 volHandle);
  735 void mps_mapping_enclosure_dev_status_change_event(struct mps_softc *,
  736     Mpi2EventDataSasEnclDevStatusChange_t *event_data);
  737 void mps_mapping_ir_config_change_event(struct mps_softc *sc,
  738     Mpi2EventDataIrConfigChangeList_t *event_data);
  739 
  740 void mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
  741     MPI2_EVENT_NOTIFICATION_REPLY *event);
  742 void mpssas_prepare_remove(struct mpssas_softc *sassc, uint16_t handle);
  743 void mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle);
  744 int mpssas_startup(struct mps_softc *sc);
  745 struct mpssas_target * mpssas_find_target_by_handle(struct mpssas_softc *, int, uint16_t);
  746 
  747 SYSCTL_DECL(_hw_mps);
  748 
  749 /* Compatibility shims for different OS versions */
  750 #if __FreeBSD_version >= 800001
  751 #define mps_kproc_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
  752     kproc_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg)
  753 #define mps_kproc_exit(arg)     kproc_exit(arg)
  754 #else
  755 #define mps_kproc_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
  756     kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg)
  757 #define mps_kproc_exit(arg)     kthread_exit(arg)
  758 #endif
  759 
  760 #if defined(CAM_PRIORITY_XPT)
  761 #define MPS_PRIORITY_XPT        CAM_PRIORITY_XPT
  762 #else
  763 #define MPS_PRIORITY_XPT        5
  764 #endif
  765 
  766 #if __FreeBSD_version < 800107
  767 // Prior to FreeBSD-8.0 scp3_flags was not defined.
  768 #define spc3_flags reserved
  769 
  770 #define SPC3_SID_PROTECT    0x01
  771 #define SPC3_SID_3PC        0x08
  772 #define SPC3_SID_TPGS_MASK  0x30
  773 #define SPC3_SID_TPGS_IMPLICIT  0x10
  774 #define SPC3_SID_TPGS_EXPLICIT  0x20
  775 #define SPC3_SID_ACC        0x40
  776 #define SPC3_SID_SCCS       0x80
  777 
  778 #define CAM_PRIORITY_NORMAL CAM_PRIORITY_NONE
  779 #endif
  780 
  781 #endif
  782 

Cache object: 1b3aa7dbd9e5a4c41a4fbff7796d80e6


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