Print this page
Code reconciliation with other base.
Update tx waitq's code.
Create 2 threads, divide the workflow and deliver
to the hardware from the threads.
Optimise mutex's and code paths.
Split out offline target code.
Enable Fast Path for capable devices.
Merge fixes for Illumos issue 4819, fix mpt_sas command timeout handling.
Tweeks debug flags.
Lint and cstyle fixes.
Fix problem with running against 64bit msgaddr attributes for DMA.
Default is now to run like this.
Fixes for Illumos issue 4682.
Fix hang bug to do with tx_wq.
Re-arrange mptsas_poll() to disable interrupts before issuing the
command.
Improve the tx_waitq code path.
Major rework of mutexes.
During normal operation do not grab m_mutex during interrupt.
Use reply post queues instead.
Distribute command done processing around the threads.
Improved auto-request sense memory usage.
Re-arrange mptsas_intr() to reduce number of spurious interrupts.
Should not need m_in_callback flag. It prevents concurrent
command completion processing.
Added code to support using MSI-X interrupts across multiple
reply queues. Not tested with anything other than 3008 yet.
Use MSI-X interrupts, just one for now.
Pre-allocate array for request sense buffers, similar to command frames.
No more messing about with scsi_alloc_consistent_buf().
Add rolling buffer for *all* debug messages.
Improve mdb module and seperate out into mpt_sas3.
Initial modifications using the code changes present between
the LSI source code for FreeBSD drivers. Specifically the changes
between from mpslsi-source-17.00.00.00 -> mpslsi-source-03.00.00.00.
This mainly involves using a different scatter/gather element in
frame setup.
Changes to enable driver to compile.
Header paths, object lists, etc.


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.

  26  */
  27 
  28 /*
  29  * Copyright (c) 2000 to 2010, LSI Corporation.
  30  * All rights reserved.
  31  *
  32  * Redistribution and use in source and binary forms of all code within
  33  * this file that is exclusively owned by LSI, with or without
  34  * modification, is permitted provided that, in addition to the CDDL 1.0
  35  * License requirements, the following conditions are met:
  36  *
  37  *    Neither the name of the author nor the names of its contributors may be
  38  *    used to endorse or promote products derived from this software without
  39  *    specific prior written permission.
  40  *
  41  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  42  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  43  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  44  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  45  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  46  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  47  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  48  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  49  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  52  * DAMAGE.
  53  */
  54 
  55 #ifndef _SYS_SCSI_ADAPTERS_MPTVAR_H
  56 #define _SYS_SCSI_ADAPTERS_MPTVAR_H
  57 
  58 #include <sys/byteorder.h>

  59 #include <sys/isa_defs.h>
  60 #include <sys/sunmdi.h>
  61 #include <sys/mdi_impldefs.h>
  62 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
  63 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
  64 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
  65 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  66 
  67 #ifdef  __cplusplus
  68 extern "C" {
  69 #endif
  70 
  71 /*
  72  * Compile options
  73  */
  74 #ifdef DEBUG
  75 #define MPTSAS_DEBUG            /* turn on debugging code */
  76 #endif  /* DEBUG */
  77 
  78 #define MPTSAS_INITIAL_SOFT_SPACE       4
  79 
  80 #define MAX_MPI_PORTS           16
  81 
  82 /*
  83  * Note below macro definition and data type definition
  84  * are used for phy mask handling, it should be changed
  85  * simultaneously.


 124 
 125 /*
 126  * If the HBA supports DMA or bus-mastering, you may have your own
 127  * scatter-gather list for physically non-contiguous memory in one
 128  * I/O operation; if so, there's probably a size for that list.
 129  * It must be placed in the ddi_dma_lim_t structure, so that the system
 130  * DMA-support routines can use it to break up the I/O request, so we
 131  * define it here.
 132  */
 133 #if defined(__sparc)
 134 #define MPTSAS_MAX_DMA_SEGS     1
 135 #define MPTSAS_MAX_CMD_SEGS     1
 136 #else
 137 #define MPTSAS_MAX_DMA_SEGS     256
 138 #define MPTSAS_MAX_CMD_SEGS     257
 139 #endif
 140 #define MPTSAS_MAX_FRAME_SGES(mpt) \
 141         (((mpt->m_req_frame_size - (sizeof (MPI2_SCSI_IO_REQUEST))) / 8) + 1)
 142 
 143 /*
 144  * Caculating how many 64-bit DMA simple elements can be stored in the first
 145  * frame. Note that msg_scsi_io_request contains 2 double-words (8 bytes) for
 146  * element storage.  And 64-bit dma element is 3 double-words (12 bytes) in
 147  * size.

 148  */
 149 #define MPTSAS_MAX_FRAME_SGES64(mpt) \
 150         ((mpt->m_req_frame_size - \
 151         (sizeof (MPI2_SCSI_IO_REQUEST)) + sizeof (MPI2_SGE_IO_UNION)) / 12)


 152 
 153 /*
 154  * Scatter-gather list structure defined by HBA hardware
 155  */
 156 typedef struct NcrTableIndirect {       /* Table Indirect entries */
 157         uint32_t count;         /* 24 bit count */
 158         union {
 159                 uint32_t address32;     /* 32 bit address */
 160                 struct {
 161                         uint32_t Low;
 162                         uint32_t High;
 163                 } address64;            /* 64 bit address */
 164         } addr;
 165 } mptti_t;
 166 
 167 /*
 168  * preferred pkt_private length in 64-bit quantities
 169  */
 170 #ifdef  _LP64
 171 #define PKT_PRIV_SIZE   2


 183  * get offset of item in structure
 184  */
 185 #define MPTSAS_GET_ITEM_OFF(type, member) ((size_t)(&((type *)0)->member))
 186 
 187 /*
 188  * WWID provided by LSI firmware is generated by firmware but the WWID is not
 189  * IEEE NAA standard format, OBP has no chance to distinguish format of unit
 190  * address. According LSI's confirmation, the top nibble of RAID WWID is
 191  * meanless, so the consensus between Solaris and OBP is to replace top nibble
 192  * of WWID provided by LSI to "3" always to hint OBP that this is a RAID WWID
 193  * format unit address.
 194  */
 195 #define MPTSAS_RAID_WWID(wwid) \
 196         ((wwid & 0x0FFFFFFFFFFFFFFF) | 0x3000000000000000)
 197 
 198 typedef struct mptsas_target_addr {
 199         uint64_t mta_wwn;
 200         mptsas_phymask_t mta_phymask;
 201 } mptsas_target_addr_t;
 202 



 203 typedef struct mptsas_target {

 204                 mptsas_target_addr_t    m_addr;
 205                 refhash_link_t          m_link;
 206                 uint8_t                 m_dr_flag;
 207                 uint16_t                m_devhdl;
 208                 uint32_t                m_deviceinfo;
 209                 uint8_t                 m_phynum;
 210                 uint32_t                m_dups;
 211                 int32_t                 m_timeout;
 212                 int32_t                 m_timebase;
 213                 int32_t                 m_t_throttle;
 214                 int32_t                 m_t_ncmds;
 215                 int32_t                 m_reset_delay;
 216                 int32_t                 m_t_nwait;
 217 
 218                 uint16_t                m_qfull_retry_interval;
 219                 uint8_t                 m_qfull_retries;
 220                 uint16_t                m_enclosure;
 221                 uint16_t                m_slot_num;
 222                 uint32_t                m_tgt_unconfigured;


 223                 uint8_t                 m_led_status;
 224 
 225 } mptsas_target_t;
 226 




 227 typedef struct mptsas_smp {
 228         mptsas_target_addr_t    m_addr;
 229         refhash_link_t          m_link;
 230         uint16_t                m_devhdl;
 231         uint32_t                m_deviceinfo;
 232         uint16_t                m_pdevhdl;
 233         uint32_t                m_pdevinfo;
 234 } mptsas_smp_t;
 235 
 236 typedef struct mptsas_cache_frames {
 237         ddi_dma_handle_t m_dma_hdl;
 238         ddi_acc_handle_t m_acc_hdl;
 239         caddr_t m_frames_addr;
 240         uint32_t m_phys_addr;
 241 } mptsas_cache_frames_t;
 242 
 243 typedef struct  mptsas_cmd {
 244         uint_t                  cmd_flags;      /* flags from scsi_init_pkt */
 245         ddi_dma_handle_t        cmd_dmahandle;  /* dma handle */
 246         ddi_dma_cookie_t        cmd_cookie;
 247         uint_t                  cmd_cookiec;
 248         uint_t                  cmd_winindex;
 249         uint_t                  cmd_nwin;
 250         uint_t                  cmd_cur_cookie;
 251         off_t                   cmd_dma_offset;
 252         size_t                  cmd_dma_len;
 253         uint32_t                cmd_totaldmacount;
 254 
 255         ddi_dma_handle_t        cmd_arqhandle;  /* dma arq handle */
 256         ddi_dma_cookie_t        cmd_arqcookie;
 257         struct buf              *cmd_arq_buf;
 258         ddi_dma_handle_t        cmd_ext_arqhandle; /* dma extern arq handle */
 259         ddi_dma_cookie_t        cmd_ext_arqcookie;
 260         struct buf              *cmd_ext_arq_buf;
 261 
 262         int                     cmd_pkt_flags;
 263 
 264         /* timer for command in active slot */
 265         int                     cmd_active_timeout;

 266 
 267         struct scsi_pkt         *cmd_pkt;
 268         struct scsi_arq_status  cmd_scb;
 269         uchar_t                 cmd_cdblen;     /* length of cdb */
 270         uchar_t                 cmd_rqslen;     /* len of requested rqsense */
 271         uchar_t                 cmd_privlen;



 272         uint_t                  cmd_scblen;
 273         uint32_t                cmd_dmacount;
 274         uint64_t                cmd_dma_addr;
 275         uchar_t                 cmd_age;
 276         ushort_t                cmd_qfull_retries;
 277         uchar_t                 cmd_queued;     /* true if queued */
 278         struct mptsas_cmd       *cmd_linkp;
 279         mptti_t                 *cmd_sg; /* Scatter/Gather structure */
 280         uchar_t                 cmd_cdb[SCSI_CDB_SIZE];
 281         uint64_t                cmd_pkt_private[PKT_PRIV_LEN];
 282         uint32_t                cmd_slot;
 283         uint32_t                ioc_cmd_slot;

 284 
 285         mptsas_cache_frames_t   *cmd_extra_frames;
 286 
 287         uint32_t                cmd_rfm;
 288         mptsas_target_t         *cmd_tgt_addr;
 289 } mptsas_cmd_t;
 290 
 291 /*
 292  * These are the defined cmd_flags for this structure.
 293  */
 294 #define CFLAG_CMDDISC           0x000001 /* cmd currently disconnected */
 295 #define CFLAG_WATCH             0x000002 /* watchdog time for this command */
 296 #define CFLAG_FINISHED          0x000004 /* command completed */
 297 #define CFLAG_CHKSEG            0x000008 /* check cmd_data within seg */
 298 #define CFLAG_COMPLETED         0x000010 /* completion routine called */
 299 #define CFLAG_PREPARED          0x000020 /* pkt has been init'ed */
 300 #define CFLAG_IN_TRANSPORT      0x000040 /* in use by host adapter driver */
 301 #define CFLAG_RESTORE_PTRS      0x000080 /* implicit restore ptr on reconnect */
 302 #define CFLAG_ARQ_IN_PROGRESS   0x000100 /* auto request sense in progress */
 303 #define CFLAG_TRANFLAG          0x0001ff /* covers transport part of flags */
 304 #define CFLAG_TM_CMD            0x000200 /* cmd is a task management command */
 305 #define CFLAG_CMDARQ            0x000400 /* cmd is a 'rqsense' command */
 306 #define CFLAG_DMAVALID          0x000800 /* dma mapping valid */
 307 #define CFLAG_DMASEND           0x001000 /* data is going 'out' */
 308 #define CFLAG_CMDIOPB           0x002000 /* this is an 'iopb' packet */
 309 #define CFLAG_CDBEXTERN         0x004000 /* cdb kmem_alloc'd */
 310 #define CFLAG_SCBEXTERN         0x008000 /* scb kmem_alloc'd */
 311 #define CFLAG_FREE              0x010000 /* packet is on free list */
 312 #define CFLAG_PRIVEXTERN        0x020000 /* target private kmem_alloc'd */
 313 #define CFLAG_DMA_PARTIAL       0x040000 /* partial xfer OK */
 314 #define CFLAG_QFULL_STATUS      0x080000 /* pkt got qfull status */
 315 #define CFLAG_TIMEOUT           0x100000 /* passthru/config command timeout */
 316 #define CFLAG_PMM_RECEIVED      0x200000 /* use cmd_pmm* for saving pointers */
 317 #define CFLAG_RETRY             0x400000 /* cmd has been retried */
 318 #define CFLAG_CMDIOC            0x800000 /* cmd is just for for ioc, no io */
 319 #define CFLAG_EXTARQBUFVALID    0x1000000 /* extern arq buf handle is valid */
 320 #define CFLAG_PASSTHRU          0x2000000 /* cmd is a passthrough command */
 321 #define CFLAG_XARQ              0x4000000 /* cmd requests for extra sense */
 322 #define CFLAG_CMDACK            0x8000000 /* cmd for event ack */
 323 #define CFLAG_TXQ               0x10000000 /* cmd queued in the tx_waitq */
 324 #define CFLAG_FW_CMD            0x20000000 /* cmd is a fw up/down command */
 325 #define CFLAG_CONFIG            0x40000000 /* cmd is for config header/page */
 326 #define CFLAG_FW_DIAG           0x80000000 /* cmd is for FW diag buffers */
 327 









 328 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE                     8
 329 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK                     0xC0
 330 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL                       0x00
 331 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE                       0x40
 332 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT             0x80
 333 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT            0xC0
 334 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_2B          0x00
 335 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_4B          0x01
 336 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_6B          0x10
 337 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_8B          0x20
 338 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_SIZE                0x30
 339 
 340 #define MPTSAS_HASH_ARRAY_SIZE  16
 341 /*
 342  * hash table definition
 343  */
 344 
 345 #define MPTSAS_HASH_FIRST       0xffff
 346 #define MPTSAS_HASH_NEXT        0x0000
 347 
 348 typedef struct mptsas_dma_alloc_state
 349 {
 350         ddi_dma_handle_t        handle;
 351         caddr_t                 memp;
 352         size_t                  size;
 353         ddi_acc_handle_t        accessp;
 354         ddi_dma_cookie_t        cookie;
 355 } mptsas_dma_alloc_state_t;
 356 
 357 /*
 358  * passthrough request structure
 359  */
 360 typedef struct mptsas_pt_request {
 361         uint8_t *request;
 362         uint32_t request_size;
 363         uint32_t data_size;
 364         uint32_t dataout_size;
 365         uint32_t direction;


 366         ddi_dma_cookie_t data_cookie;
 367         ddi_dma_cookie_t dataout_cookie;
 368 } mptsas_pt_request_t;
 369 
 370 /*
 371  * config page request structure
 372  */
 373 typedef struct mptsas_config_request {
 374         uint32_t        page_address;
 375         uint8_t         action;
 376         uint8_t         page_type;
 377         uint8_t         page_number;
 378         uint8_t         page_length;
 379         uint8_t         page_version;
 380         uint8_t         ext_page_type;
 381         uint16_t        ext_page_length;
 382 } mptsas_config_request_t;
 383 
 384 typedef struct mptsas_fw_diagnostic_buffer {
 385         mptsas_dma_alloc_state_t        buffer_data;


 531 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::event))
 532 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::physport))
 533 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::devhdl))
 534 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::object))
 535 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::flags))
 536 
 537 /*
 538  * Status types when calling mptsas_get_target_device_info
 539  */
 540 #define DEV_INFO_SUCCESS                0x0
 541 #define DEV_INFO_FAIL_PAGE0             0x1
 542 #define DEV_INFO_WRONG_DEVICE_TYPE      0x2
 543 #define DEV_INFO_PHYS_DISK              0x3
 544 #define DEV_INFO_FAIL_ALLOC             0x4
 545 
 546 /*
 547  * mpt hotplug event defines
 548  */
 549 #define MPTSAS_DR_EVENT_RECONFIG_TARGET 0x01
 550 #define MPTSAS_DR_EVENT_OFFLINE_TARGET  0x02
 551 #define MPTSAS_TOPO_FLAG_REMOVE_HANDLE  0x04
 552 
 553 /*
 554  * SMP target hotplug events
 555  */
 556 #define MPTSAS_DR_EVENT_RECONFIG_SMP    0x10
 557 #define MPTSAS_DR_EVENT_OFFLINE_SMP     0x20
 558 #define MPTSAS_DR_EVENT_MASK            0x3F
 559 
 560 /*
 561  * mpt hotplug status definition for m_dr_flag
 562  */
 563 
 564 /*
 565  * MPTSAS_DR_INACTIVE
 566  *
 567  * The target is in a normal operating state.
 568  * No dynamic reconfiguration operation is in progress.
 569  */
 570 #define MPTSAS_DR_INACTIVE                              0x0
 571 /*


 625         uint8_t         port_num;
 626         kstat_t         *phy_stats;
 627         uint32_t        invalid_dword_count;
 628         uint32_t        running_disparity_error_count;
 629         uint32_t        loss_of_dword_sync_count;
 630         uint32_t        phy_reset_problem_count;
 631         void            *mpt;
 632 } smhba_info_t;
 633 
 634 typedef struct mptsas_phy_info {
 635         uint8_t                 port_num;
 636         uint8_t                 port_flags;
 637         uint16_t                ctrl_devhdl;
 638         uint32_t                phy_device_type;
 639         uint16_t                attached_devhdl;
 640         mptsas_phymask_t        phy_mask;
 641         smhba_info_t            smhba_info;
 642 } mptsas_phy_info_t;
 643 
 644 
 645 typedef struct mptsas_doneq_thread_arg {
 646         void            *mpt;
 647         uint64_t        t;
 648 } mptsas_doneq_thread_arg_t;






 649 
 650 #define MPTSAS_DONEQ_THREAD_ACTIVE      0x1
 651 typedef struct mptsas_doneq_thread_list {
 652         mptsas_cmd_t            *doneq;
 653         mptsas_cmd_t            **donetail;
 654         kthread_t               *threadp;
 655         kcondvar_t              cv;
 656         ushort_t                reserv1;
 657         uint32_t                reserv2;
 658         kmutex_t                mutex;
 659         uint32_t                flag;
 660         uint32_t                len;
 661         mptsas_doneq_thread_arg_t       arg;
 662 } mptsas_doneq_thread_list_t;
 663 





























 664 typedef struct mptsas {
 665         int             m_instance;
 666 
 667         struct mptsas *m_next;
 668 
 669         scsi_hba_tran_t         *m_tran;
 670         smp_hba_tran_t          *m_smptran;
 671         kmutex_t                m_mutex;
 672         kmutex_t                m_passthru_mutex;
 673         kcondvar_t              m_cv;
 674         kcondvar_t              m_passthru_cv;
 675         kcondvar_t              m_fw_cv;
 676         kcondvar_t              m_config_cv;
 677         kcondvar_t              m_fw_diag_cv;
 678         dev_info_t              *m_dip;
 679 
 680         /*
 681          * soft state flags
 682          */
 683         uint_t          m_softstate;
 684 
 685         refhash_t       *m_targets;
 686         refhash_t       *m_smp_targets;
 687 
 688         m_raidconfig_t  m_raidconfig[MPTSAS_MAX_RAIDCONFIGS];
 689         uint8_t         m_num_raid_configs;

 690 
 691         struct mptsas_slots *m_active;  /* outstanding cmds */
 692 
 693         mptsas_cmd_t    *m_waitq;       /* cmd queue for active request */
 694         mptsas_cmd_t    **m_waitqtail;  /* wait queue tail ptr */
 695 
 696         kmutex_t        m_tx_waitq_mutex;
 697         mptsas_cmd_t    *m_tx_waitq;    /* TX cmd queue for active request */
 698         mptsas_cmd_t    **m_tx_waitqtail;       /* tx_wait queue tail ptr */
 699         int             m_tx_draining;  /* TX queue draining flag */
 700 
 701         mptsas_cmd_t    *m_doneq;       /* queue of completed commands */
 702         mptsas_cmd_t    **m_donetail;   /* queue tail ptr */
 703 
 704         /*
 705          * variables for helper threads (fan-out interrupts)
 706          */
 707         mptsas_doneq_thread_list_t      *m_doneq_thread_id;
 708         uint32_t                m_doneq_thread_n;

 709         uint32_t                m_doneq_thread_threshold;
 710         uint32_t                m_doneq_length_threshold;
 711         uint32_t                m_doneq_len;
 712         kcondvar_t              m_doneq_thread_cv;
 713         kmutex_t                m_doneq_mutex;
 714 
 715         int             m_ncmds;        /* number of outstanding commands */


 716         m_event_struct_t *m_ioc_event_cmdq;     /* cmd queue for ioc event */
 717         m_event_struct_t **m_ioc_event_cmdtail; /* ioc cmd queue tail */
 718 
 719         ddi_acc_handle_t m_datap;       /* operating regs data access handle */
 720 
 721         struct _MPI2_SYSTEM_INTERFACE_REGS      *m_reg;
 722 
 723         ushort_t        m_devid;        /* device id of chip. */
 724         uchar_t         m_revid;        /* revision of chip. */
 725         uint16_t        m_svid;         /* subsystem Vendor ID of chip */
 726         uint16_t        m_ssid;         /* subsystem Device ID of chip */
 727 
 728         uchar_t         m_sync_offset;  /* default offset for this chip. */
 729 
 730         timeout_id_t    m_quiesce_timeid;
 731 
 732         ddi_dma_handle_t m_dma_req_frame_hdl;
 733         ddi_acc_handle_t m_acc_req_frame_hdl;


 734         ddi_dma_handle_t m_dma_reply_frame_hdl;
 735         ddi_acc_handle_t m_acc_reply_frame_hdl;
 736         ddi_dma_handle_t m_dma_free_queue_hdl;
 737         ddi_acc_handle_t m_acc_free_queue_hdl;
 738         ddi_dma_handle_t m_dma_post_queue_hdl;
 739         ddi_acc_handle_t m_acc_post_queue_hdl;

 740 
 741         /*
 742          * list of reset notification requests
 743          */
 744         struct scsi_reset_notify_entry  *m_reset_notify_listf;
 745 
 746         /*
 747          * qfull handling
 748          */
 749         timeout_id_t    m_restart_cmd_timeid;
 750 
 751         /*
 752          * scsi reset delay per bus
 753          */
 754         uint_t          m_scsi_reset_delay;
 755 
 756         int             m_pm_idle_delay;
 757 
 758         uchar_t         m_polled_intr;  /* intr was polled. */
 759         uchar_t         m_suspended;    /* true if driver is suspended */
 760 
 761         struct kmem_cache *m_kmem_cache;
 762         struct kmem_cache *m_cache_frames;
 763 
 764         /*
 765          * hba options.
 766          */
 767         uint_t          m_options;
 768 
 769         int             m_in_callback;
 770 
 771         int             m_power_level;  /* current power level */
 772 
 773         int             m_busy;         /* power management busy state */
 774 
 775         off_t           m_pmcsr_offset; /* PMCSR offset */
 776 
 777         ddi_acc_handle_t m_config_handle;
 778 
 779         ddi_dma_attr_t          m_io_dma_attr;  /* Used for data I/O */
 780         ddi_dma_attr_t          m_msg_dma_attr; /* Used for message frames */
 781         ddi_device_acc_attr_t   m_dev_acc_attr;
 782         ddi_device_acc_attr_t   m_reg_acc_attr;
 783 
 784         /*
 785          * request/reply variables
 786          */
 787         caddr_t         m_req_frame;
 788         uint64_t        m_req_frame_dma_addr;



 789         caddr_t         m_reply_frame;
 790         uint64_t        m_reply_frame_dma_addr;
 791         caddr_t         m_free_queue;
 792         uint64_t        m_free_queue_dma_addr;
 793         caddr_t         m_post_queue;
 794         uint64_t        m_post_queue_dma_addr;


 795 
 796         m_replyh_arg_t *m_replyh_args;
 797 
 798         uint16_t        m_max_requests;
 799         uint16_t        m_req_frame_size;

 800 
 801         /*
 802          * Max frames per request reprted in IOC Facts
 803          */
 804         uint8_t         m_max_chain_depth;
 805         /*
 806          * Max frames per request which is used in reality. It's adjusted
 807          * according DMA SG length attribute, and shall not exceed the
 808          * m_max_chain_depth.
 809          */
 810         uint8_t         m_max_request_frames;



 811 
 812         uint16_t        m_free_queue_depth;
 813         uint16_t        m_post_queue_depth;
 814         uint16_t        m_max_replies;
 815         uint32_t        m_free_index;
 816         uint32_t        m_post_index;
 817         uint8_t         m_reply_frame_size;
 818         uint32_t        m_ioc_capabilities;
 819 
 820         /*









 821          * indicates if the firmware was upload by the driver
 822          * at boot time
 823          */
 824         ushort_t        m_fwupload;
 825 
 826         uint16_t        m_productid;
 827 
 828         /*
 829          * per instance data structures for dma memory resources for
 830          * MPI handshake protocol. only one handshake cmd can run at a time.
 831          */
 832         ddi_dma_handle_t        m_hshk_dma_hdl;
 833         ddi_acc_handle_t        m_hshk_acc_hdl;
 834         caddr_t                 m_hshk_memp;
 835         size_t                  m_hshk_dma_size;
 836 
 837         /* Firmware version on the card at boot time */
 838         uint32_t                m_fwversion;
 839 
 840         /* MSI specific fields */


 874         uint8_t                 m_done_traverse_dev;
 875         uint8_t                 m_done_traverse_smp;
 876         int                     m_diag_action_in_progress;
 877         uint16_t                m_dev_handle;
 878         uint16_t                m_smp_devhdl;
 879 
 880         /*
 881          * Event recording
 882          */
 883         uint8_t                 m_event_index;
 884         uint32_t                m_event_number;
 885         uint32_t                m_event_mask[4];
 886         mptsas_event_entry_t    m_events[MPTSAS_EVENT_QUEUE_SIZE];
 887 
 888         /*
 889          * FW diag Buffer List
 890          */
 891         mptsas_fw_diagnostic_buffer_t
 892                 m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_COUNT];
 893 



 894         /*
 895          * Event Replay flag (MUR support)
 896          */
 897         uint8_t                 m_event_replay;
 898 
 899         /*
 900          * IR Capable flag
 901          */
 902         uint8_t                 m_ir_capable;
 903 
 904         /*
 905          * Is HBA processing a diag reset?
 906          */
 907         uint8_t                 m_in_reset;
 908 
 909         /*
 910          * per instance cmd data structures for task management cmds
 911          */
 912         m_event_struct_t        m_event_task_mgmt;      /* must be last */
 913                                                         /* ... scsi_pkt_size */


 918  * Only one of below two conditions is satisfied, we
 919  * think the target is associated to the iport and
 920  * allow call into mptsas_probe_lun().
 921  * 1. physicalsport == physport
 922  * 2. (phymask & (1 << physport)) == 0
 923  * The condition #2 is because LSI uses lowest PHY
 924  * number as the value of physical port when auto port
 925  * configuration.
 926  */
 927 #define IS_SAME_PORT(physicalport, physport, phymask, dynamicport) \
 928         ((physicalport == physport) || (dynamicport && (phymask & \
 929         (1 << physport))))
 930 
 931 _NOTE(MUTEX_PROTECTS_DATA(mptsas::m_mutex, mptsas))
 932 _NOTE(SCHEME_PROTECTS_DATA("safe sharing", mptsas::m_next))
 933 _NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_dip mptsas::m_tran))
 934 _NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_kmem_cache))
 935 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_io_dma_attr.dma_attr_sgllen))
 936 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_devid))
 937 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_productid))
 938 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_port_type))
 939 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_mpxio_enable))
 940 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_ntargets))
 941 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_instance))
 942 
 943 /*
 944  * These should eventually migrate into the mpt header files
 945  * that may become the /kernel/misc/mpt module...
 946  */
 947 #define mptsas_init_std_hdr(hdl, mp, DevHandle, Lun, ChainOffset, Function) \
 948         mptsas_put_msg_DevHandle(hdl, mp, DevHandle); \
 949         mptsas_put_msg_ChainOffset(hdl, mp, ChainOffset); \
 950         mptsas_put_msg_Function(hdl, mp, Function); \
 951         mptsas_put_msg_Lun(hdl, mp, Lun)
 952 
 953 #define mptsas_put_msg_DevHandle(hdl, mp, val) \
 954         ddi_put16(hdl, &(mp)->DevHandle, (val))
 955 #define mptsas_put_msg_ChainOffset(hdl, mp, val) \
 956         ddi_put8(hdl, &(mp)->ChainOffset, (val))
 957 #define mptsas_put_msg_Function(hdl, mp, val) \
 958         ddi_put8(hdl, &(mp)->Function, (val))
 959 #define mptsas_put_msg_Lun(hdl, mp, val) \
 960         ddi_put8(hdl, &(mp)->LUN[1], (val))


 968 #define MPTSAS_ENABLE_DRWE(hdl) \
 969         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 970                 MPI2_WRSEQ_FLUSH_KEY_VALUE); \
 971         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 972                 MPI2_WRSEQ_1ST_KEY_VALUE); \
 973         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 974                 MPI2_WRSEQ_2ND_KEY_VALUE); \
 975         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 976                 MPI2_WRSEQ_3RD_KEY_VALUE); \
 977         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 978                 MPI2_WRSEQ_4TH_KEY_VALUE); \
 979         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 980                 MPI2_WRSEQ_5TH_KEY_VALUE); \
 981         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
 982                 MPI2_WRSEQ_6TH_KEY_VALUE);
 983 
 984 /*
 985  * m_options flags
 986  */
 987 #define MPTSAS_OPT_PM           0x01    /* Power Management */


 988 
 989 /*
 990  * m_softstate flags
 991  */
 992 #define MPTSAS_SS_DRAINING              0x02
 993 #define MPTSAS_SS_QUIESCED              0x04
 994 #define MPTSAS_SS_MSG_UNIT_RESET        0x08
 995 #define MPTSAS_DID_MSG_UNIT_RESET       0x10
 996 
 997 /*









 998  * regspec defines.
 999  */
1000 #define CONFIG_SPACE    0       /* regset[0] - configuration space */
1001 #define IO_SPACE        1       /* regset[1] - used for i/o mapped device */
1002 #define MEM_SPACE       2       /* regset[2] - used for memory mapped device */
1003 #define BASE_REG2       3       /* regset[3] - used for 875 scripts ram */
1004 
1005 /*
1006  * Handy constants
1007  */
1008 #define FALSE           0
1009 #define TRUE            1

1010 #define UNDEFINED       -1
1011 #define FAILED          -2
1012 
1013 /*
1014  * power management.
1015  */
1016 #define MPTSAS_POWER_ON(mpt) { \
1017         pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
1018             PCI_PMCSR_D0); \
1019         delay(drv_usectohz(10000)); \
1020         (void) pci_restore_config_regs(mpt->m_dip); \
1021         mptsas_setup_cmd_reg(mpt); \
1022 }
1023 
1024 #define MPTSAS_POWER_OFF(mpt) { \
1025         (void) pci_save_config_regs(mpt->m_dip); \
1026         pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
1027             PCI_PMCSR_D3HOT); \
1028         mpt->m_power_level = PM_LEVEL_D3; \
1029 }


1088 #define ADDR2MPT(ap)            (TRAN2MPT(ADDR2TRAN(ap)))
1089 
1090 #define POLL_TIMEOUT            (2 * SCSI_POLL_TIMEOUT * 1000000)
1091 #define SHORT_POLL_TIMEOUT      (1000000)       /* in usec, about 1 secs */
1092 #define MPTSAS_QUIESCE_TIMEOUT  1               /* 1 sec */
1093 #define MPTSAS_PM_IDLE_TIMEOUT  60              /* 60 seconds */
1094 
1095 #define MPTSAS_GET_ISTAT(mpt)  (ddi_get32((mpt)->m_datap, \
1096                         &(mpt)->m_reg->HostInterruptStatus))
1097 
1098 #define MPTSAS_SET_SIGP(P) \
1099                 ClrSetBits(mpt->m_devaddr + NREG_ISTAT, 0, NB_ISTAT_SIGP)
1100 
1101 #define MPTSAS_RESET_SIGP(P) (void) ddi_get8(mpt->m_datap, \
1102                         (uint8_t *)(mpt->m_devaddr + NREG_CTEST2))
1103 
1104 #define MPTSAS_GET_INTCODE(P) (ddi_get32(mpt->m_datap, \
1105                         (uint32_t *)(mpt->m_devaddr + NREG_DSPS)))
1106 
1107 
1108 #define MPTSAS_START_CMD(mpt, req_desc_lo, req_desc_hi) \
1109         ddi_put32(mpt->m_datap, &mpt->m_reg->RequestDescriptorPostLow,\
1110             req_desc_lo);\
1111         ddi_put32(mpt->m_datap, &mpt->m_reg->RequestDescriptorPostHigh,\
1112             req_desc_hi);

1113 
1114 #define INTPENDING(mpt) \
1115         (MPTSAS_GET_ISTAT(mpt) & MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT)
1116 
1117 /*
1118  * Mask all interrupts to disable
1119  */
1120 #define MPTSAS_DISABLE_INTR(mpt)        \
1121         ddi_put32((mpt)->m_datap, &(mpt)->m_reg->HostInterruptMask, \
1122             (MPI2_HIM_RIM | MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1123 
1124 /*
1125  * Mask Doorbell and Reset interrupts to enable reply desc int.
1126  */
1127 #define MPTSAS_ENABLE_INTR(mpt) \
1128         ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, \
1129         (MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1130 
1131 #define MPTSAS_GET_NEXT_REPLY(mpt, index)  \
1132         &((uint64_t *)(void *)mpt->m_post_queue)[index]
1133 
1134 #define MPTSAS_GET_NEXT_FRAME(mpt, SMID) \
1135         (mpt->m_req_frame + (mpt->m_req_frame_size * SMID))
1136 
1137 #define ClrSetBits32(hdl, reg, clr, set) \
1138         ddi_put32(hdl, (reg), \
1139             ((ddi_get32(mpt->m_datap, (reg)) & ~(clr)) | (set)))
1140 
1141 #define ClrSetBits(reg, clr, set) \
1142         ddi_put8(mpt->m_datap, (uint8_t *)(reg), \
1143                 ((ddi_get8(mpt->m_datap, (uint8_t *)(reg)) & ~(clr)) | (set)))
1144 
1145 #define MPTSAS_WAITQ_RM(mpt, cmdp)      \
1146         if ((cmdp = mpt->m_waitq) != NULL) { \
1147                 /* If the queue is now empty fix the tail pointer */    \
1148                 if ((mpt->m_waitq = cmdp->cmd_linkp) == NULL) \
1149                         mpt->m_waitqtail = &mpt->m_waitq; \
1150                 cmdp->cmd_linkp = NULL; \
1151                 cmdp->cmd_queued = FALSE; \
1152         }
1153 
1154 #define MPTSAS_TX_WAITQ_RM(mpt, cmdp)   \
1155         if ((cmdp = mpt->m_tx_waitq) != NULL) { \
1156                 /* If the queue is now empty fix the tail pointer */    \
1157                 if ((mpt->m_tx_waitq = cmdp->cmd_linkp) == NULL) \
1158                         mpt->m_tx_waitqtail = &mpt->m_tx_waitq; \
1159                 cmdp->cmd_linkp = NULL; \
1160                 cmdp->cmd_queued = FALSE; \
1161         }
1162 
1163 /*
1164  * defaults for the global properties
1165  */
1166 #define DEFAULT_SCSI_OPTIONS    SCSI_OPTIONS_DR
1167 #define DEFAULT_TAG_AGE_LIMIT   2
1168 #define DEFAULT_WD_TICK         10
1169 
1170 /*
1171  * invalid hostid.
1172  */
1173 #define MPTSAS_INVALID_HOSTID  -1
1174 
1175 /*
1176  * Get/Set hostid from SCSI port configuration page
1177  */
1178 #define MPTSAS_GET_HOST_ID(configuration) (configuration & 0xFF)
1179 #define MPTSAS_SET_HOST_ID(hostid) (hostid | ((1 << hostid) << 16))
1180 
1181 /*
1182  * Config space.
1183  */
1184 #define MPTSAS_LATENCY_TIMER    0x40
1185 
1186 /*
1187  * Offset to firmware version
1188  */


1235  * response code tlr flag
1236  */
1237 #define MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF       0x02
1238 
1239 /*
1240  * System Events
1241  */
1242 #ifndef DDI_VENDOR_LSI
1243 #define DDI_VENDOR_LSI  "LSI"
1244 #endif  /* DDI_VENDOR_LSI */
1245 
1246 /*
1247  * Shared functions
1248  */
1249 int mptsas_save_cmd(struct mptsas *mpt, struct mptsas_cmd *cmd);
1250 void mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
1251 void mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
1252 void mptsas_log(struct mptsas *mpt, int level, char *fmt, ...);
1253 int mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime);
1254 int mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)());
1255 int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action,
1256         uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber,
1257         uint8_t pageversion, uint8_t pagelength, uint32_t
1258         SGEflagslength, uint32_t SGEaddress32);
1259 int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
1260         uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
1261         uint8_t pageversion, uint16_t extpagelength,
1262         uint32_t SGEflagslength, uint32_t SGEaddress32);
1263 int mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
1264         uint8_t type, int mode);
1265 int mptsas_check_flash(mptsas_t *mpt, caddr_t origfile, uint32_t size,
1266         uint8_t type, int mode);
1267 int mptsas_download_firmware();
1268 int mptsas_can_download_firmware();
1269 int mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep);
1270 void mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep);
1271 mptsas_phymask_t mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport);
1272 void mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd);
1273 int mptsas_check_acc_handle(ddi_acc_handle_t handle);
1274 int mptsas_check_dma_handle(ddi_dma_handle_t handle);
1275 void mptsas_fm_ereport(mptsas_t *mpt, char *detail);
1276 int mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
1277     ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
1278     uint32_t alloc_size, ddi_dma_cookie_t *cookiep);
1279 void mptsas_dma_addr_destroy(ddi_dma_handle_t *, ddi_acc_handle_t *);
1280 
1281 /*
1282  * impl functions
1283  */
1284 int mptsas_ioc_wait_for_response(mptsas_t *mpt);
1285 int mptsas_ioc_wait_for_doorbell(mptsas_t *mpt);
1286 int mptsas_ioc_reset(mptsas_t *mpt, int);
1287 int mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1288     ddi_acc_handle_t accessp);
1289 int mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1290     ddi_acc_handle_t accessp);
1291 int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action,
1292     uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber,
1293     uint8_t pageversion, uint8_t pagelength, uint32_t SGEflagslength,
1294     uint32_t SGEaddress32);
1295 int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
1296     uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
1297     uint8_t pageversion, uint16_t extpagelength,
1298     uint32_t SGEflagslength, uint32_t SGEaddress32);
1299 
1300 int mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd,
1301     struct scsi_pkt **pkt);
1302 void mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd);
1303 void mptsas_destroy_ioc_event_cmd(mptsas_t *mpt);
1304 void mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd);
1305 int mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
1306     uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
1307     caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...);
1308 
1309 int mptsas_ioc_task_management(mptsas_t *mpt, int task_type,
1310     uint16_t dev_handle, int lun, uint8_t *reply, uint32_t reply_size,
1311     int mode);
1312 int mptsas_send_event_ack(mptsas_t *mpt, uint32_t event, uint32_t eventcntx);
1313 void mptsas_send_pending_event_ack(mptsas_t *mpt);
1314 void mptsas_set_throttle(struct mptsas *mpt, mptsas_target_t *ptgt, int what);
1315 int mptsas_restart_ioc(mptsas_t *mpt);
1316 void mptsas_update_driver_data(struct mptsas *mpt);
1317 uint64_t mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun);
1318 
1319 /*
1320  * init functions
1321  */
1322 int mptsas_ioc_get_facts(mptsas_t *mpt);
1323 int mptsas_ioc_get_port_facts(mptsas_t *mpt, int port);
1324 int mptsas_ioc_enable_port(mptsas_t *mpt);
1325 int mptsas_ioc_enable_event_notification(mptsas_t *mpt);
1326 int mptsas_ioc_init(mptsas_t *mpt);
1327 
1328 /*
1329  * configuration pages operation
1330  */
1331 int mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
1332     uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
1333     uint8_t *physport, uint8_t *phynum, uint16_t *pdevhandle,
1334     uint16_t *slot_num, uint16_t *enclosure);
1335 int mptsas_get_sas_io_unit_page(mptsas_t *mpt);
1336 int mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt);
1337 int mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address,
1338     mptsas_smp_t *info);
1339 int mptsas_set_ioc_params(mptsas_t *mpt);
1340 int mptsas_get_manufacture_page5(mptsas_t *mpt);
1341 int mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address,
1342     uint64_t *sas_wwn, uint8_t *portwidth);
1343 int mptsas_get_bios_page3(mptsas_t *mpt,  uint32_t *bios_version);
1344 int
1345 mptsas_get_sas_phy_page0(mptsas_t *mpt, uint32_t page_address,
1346     smhba_info_t *info);
1347 int
1348 mptsas_get_sas_phy_page1(mptsas_t *mpt, uint32_t page_address,
1349     smhba_info_t *info);
1350 int
1351 mptsas_get_manufacture_page0(mptsas_t *mpt);
1352 void
1353 mptsas_create_phy_stats(mptsas_t *mpt, char *iport, dev_info_t *dip);
1354 void mptsas_destroy_phy_stats(mptsas_t *mpt);
1355 int mptsas_smhba_phy_init(mptsas_t *mpt);
1356 /*
1357  * RAID functions
1358  */
1359 int mptsas_get_raid_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol);
1360 int mptsas_get_raid_info(mptsas_t *mpt);
1361 int mptsas_get_physdisk_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol,
1362     uint8_t physdisknum);
1363 int mptsas_delete_volume(mptsas_t *mpt, uint16_t volid);
1364 void mptsas_raid_action_system_shutdown(mptsas_t *mpt);
1365 
1366 #define MPTSAS_IOCSTATUS(status) (status & MPI2_IOCSTATUS_MASK)
1367 /*
1368  * debugging.
1369  */
1370 #if defined(MPTSAS_DEBUG)
1371 
1372 void mptsas_printf(char *fmt, ...);

1373 
1374 #define MPTSAS_DBGPR(m, args)   \
1375         if (mptsas_debug_flags & (m)) \
1376                 mptsas_printf args


1377 #else   /* ! defined(MPTSAS_DEBUG) */
1378 #define MPTSAS_DBGPR(m, args)
1379 #endif  /* defined(MPTSAS_DEBUG) */
1380 
1381 #define NDBG0(args)     MPTSAS_DBGPR(0x01, args)        /* init */
1382 #define NDBG1(args)     MPTSAS_DBGPR(0x02, args)        /* normal running */
1383 #define NDBG2(args)     MPTSAS_DBGPR(0x04, args)        /* property handling */
1384 #define NDBG3(args)     MPTSAS_DBGPR(0x08, args)        /* pkt handling */
1385 
1386 #define NDBG4(args)     MPTSAS_DBGPR(0x10, args)        /* kmem alloc/free */
1387 #define NDBG5(args)     MPTSAS_DBGPR(0x20, args)        /* polled cmds */
1388 #define NDBG6(args)     MPTSAS_DBGPR(0x40, args)        /* interrupts */
1389 #define NDBG7(args)     MPTSAS_DBGPR(0x80, args)        /* queue handling */
1390 
1391 #define NDBG8(args)     MPTSAS_DBGPR(0x0100, args)      /* arq */
1392 #define NDBG9(args)     MPTSAS_DBGPR(0x0200, args)      /* Tagged Q'ing */
1393 #define NDBG10(args)    MPTSAS_DBGPR(0x0400, args)      /* halting chip */
1394 #define NDBG11(args)    MPTSAS_DBGPR(0x0800, args)      /* power management */
1395 
1396 #define NDBG12(args)    MPTSAS_DBGPR(0x1000, args)      /* enumeration */
1397 #define NDBG13(args)    MPTSAS_DBGPR(0x2000, args)      /* configuration page */
1398 #define NDBG14(args)    MPTSAS_DBGPR(0x4000, args)      /* LED control */
1399 #define NDBG15(args)    MPTSAS_DBGPR(0x8000, args)
1400 
1401 #define NDBG16(args)    MPTSAS_DBGPR(0x010000, args)
1402 #define NDBG17(args)    MPTSAS_DBGPR(0x020000, args)    /* scatter/gather */
1403 #define NDBG18(args)    MPTSAS_DBGPR(0x040000, args)
1404 #define NDBG19(args)    MPTSAS_DBGPR(0x080000, args)    /* handshaking */
1405 
1406 #define NDBG20(args)    MPTSAS_DBGPR(0x100000, args)    /* events */
1407 #define NDBG21(args)    MPTSAS_DBGPR(0x200000, args)    /* dma */
1408 #define NDBG22(args)    MPTSAS_DBGPR(0x400000, args)    /* reset */
1409 #define NDBG23(args)    MPTSAS_DBGPR(0x800000, args)    /* abort */
1410 
1411 #define NDBG24(args)    MPTSAS_DBGPR(0x1000000, args)   /* capabilities */
1412 #define NDBG25(args)    MPTSAS_DBGPR(0x2000000, args)   /* flushing */
1413 #define NDBG26(args)    MPTSAS_DBGPR(0x4000000, args)
1414 #define NDBG27(args)    MPTSAS_DBGPR(0x8000000, args)
1415 
1416 #define NDBG28(args)    MPTSAS_DBGPR(0x10000000, args)  /* hotplug */
1417 #define NDBG29(args)    MPTSAS_DBGPR(0x20000000, args)  /* timeouts */
1418 #define NDBG30(args)    MPTSAS_DBGPR(0x40000000, args)  /* mptsas_watch */
1419 #define NDBG31(args)    MPTSAS_DBGPR(0x80000000, args)  /* negotations */
1420 
1421 /*
1422  * auto request sense
1423  */
1424 #define RQ_MAKECOM_COMMON(pkt, flag, cmd) \
1425         (pkt)->pkt_flags = (flag), \
1426         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_cmd = (cmd), \
1427         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
1428             (pkt)->pkt_address.a_lun
1429 
1430 #define RQ_MAKECOM_G0(pkt, flag, cmd, addr, cnt) \
1431         RQ_MAKECOM_COMMON((pkt), (flag), (cmd)), \
1432         FORMG0ADDR(((union scsi_cdb *)(pkt)->pkt_cdbp), (addr)), \
1433         FORMG0COUNT(((union scsi_cdb *)(pkt)->pkt_cdbp), (cnt))
1434 
1435 
1436 #ifdef  __cplusplus
1437 }
1438 #endif
1439 
1440 #endif  /* _SYS_SCSI_ADAPTERS_MPTVAR_H */


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
  27  */
  28 
  29 /*
  30  * Copyright (c) 2000 to 2010, LSI Corporation.
  31  * All rights reserved.
  32  *
  33  * Redistribution and use in source and binary forms of all code within
  34  * this file that is exclusively owned by LSI, with or without
  35  * modification, is permitted provided that, in addition to the CDDL 1.0
  36  * License requirements, the following conditions are met:
  37  *
  38  *    Neither the name of the author nor the names of its contributors may be
  39  *    used to endorse or promote products derived from this software without
  40  *    specific prior written permission.
  41  *
  42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  45  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  46  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  47  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  48  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  49  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  50  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  51  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  52  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  53  * DAMAGE.
  54  */
  55 
  56 #ifndef _SYS_SCSI_ADAPTERS_MPTSAS3_VAR_H
  57 #define _SYS_SCSI_ADAPTERS_MPTSAS3_VAR_H
  58 
  59 #include <sys/byteorder.h>
  60 #include <sys/queue.h>
  61 #include <sys/isa_defs.h>
  62 #include <sys/sunmdi.h>
  63 #include <sys/mdi_impldefs.h>
  64 #include <sys/scsi/adapters/mpt_sas3/mptsas3_hash.h>
  65 #include <sys/scsi/adapters/mpt_sas3/mptsas3_ioctl.h>
  66 #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_tool.h>
  67 #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_cnfg.h>
  68 
  69 #ifdef  __cplusplus
  70 extern "C" {
  71 #endif
  72 
  73 /*
  74  * Compile options
  75  */
  76 #ifdef DEBUG
  77 #define MPTSAS_DEBUG            /* turn on debugging code */
  78 #endif  /* DEBUG */
  79 
  80 #define MPTSAS_INITIAL_SOFT_SPACE       4
  81 
  82 #define MAX_MPI_PORTS           16
  83 
  84 /*
  85  * Note below macro definition and data type definition
  86  * are used for phy mask handling, it should be changed
  87  * simultaneously.


 126 
 127 /*
 128  * If the HBA supports DMA or bus-mastering, you may have your own
 129  * scatter-gather list for physically non-contiguous memory in one
 130  * I/O operation; if so, there's probably a size for that list.
 131  * It must be placed in the ddi_dma_lim_t structure, so that the system
 132  * DMA-support routines can use it to break up the I/O request, so we
 133  * define it here.
 134  */
 135 #if defined(__sparc)
 136 #define MPTSAS_MAX_DMA_SEGS     1
 137 #define MPTSAS_MAX_CMD_SEGS     1
 138 #else
 139 #define MPTSAS_MAX_DMA_SEGS     256
 140 #define MPTSAS_MAX_CMD_SEGS     257
 141 #endif
 142 #define MPTSAS_MAX_FRAME_SGES(mpt) \
 143         (((mpt->m_req_frame_size - (sizeof (MPI2_SCSI_IO_REQUEST))) / 8) + 1)
 144 
 145 /*
 146  * Calculating how many 64-bit DMA simple elements can be stored in the first
 147  * frame. Note that msg_scsi_io_request contains 2 double-words (8 bytes) for
 148  * element storage.  And 64-bit dma element is 3 double-words (12 bytes) in
 149  * size. IEEE 64-bit dma element used for SAS3 controllers is 4 double-words
 150  * (16 bytes).
 151  */
 152 #define MPTSAS_MAX_FRAME_SGES64(mpt) \
 153         ((mpt->m_req_frame_size - \
 154         sizeof (MPI2_SCSI_IO_REQUEST) + sizeof (MPI2_SGE_IO_UNION)) / \
 155         (mpt->m_MPI25 ? sizeof (MPI2_IEEE_SGE_SIMPLE64) : \
 156         sizeof (MPI2_SGE_SIMPLE64)))
 157 
 158 /*
 159  * Scatter-gather list structure defined by HBA hardware
 160  */
 161 typedef struct NcrTableIndirect {       /* Table Indirect entries */
 162         uint32_t count;         /* 24 bit count */
 163         union {
 164                 uint32_t address32;     /* 32 bit address */
 165                 struct {
 166                         uint32_t Low;
 167                         uint32_t High;
 168                 } address64;            /* 64 bit address */
 169         } addr;
 170 } mptti_t;
 171 
 172 /*
 173  * preferred pkt_private length in 64-bit quantities
 174  */
 175 #ifdef  _LP64
 176 #define PKT_PRIV_SIZE   2


 188  * get offset of item in structure
 189  */
 190 #define MPTSAS_GET_ITEM_OFF(type, member) ((size_t)(&((type *)0)->member))
 191 
 192 /*
 193  * WWID provided by LSI firmware is generated by firmware but the WWID is not
 194  * IEEE NAA standard format, OBP has no chance to distinguish format of unit
 195  * address. According LSI's confirmation, the top nibble of RAID WWID is
 196  * meanless, so the consensus between Solaris and OBP is to replace top nibble
 197  * of WWID provided by LSI to "3" always to hint OBP that this is a RAID WWID
 198  * format unit address.
 199  */
 200 #define MPTSAS_RAID_WWID(wwid) \
 201         ((wwid & 0x0FFFFFFFFFFFFFFF) | 0x3000000000000000)
 202 
 203 typedef struct mptsas_target_addr {
 204         uint64_t mta_wwn;
 205         mptsas_phymask_t mta_phymask;
 206 } mptsas_target_addr_t;
 207 
 208 TAILQ_HEAD(mptsas_active_cmdq, mptsas_cmd);
 209 typedef struct mptsas_active_cmdq mptsas_active_cmdq_t;
 210 
 211 typedef struct mptsas_target {
 212                 kmutex_t                m_t_mutex;
 213                 mptsas_target_addr_t    m_addr;
 214                 refhash_link_t          m_link;

 215                 uint16_t                m_devhdl;
 216                 uint32_t                m_deviceinfo;

 217                 uint32_t                m_dups;
 218                 uint8_t                 m_phynum;
 219                 mptsas_active_cmdq_t    m_active_cmdq;
 220                 int32_t                 m_t_throttle;
 221                 int32_t                 m_t_ncmds;
 222                 int32_t                 m_reset_delay;
 223                 int32_t                 m_t_nwait;
 224                 uint16_t                m_io_flags;


 225                 uint16_t                m_enclosure;
 226                 uint16_t                m_slot_num;
 227                 uint16_t                m_qfull_retry_interval;
 228                 uint8_t                 m_qfull_retries;
 229                 uint8_t                 m_tgt_unconfigured;
 230                 uint8_t                 m_led_status;
 231                 uint8_t                 m_dr_flag;
 232 } mptsas_target_t;
 233 
 234 /*
 235  * If you change this structure, be sure that mptsas_smp_target_copy()
 236  * does the right thing.
 237  */
 238 typedef struct mptsas_smp {
 239         mptsas_target_addr_t    m_addr;
 240         refhash_link_t          m_link;
 241         uint16_t                m_devhdl;
 242         uint32_t                m_deviceinfo;
 243         uint16_t                m_pdevhdl;
 244         uint32_t                m_pdevinfo;
 245 } mptsas_smp_t;
 246 
 247 typedef struct mptsas_cache_frames {
 248         ddi_dma_handle_t m_dma_hdl;
 249         ddi_acc_handle_t m_acc_hdl;
 250         caddr_t m_frames_addr;
 251         uint64_t m_phys_addr;
 252 } mptsas_cache_frames_t;
 253 
 254 typedef struct  mptsas_cmd {
 255         uint_t                  cmd_flags;      /* flags from scsi_init_pkt */
 256         ddi_dma_handle_t        cmd_dmahandle;  /* dma handle */
 257         ddi_dma_cookie_t        cmd_cookie;
 258         uint_t                  cmd_cookiec;
 259         uint_t                  cmd_winindex;
 260         uint_t                  cmd_nwin;
 261         uint_t                  cmd_cur_cookie;
 262         off_t                   cmd_dma_offset;
 263         size_t                  cmd_dma_len;
 264         uint32_t                cmd_totaldmacount;
 265         caddr_t                 cmd_arq_buf;






 266 
 267         int                     cmd_pkt_flags;
 268 
 269         /* pending expiration time for command in active slot */
 270         hrtime_t                cmd_active_expiration;
 271         TAILQ_ENTRY(mptsas_cmd) cmd_active_link;
 272 
 273         struct scsi_pkt         *cmd_pkt;
 274         struct scsi_arq_status  cmd_scb;
 275         uchar_t                 cmd_cdblen;     /* length of cdb */
 276         uchar_t                 cmd_rqslen;     /* len of requested rqsense */
 277         uchar_t                 cmd_privlen;
 278         uint16_t                cmd_extrqslen;  /* len of extended rqsense */
 279         uint16_t                cmd_extrqschunks; /* len in map chunks */
 280         uint16_t                cmd_extrqsidx;  /* Index into map */
 281         uint_t                  cmd_scblen;
 282         uint32_t                cmd_dmacount;
 283         uint64_t                cmd_dma_addr;
 284         uchar_t                 cmd_age;
 285         ushort_t                cmd_qfull_retries;
 286         uchar_t                 cmd_queued;     /* true if queued */
 287         struct mptsas_cmd       *cmd_linkp;
 288         mptti_t                 *cmd_sg; /* Scatter/Gather structure */
 289         uchar_t                 cmd_cdb[SCSI_CDB_SIZE];
 290         uint64_t                cmd_pkt_private[PKT_PRIV_LEN];
 291         uint32_t                cmd_slot;
 292         uint32_t                ioc_cmd_slot;
 293         uint8_t                 cmd_rpqidx;
 294 
 295         mptsas_cache_frames_t   *cmd_extra_frames;
 296 
 297         uint32_t                cmd_rfm;
 298         mptsas_target_t         *cmd_tgt_addr;
 299 } mptsas_cmd_t;
 300 
 301 /*
 302  * These are the defined cmd_flags for this structure.
 303  */
 304 #define CFLAG_CMDDISC           0x000001 /* cmd currently disconnected */
 305 #define CFLAG_WATCH             0x000002 /* watchdog time for this command */
 306 #define CFLAG_FINISHED          0x000004 /* command completed */
 307 #define CFLAG_CHKSEG            0x000008 /* check cmd_data within seg */
 308 #define CFLAG_COMPLETED         0x000010 /* completion routine called */
 309 #define CFLAG_PREPARED          0x000020 /* pkt has been init'ed */
 310 #define CFLAG_IN_TRANSPORT      0x000040 /* in use by host adapter driver */
 311 #define CFLAG_RESTORE_PTRS      0x000080 /* implicit restore ptr on reconnect */
 312 #define CFLAG_ARQ_IN_PROGRESS   0x000100 /* auto request sense in progress */
 313 #define CFLAG_TRANFLAG          0x0001ff /* covers transport part of flags */
 314 #define CFLAG_TM_CMD            0x000200 /* cmd is a task management command */
 315 #define CFLAG_CMDARQ            0x000400 /* cmd is a 'rqsense' command */
 316 #define CFLAG_DMAVALID          0x000800 /* dma mapping valid */
 317 #define CFLAG_DMASEND           0x001000 /* data is going 'out' */
 318 #define CFLAG_CMDIOPB           0x002000 /* this is an 'iopb' packet */
 319 #define CFLAG_CDBEXTERN         0x004000 /* cdb kmem_alloc'd */
 320 #define CFLAG_SCBEXTERN         0x008000 /* scb kmem_alloc'd */
 321 #define CFLAG_FREE              0x010000 /* packet is on free list */
 322 #define CFLAG_PRIVEXTERN        0x020000 /* target private kmem_alloc'd */
 323 #define CFLAG_DMA_PARTIAL       0x040000 /* partial xfer OK */
 324 #define CFLAG_QFULL_STATUS      0x080000 /* pkt got qfull status */
 325 #define CFLAG_TIMEOUT           0x100000 /* passthru/config command timeout */
 326 #define CFLAG_PMM_RECEIVED      0x200000 /* use cmd_pmm* for saving pointers */
 327 #define CFLAG_RETRY             0x400000 /* cmd has been retried */
 328 #define CFLAG_CMDIOC            0x800000 /* cmd is just for for ioc, no io */

 329 #define CFLAG_PASSTHRU          0x2000000 /* cmd is a passthrough command */
 330 #define CFLAG_XARQ              0x4000000 /* cmd requests for extra sense */
 331 #define CFLAG_CMDACK            0x8000000 /* cmd for event ack */
 332 #define CFLAG_TXQ               0x10000000 /* cmd queued in the tx_waitq */
 333 #define CFLAG_FW_CMD            0x20000000 /* cmd is a fw up/down command */
 334 #define CFLAG_CONFIG            0x40000000 /* cmd is for config header/page */
 335 #define CFLAG_FW_DIAG           0x80000000 /* cmd is for FW diag buffers */
 336 
 337 #ifdef MPTSAS_DEBUG
 338 /* Could be used with cmn_err %b */
 339 #define CFLAGS_DEBUG_BITS "\\020\\0CmdDisc\\1Watch\\2Finished\\3ChkSeg" \
 340         "\\4Cmpltd\\5Prepd\\6InTran\\7RestPtrs\\8ARQIP\\9TM\\10CArq" \
 341         "\\11DMAVal\\12DMASnd\\13CIopb\\14CDBExt\\15SCBExt\\16Free" \
 342         "\\17PrivExt\\18DMAPrtl\\19QFull\\20Tout\\21PMMRcv\\22Retry" \
 343         "\\23CIoc\\25PThru\\26XArq\\27CAck\\28TXq\\29FWCmd\\30Config\\31FWDiag"
 344 #endif
 345 
 346 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE                     8
 347 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK                     0xC0
 348 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL                       0x00
 349 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE                       0x40
 350 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT             0x80
 351 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT            0xC0
 352 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_2B          0x00
 353 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_4B          0x01
 354 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_6B          0x10
 355 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_8B          0x20
 356 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT_SIZE                0x30
 357 
 358 #define MPTSAS_HASH_ARRAY_SIZE  16
 359 /*
 360  * hash table definition
 361  */
 362 
 363 #define MPTSAS_HASH_FIRST       0xffff
 364 #define MPTSAS_HASH_NEXT        0x0000
 365 
 366 typedef struct mptsas_dma_alloc_state
 367 {
 368         ddi_dma_handle_t        handle;
 369         caddr_t                 memp;
 370         size_t                  size;
 371         ddi_acc_handle_t        accessp;
 372         ddi_dma_cookie_t        cookie;
 373 } mptsas_dma_alloc_state_t;
 374 
 375 /*
 376  * passthrough request structure
 377  */
 378 typedef struct mptsas_pt_request {
 379         uint8_t *request;
 380         uint32_t request_size;
 381         uint32_t data_size;
 382         uint32_t dataout_size;
 383         uint8_t direction;
 384         uint8_t simple;
 385         uint16_t sgl_offset;
 386         ddi_dma_cookie_t data_cookie;
 387         ddi_dma_cookie_t dataout_cookie;
 388 } mptsas_pt_request_t;
 389 
 390 /*
 391  * config page request structure
 392  */
 393 typedef struct mptsas_config_request {
 394         uint32_t        page_address;
 395         uint8_t         action;
 396         uint8_t         page_type;
 397         uint8_t         page_number;
 398         uint8_t         page_length;
 399         uint8_t         page_version;
 400         uint8_t         ext_page_type;
 401         uint16_t        ext_page_length;
 402 } mptsas_config_request_t;
 403 
 404 typedef struct mptsas_fw_diagnostic_buffer {
 405         mptsas_dma_alloc_state_t        buffer_data;


 551 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::event))
 552 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::physport))
 553 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::devhdl))
 554 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::object))
 555 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas_topo_change_list_t::flags))
 556 
 557 /*
 558  * Status types when calling mptsas_get_target_device_info
 559  */
 560 #define DEV_INFO_SUCCESS                0x0
 561 #define DEV_INFO_FAIL_PAGE0             0x1
 562 #define DEV_INFO_WRONG_DEVICE_TYPE      0x2
 563 #define DEV_INFO_PHYS_DISK              0x3
 564 #define DEV_INFO_FAIL_ALLOC             0x4
 565 
 566 /*
 567  * mpt hotplug event defines
 568  */
 569 #define MPTSAS_DR_EVENT_RECONFIG_TARGET 0x01
 570 #define MPTSAS_DR_EVENT_OFFLINE_TARGET  0x02
 571 #define MPTSAS_DR_EVENT_REMOVE_HANDLE   0x04
 572 
 573 /*
 574  * SMP target hotplug events
 575  */
 576 #define MPTSAS_DR_EVENT_RECONFIG_SMP    0x10
 577 #define MPTSAS_DR_EVENT_OFFLINE_SMP     0x20
 578 #define MPTSAS_DR_EVENT_MASK            0x3F
 579 
 580 /*
 581  * mpt hotplug status definition for m_dr_flag
 582  */
 583 
 584 /*
 585  * MPTSAS_DR_INACTIVE
 586  *
 587  * The target is in a normal operating state.
 588  * No dynamic reconfiguration operation is in progress.
 589  */
 590 #define MPTSAS_DR_INACTIVE                              0x0
 591 /*


 645         uint8_t         port_num;
 646         kstat_t         *phy_stats;
 647         uint32_t        invalid_dword_count;
 648         uint32_t        running_disparity_error_count;
 649         uint32_t        loss_of_dword_sync_count;
 650         uint32_t        phy_reset_problem_count;
 651         void            *mpt;
 652 } smhba_info_t;
 653 
 654 typedef struct mptsas_phy_info {
 655         uint8_t                 port_num;
 656         uint8_t                 port_flags;
 657         uint16_t                ctrl_devhdl;
 658         uint32_t                phy_device_type;
 659         uint16_t                attached_devhdl;
 660         mptsas_phymask_t        phy_mask;
 661         smhba_info_t            smhba_info;
 662 } mptsas_phy_info_t;
 663 
 664 
 665 typedef struct mptsas_thread_arg {
 666         void            *mpt;
 667         uint32_t        t;
 668 } mptsas_thread_arg_t;
 669 
 670 typedef struct mptsas_done_list {
 671         mptsas_cmd_t            *dl_q;
 672         mptsas_cmd_t            **dl_tail;
 673         uint32_t                dl_len;
 674 } mptsas_done_list_t;
 675 
 676 #define MPTSAS_DONEQ_THREAD_ACTIVE      0x1
 677 typedef struct mptsas_doneq_thread_list {
 678         mptsas_done_list_t      dlist;

 679         kthread_t               *threadp;
 680         kcondvar_t              cv;
 681         ushort_t                reserv1;
 682         uint32_t                reserv2;
 683         kmutex_t                mutex;
 684         uint32_t                flag;
 685         mptsas_thread_arg_t     arg;

 686 } mptsas_doneq_thread_list_t;
 687 
 688 typedef struct mptsas_reply_pqueue {
 689         kmutex_t                rpq_mutex;
 690         uint8_t                 rpq_num;
 691         caddr_t                 rpq_queue; /* Pointer to this queue base */
 692         uint32_t                rpq_index; /* Index of next replyq entry */
 693         uint32_t                rpq_ncmds; /* Number of outstanding commands */
 694         mptsas_done_list_t      rpq_dlist;
 695         uint32_t                rpq_intr_count;
 696         uint32_t                rpq_intr_unclaimed;
 697         uint32_t                rpq_intr_mutexbusy;
 698 } mptsas_reply_pqueue_t;
 699 
 700 
 701 typedef struct mptsas_tx_waitqueue {
 702         kmutex_t        txwq_mutex;
 703         kcondvar_t      txwq_cv;
 704         kcondvar_t      txwq_drain_cv;
 705         kthread_t       *txwq_threadp;
 706         mptsas_cmd_t    *txwq_cmdq;     /* TX cmd queue for active request */
 707         mptsas_cmd_t    **txwq_qtail;   /* tx_wait queue tail ptr */
 708         uint32_t        txwq_len;       /* TX queue length */
 709         mptsas_thread_arg_t     arg;
 710         uint8_t         txwq_active;    /* Thread active flag */
 711         uint8_t         txwq_draining;  /* TX queue draining flag */
 712         uint8_t         txwq_wdrain;
 713 } mptsas_tx_waitqueue_t;
 714 
 715 #define NUM_TX_WAITQ    2
 716 
 717 typedef struct mptsas {
 718         int             m_instance;
 719 
 720         struct mptsas *m_next;
 721 
 722         scsi_hba_tran_t         *m_tran;
 723         smp_hba_tran_t          *m_smptran;
 724         kmutex_t                m_mutex;
 725         kmutex_t                m_passthru_mutex;
 726         kcondvar_t              m_cv;
 727         kcondvar_t              m_passthru_cv;
 728         kcondvar_t              m_fw_cv;
 729         kcondvar_t              m_config_cv;
 730         kcondvar_t              m_fw_diag_cv;
 731         dev_info_t              *m_dip;
 732 
 733         /*
 734          * soft state flags
 735          */
 736         uint_t          m_softstate;
 737 
 738         refhash_t       *m_targets;
 739         refhash_t       *m_smp_targets;
 740 
 741         m_raidconfig_t  m_raidconfig[MPTSAS_MAX_RAIDCONFIGS];
 742         uint8_t         m_num_raid_configs;
 743         uint8_t         m_pref_tx_waitq;
 744 
 745         struct mptsas_slots *m_active;  /* outstanding cmds */
 746 
 747         mptsas_cmd_t    *m_waitq;       /* cmd queue for active request */
 748         mptsas_cmd_t    **m_waitqtail;  /* wait queue tail ptr */
 749         mptsas_tx_waitqueue_t   m_tx_waitq[NUM_TX_WAITQ];
 750         uint16_t                m_txwq_thread_threshold;
 751         uint16_t                m_txwq_thread_n;
 752         uint8_t                 m_txwq_enabled;
 753         uint8_t                 m_txwq_allow_q_jumping;
 754         mptsas_done_list_t      m_dlist; /* List of completed commands */


 755 
 756         /*
 757          * variables for helper threads (fan-out interrupts)
 758          */
 759         mptsas_doneq_thread_list_t      *m_doneq_thread_id;
 760         uint16_t                m_doneq_thread_n;
 761         uint16_t                m_doneq_next_thread;
 762         uint32_t                m_doneq_thread_threshold;
 763         uint32_t                m_doneq_length_threshold;
 764         kcondvar_t              m_qthread_cv;
 765         kmutex_t                m_qthread_mutex;

 766 
 767         uint32_t                m_ncmds; /* number of outstanding commands */
 768         uint32_t                m_ncstarted; /* ncmds started per interval */
 769         uint32_t                m_lncstarted; /* record of last value */
 770         m_event_struct_t *m_ioc_event_cmdq;     /* cmd queue for ioc event */
 771         m_event_struct_t **m_ioc_event_cmdtail; /* ioc cmd queue tail */
 772 
 773         ddi_acc_handle_t m_datap;       /* operating regs data access handle */
 774 
 775         struct _MPI2_SYSTEM_INTERFACE_REGS      *m_reg;
 776 
 777         ushort_t        m_devid;        /* device id of chip. */
 778         uchar_t         m_revid;        /* revision of chip. */
 779         uint16_t        m_svid;         /* subsystem Vendor ID of chip */
 780         uint16_t        m_ssid;         /* subsystem Device ID of chip */
 781 
 782         uchar_t         m_sync_offset;  /* default offset for this chip. */
 783 
 784         timeout_id_t    m_quiesce_timeid;
 785 
 786         ddi_dma_handle_t m_dma_req_frame_hdl;
 787         ddi_acc_handle_t m_acc_req_frame_hdl;
 788         ddi_dma_handle_t m_dma_req_sense_hdl;
 789         ddi_acc_handle_t m_acc_req_sense_hdl;
 790         ddi_dma_handle_t m_dma_reply_frame_hdl;
 791         ddi_acc_handle_t m_acc_reply_frame_hdl;
 792         ddi_dma_handle_t m_dma_free_queue_hdl;
 793         ddi_acc_handle_t m_acc_free_queue_hdl;
 794         ddi_dma_handle_t m_dma_post_queue_hdl;
 795         ddi_acc_handle_t m_acc_post_queue_hdl;
 796         uint8_t         m_dma_flags;
 797 
 798         /*
 799          * list of reset notification requests
 800          */
 801         struct scsi_reset_notify_entry  *m_reset_notify_listf;
 802 
 803         /*
 804          * qfull handling
 805          */
 806         timeout_id_t    m_restart_cmd_timeid;
 807 
 808         /*
 809          * scsi reset delay per bus
 810          */
 811         uint_t          m_scsi_reset_delay;
 812 
 813         int             m_pm_idle_delay;
 814 
 815         uchar_t         m_polled_intr;  /* intr was polled. */
 816         uchar_t         m_suspended;    /* true if driver is suspended */
 817 
 818         struct kmem_cache *m_kmem_cache;
 819         struct kmem_cache *m_cache_frames;
 820 
 821         /*
 822          * hba options.
 823          */
 824         uint_t          m_options;
 825 


 826         int             m_power_level;  /* current power level */
 827 
 828         int             m_busy;         /* power management busy state */
 829 
 830         off_t           m_pmcsr_offset; /* PMCSR offset */
 831 
 832         ddi_acc_handle_t m_config_handle;
 833 
 834         ddi_dma_attr_t          m_io_dma_attr;  /* Used for data I/O */
 835         ddi_dma_attr_t          m_msg_dma_attr; /* Used for message frames */
 836         ddi_device_acc_attr_t   m_dev_acc_attr;
 837         ddi_device_acc_attr_t   m_reg_acc_attr;
 838 
 839         /*
 840          * request/reply variables
 841          */
 842         caddr_t         m_req_frame;
 843         uint64_t        m_req_frame_dma_addr;
 844         caddr_t         m_req_sense;
 845         caddr_t         m_extreq_sense;
 846         uint64_t        m_req_sense_dma_addr;
 847         caddr_t         m_reply_frame;
 848         uint64_t        m_reply_frame_dma_addr;
 849         caddr_t         m_free_queue;
 850         uint64_t        m_free_queue_dma_addr;
 851         caddr_t         m_post_queue;
 852         uint64_t        m_post_queue_dma_addr;
 853         struct map      *m_erqsense_map;
 854         mptsas_reply_pqueue_t   *m_rep_post_queues;
 855 
 856         m_replyh_arg_t *m_replyh_args;
 857 
 858         uint16_t        m_max_requests;
 859         uint16_t        m_req_frame_size;
 860         uint16_t        m_req_sense_size;
 861 
 862         /*
 863          * Max frames per request reported in IOC Facts
 864          */
 865         uint8_t         m_max_chain_depth;
 866         /*
 867          * Max frames per request which is used in reality. It's adjusted
 868          * according DMA SG length attribute, and shall not exceed the
 869          * m_max_chain_depth.
 870          */
 871         uint8_t         m_max_request_frames;
 872         uint8_t         m_max_msix_vectors;
 873         uint8_t         m_reply_frame_size;
 874         uint8_t         m_post_reply_qcount;
 875 
 876         uint16_t        m_free_queue_depth;
 877         uint16_t        m_post_queue_depth;
 878         uint16_t        m_max_replies;
 879         uint32_t        m_free_index;


 880         uint32_t        m_ioc_capabilities;
 881 
 882         /*
 883          * Housekeeping.
 884          */
 885         uint64_t        m_interrupt_count;
 886         uint32_t        m_unclaimed_pm_interrupt_count;
 887         uint32_t        m_unclaimed_polled_interrupt_count;
 888         uint32_t        m_unclaimed_no_interrupt_count;
 889         uint32_t        m_unclaimed_nocmd_interrupt_count;
 890 
 891         /*
 892          * indicates if the firmware was upload by the driver
 893          * at boot time
 894          */
 895         ushort_t        m_fwupload;
 896 
 897         uint16_t        m_productid;
 898 
 899         /*
 900          * per instance data structures for dma memory resources for
 901          * MPI handshake protocol. only one handshake cmd can run at a time.
 902          */
 903         ddi_dma_handle_t        m_hshk_dma_hdl;
 904         ddi_acc_handle_t        m_hshk_acc_hdl;
 905         caddr_t                 m_hshk_memp;
 906         size_t                  m_hshk_dma_size;
 907 
 908         /* Firmware version on the card at boot time */
 909         uint32_t                m_fwversion;
 910 
 911         /* MSI specific fields */


 945         uint8_t                 m_done_traverse_dev;
 946         uint8_t                 m_done_traverse_smp;
 947         int                     m_diag_action_in_progress;
 948         uint16_t                m_dev_handle;
 949         uint16_t                m_smp_devhdl;
 950 
 951         /*
 952          * Event recording
 953          */
 954         uint8_t                 m_event_index;
 955         uint32_t                m_event_number;
 956         uint32_t                m_event_mask[4];
 957         mptsas_event_entry_t    m_events[MPTSAS_EVENT_QUEUE_SIZE];
 958 
 959         /*
 960          * FW diag Buffer List
 961          */
 962         mptsas_fw_diagnostic_buffer_t
 963                 m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_COUNT];
 964 
 965         /* GEN3 support */
 966         uint8_t                 m_MPI25;
 967 
 968         /*
 969          * Event Replay flag (MUR support)
 970          */
 971         uint8_t                 m_event_replay;
 972 
 973         /*
 974          * IR Capable flag
 975          */
 976         uint8_t                 m_ir_capable;
 977 
 978         /*
 979          * Is HBA processing a diag reset?
 980          */
 981         uint8_t                 m_in_reset;
 982 
 983         /*
 984          * per instance cmd data structures for task management cmds
 985          */
 986         m_event_struct_t        m_event_task_mgmt;      /* must be last */
 987                                                         /* ... scsi_pkt_size */


 992  * Only one of below two conditions is satisfied, we
 993  * think the target is associated to the iport and
 994  * allow call into mptsas_probe_lun().
 995  * 1. physicalsport == physport
 996  * 2. (phymask & (1 << physport)) == 0
 997  * The condition #2 is because LSI uses lowest PHY
 998  * number as the value of physical port when auto port
 999  * configuration.
1000  */
1001 #define IS_SAME_PORT(physicalport, physport, phymask, dynamicport) \
1002         ((physicalport == physport) || (dynamicport && (phymask & \
1003         (1 << physport))))
1004 
1005 _NOTE(MUTEX_PROTECTS_DATA(mptsas::m_mutex, mptsas))
1006 _NOTE(SCHEME_PROTECTS_DATA("safe sharing", mptsas::m_next))
1007 _NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_dip mptsas::m_tran))
1008 _NOTE(SCHEME_PROTECTS_DATA("stable data", mptsas::m_kmem_cache))
1009 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_io_dma_attr.dma_attr_sgllen))
1010 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_devid))
1011 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_productid))

1012 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_mpxio_enable))

1013 _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_instance))
1014 
1015 /*
1016  * These should eventually migrate into the mpt header files
1017  * that may become the /kernel/misc/mpt module...
1018  */
1019 #define mptsas_init_std_hdr(hdl, mp, DevHandle, Lun, ChainOffset, Function) \
1020         mptsas_put_msg_DevHandle(hdl, mp, DevHandle); \
1021         mptsas_put_msg_ChainOffset(hdl, mp, ChainOffset); \
1022         mptsas_put_msg_Function(hdl, mp, Function); \
1023         mptsas_put_msg_Lun(hdl, mp, Lun)
1024 
1025 #define mptsas_put_msg_DevHandle(hdl, mp, val) \
1026         ddi_put16(hdl, &(mp)->DevHandle, (val))
1027 #define mptsas_put_msg_ChainOffset(hdl, mp, val) \
1028         ddi_put8(hdl, &(mp)->ChainOffset, (val))
1029 #define mptsas_put_msg_Function(hdl, mp, val) \
1030         ddi_put8(hdl, &(mp)->Function, (val))
1031 #define mptsas_put_msg_Lun(hdl, mp, val) \
1032         ddi_put8(hdl, &(mp)->LUN[1], (val))


1040 #define MPTSAS_ENABLE_DRWE(hdl) \
1041         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1042                 MPI2_WRSEQ_FLUSH_KEY_VALUE); \
1043         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1044                 MPI2_WRSEQ_1ST_KEY_VALUE); \
1045         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1046                 MPI2_WRSEQ_2ND_KEY_VALUE); \
1047         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1048                 MPI2_WRSEQ_3RD_KEY_VALUE); \
1049         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1050                 MPI2_WRSEQ_4TH_KEY_VALUE); \
1051         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1052                 MPI2_WRSEQ_5TH_KEY_VALUE); \
1053         ddi_put32(hdl->m_datap, &hdl->m_reg->WriteSequence, \
1054                 MPI2_WRSEQ_6TH_KEY_VALUE);
1055 
1056 /*
1057  * m_options flags
1058  */
1059 #define MPTSAS_OPT_PM           0x01    /* Power Management */
1060 #define MPTSAS_OPT_MSI          0x02    /* PCI MSI Interrupts */
1061 #define MPTSAS_OPT_MSI_X        0x04    /* PCI MSI-X Interrupts */
1062 
1063 /*
1064  * m_softstate flags
1065  */
1066 #define MPTSAS_SS_DRAINING              0x02
1067 #define MPTSAS_SS_QUIESCED              0x04
1068 #define MPTSAS_SS_MSG_UNIT_RESET        0x08
1069 #define MPTSAS_DID_MSG_UNIT_RESET       0x10
1070 
1071 /*
1072  * m_dma_flags (allocated).
1073  */
1074 #define MPTSAS_REQ_FRAME        0x01
1075 #define MPTSAS_REQ_SENSE        0x02
1076 #define MPTSAS_REPLY_FRAME      0x04
1077 #define MPTSAS_FREE_QUEUE       0x08
1078 #define MPTSAS_POST_QUEUE       0x10
1079 
1080 /*
1081  * regspec defines.
1082  */
1083 #define CONFIG_SPACE    0       /* regset[0] - configuration space */
1084 #define IO_SPACE        1       /* regset[1] - used for i/o mapped device */
1085 #define MEM_SPACE       2       /* regset[2] - used for memory mapped device */
1086 #define BASE_REG2       3       /* regset[3] - used for 875 scripts ram */
1087 
1088 /*
1089  * Handy constants
1090  */
1091 #define FALSE           0
1092 #define TRUE            1
1093 #define BLOCKED         2
1094 #define UNDEFINED       -1
1095 #define FAILED          -2
1096 
1097 /*
1098  * power management.
1099  */
1100 #define MPTSAS_POWER_ON(mpt) { \
1101         pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
1102             PCI_PMCSR_D0); \
1103         delay(drv_usectohz(10000)); \
1104         (void) pci_restore_config_regs(mpt->m_dip); \
1105         mptsas_setup_cmd_reg(mpt); \
1106 }
1107 
1108 #define MPTSAS_POWER_OFF(mpt) { \
1109         (void) pci_save_config_regs(mpt->m_dip); \
1110         pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, \
1111             PCI_PMCSR_D3HOT); \
1112         mpt->m_power_level = PM_LEVEL_D3; \
1113 }


1172 #define ADDR2MPT(ap)            (TRAN2MPT(ADDR2TRAN(ap)))
1173 
1174 #define POLL_TIMEOUT            (2 * SCSI_POLL_TIMEOUT * 1000000)
1175 #define SHORT_POLL_TIMEOUT      (1000000)       /* in usec, about 1 secs */
1176 #define MPTSAS_QUIESCE_TIMEOUT  1               /* 1 sec */
1177 #define MPTSAS_PM_IDLE_TIMEOUT  60              /* 60 seconds */
1178 
1179 #define MPTSAS_GET_ISTAT(mpt)  (ddi_get32((mpt)->m_datap, \
1180                         &(mpt)->m_reg->HostInterruptStatus))
1181 
1182 #define MPTSAS_SET_SIGP(P) \
1183                 ClrSetBits(mpt->m_devaddr + NREG_ISTAT, 0, NB_ISTAT_SIGP)
1184 
1185 #define MPTSAS_RESET_SIGP(P) (void) ddi_get8(mpt->m_datap, \
1186                         (uint8_t *)(mpt->m_devaddr + NREG_CTEST2))
1187 
1188 #define MPTSAS_GET_INTCODE(P) (ddi_get32(mpt->m_datap, \
1189                         (uint32_t *)(mpt->m_devaddr + NREG_DSPS)))
1190 
1191 
1192 #define MPTSAS_START_CMD(mpt, req_desc) \
1193         ddi_put64(mpt->m_datap, \
1194             (uint64_t *)(void *)&mpt->m_reg->RequestDescriptorPostLow, \
1195             req_desc);                                                 \
1196         atomic_inc_32(&mpt->m_ncstarted)
1197 
1198 
1199 #define INTPENDING(mpt) \
1200         (MPTSAS_GET_ISTAT(mpt) & MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT)
1201 
1202 /*
1203  * Mask all interrupts to disable
1204  */
1205 #define MPTSAS_DISABLE_INTR(mpt)        \
1206         ddi_put32((mpt)->m_datap, &(mpt)->m_reg->HostInterruptMask, \
1207             (MPI2_HIM_RIM | MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1208 
1209 /*
1210  * Mask Doorbell and Reset interrupts to enable reply desc int.
1211  */
1212 #define MPTSAS_ENABLE_INTR(mpt) \
1213         ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, \
1214         (MPI2_HIM_DIM | MPI2_HIM_RESET_IRQ_MASK))
1215 
1216 #define MPTSAS_GET_NEXT_REPLY(rpqp, index)  \
1217         &((uint64_t *)(void *)rpqp->rpq_queue)[index]
1218 
1219 #define MPTSAS_GET_NEXT_FRAME(mpt, SMID) \
1220         (mpt->m_req_frame + (mpt->m_req_frame_size * SMID))
1221 
1222 #define ClrSetBits32(hdl, reg, clr, set) \
1223         ddi_put32(hdl, (reg), \
1224             ((ddi_get32(mpt->m_datap, (reg)) & ~(clr)) | (set)))
1225 
1226 #define ClrSetBits(reg, clr, set) \
1227         ddi_put8(mpt->m_datap, (uint8_t *)(reg), \
1228                 ((ddi_get8(mpt->m_datap, (uint8_t *)(reg)) & ~(clr)) | (set)))
1229 
1230 #define MPTSAS_WAITQ_RM(mpt, cmdp)      \
1231         if ((cmdp = mpt->m_waitq) != NULL) { \
1232                 /* If the queue is now empty fix the tail pointer */    \
1233                 if ((mpt->m_waitq = cmdp->cmd_linkp) == NULL) \
1234                         mpt->m_waitqtail = &mpt->m_waitq; \
1235                 cmdp->cmd_linkp = NULL; \
1236                 cmdp->cmd_queued = FALSE; \
1237         }
1238 
1239 #define MPTSAS_TX_WAITQ_RM(mpt, cmdp)   \
1240         if ((cmdp = mpt->m_tx_waitq) != NULL) { \
1241                 /* If the queue is now empty fix the tail pointer */    \
1242                 if ((mpt->m_tx_waitq = cmdp->cmd_linkp) == NULL) \
1243                         mpt->m_tx_waitqtail = &mpt->m_tx_waitq; \
1244                 cmdp->cmd_linkp = NULL; \
1245                 cmdp->cmd_queued = FALSE; \
1246         }
1247 
1248 /*
1249  * defaults for the global properties
1250  */
1251 #define DEFAULT_SCSI_OPTIONS    SCSI_OPTIONS_DR
1252 #define DEFAULT_TAG_AGE_LIMIT   2
1253 #define DEFAULT_WD_TICK         1
1254 
1255 /*
1256  * invalid hostid.
1257  */
1258 #define MPTSAS_INVALID_HOSTID  -1
1259 
1260 /*
1261  * Get/Set hostid from SCSI port configuration page
1262  */
1263 #define MPTSAS_GET_HOST_ID(configuration) (configuration & 0xFF)
1264 #define MPTSAS_SET_HOST_ID(hostid) (hostid | ((1 << hostid) << 16))
1265 
1266 /*
1267  * Config space.
1268  */
1269 #define MPTSAS_LATENCY_TIMER    0x40
1270 
1271 /*
1272  * Offset to firmware version
1273  */


1320  * response code tlr flag
1321  */
1322 #define MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF       0x02
1323 
1324 /*
1325  * System Events
1326  */
1327 #ifndef DDI_VENDOR_LSI
1328 #define DDI_VENDOR_LSI  "LSI"
1329 #endif  /* DDI_VENDOR_LSI */
1330 
1331 /*
1332  * Shared functions
1333  */
1334 int mptsas_save_cmd(struct mptsas *mpt, struct mptsas_cmd *cmd);
1335 void mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
1336 void mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
1337 void mptsas_log(struct mptsas *mpt, int level, char *fmt, ...);
1338 int mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime);
1339 int mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)());








1340 int mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
1341         uint8_t type, int mode);
1342 int mptsas_check_flash(mptsas_t *mpt, caddr_t origfile, uint32_t size,
1343         uint8_t type, int mode);
1344 int mptsas_download_firmware();
1345 int mptsas_can_download_firmware();
1346 int mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep);
1347 void mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep);
1348 mptsas_phymask_t mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport);
1349 void mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd);
1350 int mptsas_check_acc_handle(ddi_acc_handle_t handle);
1351 int mptsas_check_dma_handle(ddi_dma_handle_t handle);
1352 void mptsas_fm_ereport(mptsas_t *mpt, char *detail);
1353 int mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
1354     ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
1355     uint32_t alloc_size, ddi_dma_cookie_t *cookiep);
1356 void mptsas_dma_addr_destroy(ddi_dma_handle_t *, ddi_acc_handle_t *);
1357 
1358 /*
1359  * impl functions
1360  */
1361 int mptsas_ioc_wait_for_response(mptsas_t *mpt);
1362 int mptsas_ioc_wait_for_doorbell(mptsas_t *mpt);
1363 int mptsas_ioc_reset(mptsas_t *mpt, int);
1364 int mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1365     ddi_acc_handle_t accessp);
1366 int mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
1367     ddi_acc_handle_t accessp);
1368 int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action,
1369     uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber,
1370     uint8_t pageversion, uint8_t pagelength, uint32_t SGEflagslength,
1371     uint64_t SGEaddress);
1372 int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
1373     uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
1374     uint8_t pageversion, uint16_t extpagelength,
1375     uint32_t SGEflagslength, uint64_t SGEaddress);
1376 
1377 int mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd,
1378     struct scsi_pkt **pkt);
1379 void mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd);
1380 void mptsas_destroy_ioc_event_cmd(mptsas_t *mpt);
1381 void mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd);
1382 int mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
1383     uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
1384     caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...);
1385 
1386 int mptsas_ioc_task_management(mptsas_t *mpt, int task_type,
1387     uint16_t dev_handle, int lun, uint8_t *reply, uint32_t reply_size,
1388     int mode);
1389 int mptsas_send_event_ack(mptsas_t *mpt, uint32_t event, uint32_t eventcntx);
1390 void mptsas_send_pending_event_ack(mptsas_t *mpt);

1391 int mptsas_restart_ioc(mptsas_t *mpt);
1392 void mptsas_update_driver_data(struct mptsas *mpt);
1393 uint64_t mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun);
1394 
1395 /*
1396  * init functions
1397  */
1398 int mptsas_ioc_get_facts(mptsas_t *mpt);
1399 int mptsas_ioc_get_port_facts(mptsas_t *mpt, int port);
1400 int mptsas_ioc_enable_port(mptsas_t *mpt);
1401 int mptsas_ioc_enable_event_notification(mptsas_t *mpt);
1402 int mptsas_ioc_init(mptsas_t *mpt);
1403 
1404 /*
1405  * configuration pages operation
1406  */
1407 int mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
1408     uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
1409     uint8_t *physport, uint8_t *phynum, uint16_t *pdevhandle,
1410     uint16_t *slot_num, uint16_t *enclosure, uint16_t *io_flags);
1411 int mptsas_get_sas_io_unit_page(mptsas_t *mpt);
1412 int mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt);
1413 int mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address,
1414     mptsas_smp_t *info);
1415 int mptsas_set_ioc_params(mptsas_t *mpt);
1416 int mptsas_get_manufacture_page5(mptsas_t *mpt);
1417 int mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address,
1418     uint64_t *sas_wwn, uint8_t *portwidth);
1419 int mptsas_get_bios_page3(mptsas_t *mpt,  uint32_t *bios_version);
1420 int
1421 mptsas_get_sas_phy_page0(mptsas_t *mpt, uint32_t page_address,
1422     smhba_info_t *info);
1423 int
1424 mptsas_get_sas_phy_page1(mptsas_t *mpt, uint32_t page_address,
1425     smhba_info_t *info);
1426 int
1427 mptsas_get_manufacture_page0(mptsas_t *mpt);
1428 void
1429 mptsas_create_phy_stats(mptsas_t *mpt, char *iport, dev_info_t *dip);
1430 void mptsas_destroy_phy_stats(mptsas_t *mpt);
1431 int mptsas_smhba_phy_init(mptsas_t *mpt);
1432 /*
1433  * RAID functions
1434  */
1435 int mptsas_get_raid_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol);
1436 int mptsas_get_raid_info(mptsas_t *mpt);
1437 int mptsas_get_physdisk_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol,
1438     uint8_t physdisknum);
1439 int mptsas_delete_volume(mptsas_t *mpt, uint16_t volid);
1440 void mptsas_raid_action_system_shutdown(mptsas_t *mpt);
1441 
1442 #define MPTSAS_IOCSTATUS(status) (status & MPI2_IOCSTATUS_MASK)
1443 /*
1444  * debugging.
1445  */
1446 #if defined(MPTSAS_DEBUG)
1447 
1448 void mptsas_printf(char *fmt, ...);
1449 void mptsas_debug_log(char *fmt, ...);
1450 
1451 #define MPTSAS_DBGPR(m, args)   \
1452         if (mptsas_debug_flags & (m)) \
1453                 mptsas_printf args;   \
1454         if (~mptsas_dbglog_imask & (m)) \
1455                 mptsas_debug_log args
1456 #else   /* ! defined(MPTSAS_DEBUG) */
1457 #define MPTSAS_DBGPR(m, args)
1458 #endif  /* defined(MPTSAS_DEBUG) */
1459 
1460 #define NDBG0(args)     MPTSAS_DBGPR(0x01, args)        /* init */
1461 #define NDBG1(args)     MPTSAS_DBGPR(0x02, args)        /* normal running */
1462 #define NDBG2(args)     MPTSAS_DBGPR(0x04, args)        /* property handling */
1463 #define NDBG3(args)     MPTSAS_DBGPR(0x08, args)        /* pkt handling */
1464 
1465 #define NDBG4(args)     MPTSAS_DBGPR(0x10, args)        /* kmem alloc/free */
1466 #define NDBG5(args)     MPTSAS_DBGPR(0x20, args)        /* polled cmds */
1467 #define NDBG6(args)     MPTSAS_DBGPR(0x40, args)        /* interrupt setup */
1468 #define NDBG7(args)     MPTSAS_DBGPR(0x80, args)        /* queue handling */
1469 
1470 #define NDBG8(args)     MPTSAS_DBGPR(0x0100, args)      /* arq */
1471 #define NDBG9(args)     MPTSAS_DBGPR(0x0200, args)      /* Tagged Q'ing */
1472 #define NDBG10(args)    MPTSAS_DBGPR(0x0400, args)      /* halting chip */
1473 #define NDBG11(args)    MPTSAS_DBGPR(0x0800, args)      /* power management */
1474 
1475 #define NDBG12(args)    MPTSAS_DBGPR(0x1000, args)      /* enumeration */
1476 #define NDBG13(args)    MPTSAS_DBGPR(0x2000, args)      /* configuration page */
1477 #define NDBG14(args)    MPTSAS_DBGPR(0x4000, args)      /* LED control */
1478 #define NDBG15(args)    MPTSAS_DBGPR(0x8000, args)      /* Passthrough */
1479 
1480 #define NDBG16(args)    MPTSAS_DBGPR(0x010000, args)    /* SAS Broadcasts */
1481 #define NDBG17(args)    MPTSAS_DBGPR(0x020000, args)    /* scatter/gather */
1482 #define NDBG18(args)    MPTSAS_DBGPR(0x040000, args)    /* Interrupts */
1483 #define NDBG19(args)    MPTSAS_DBGPR(0x080000, args)    /* handshaking */
1484 
1485 #define NDBG20(args)    MPTSAS_DBGPR(0x100000, args)    /* events */
1486 #define NDBG21(args)    MPTSAS_DBGPR(0x200000, args)    /* dma */
1487 #define NDBG22(args)    MPTSAS_DBGPR(0x400000, args)    /* reset */
1488 #define NDBG23(args)    MPTSAS_DBGPR(0x800000, args)    /* abort */
1489 
1490 #define NDBG24(args)    MPTSAS_DBGPR(0x1000000, args)   /* capabilities */
1491 #define NDBG25(args)    MPTSAS_DBGPR(0x2000000, args)   /* flushing */
1492 #define NDBG26(args)    MPTSAS_DBGPR(0x4000000, args)
1493 #define NDBG27(args)    MPTSAS_DBGPR(0x8000000, args)
1494 
1495 #define NDBG28(args)    MPTSAS_DBGPR(0x10000000, args)  /* hotplug */
1496 #define NDBG29(args)    MPTSAS_DBGPR(0x20000000, args)  /* timeouts */
1497 #define NDBG30(args)    MPTSAS_DBGPR(0x40000000, args)  /* mptsas_watch */
1498 #define NDBG31(args)    MPTSAS_DBGPR(0x80000000, args)  /* negotations */
1499 
1500 /*
1501  * auto request sense
1502  */
1503 #define RQ_MAKECOM_COMMON(pkt, flag, cmd) \
1504         (pkt)->pkt_flags = (flag), \
1505         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_cmd = (cmd), \
1506         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
1507             (pkt)->pkt_address.a_lun
1508 
1509 #define RQ_MAKECOM_G0(pkt, flag, cmd, addr, cnt) \
1510         RQ_MAKECOM_COMMON((pkt), (flag), (cmd)), \
1511         FORMG0ADDR(((union scsi_cdb *)(pkt)->pkt_cdbp), (addr)), \
1512         FORMG0COUNT(((union scsi_cdb *)(pkt)->pkt_cdbp), (cnt))
1513 
1514 
1515 #ifdef  __cplusplus
1516 }
1517 #endif
1518 
1519 #endif  /* _SYS_SCSI_ADAPTERS_MPTSAS3_VAR_H */