Print this page
    
MFV: illumos-gate@fd6d41c5025e9fb45a115fc82d86e9983d1e9fd6
9815 Want basic AHCI enclosure services
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Robert Mustacchi <rm@joyent.com>
Conflicts:
        usr/src/cmd/Makefile
re #12164 Marvell 88SE9128: Appliance hard hangs on boot probing duplicated ahci device
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h
          +++ new/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       25 + * Copyright (c) 2018, Joyent, Inc.
  25   26   */
  26   27  
  27   28  
  28   29  #ifndef _AHCIVAR_H
  29   30  #define _AHCIVAR_H
  30   31  
  31   32  #ifdef  __cplusplus
  32   33  extern "C" {
  33   34  #endif
  34   35  
       36 +#include <sys/sata/adapters/ahci/ahciem.h>
       37 +
  35   38  /*
  36   39   * AHCI address qualifier flags (in qual field of ahci_addr struct).
  37   40   */
  38   41  #define AHCI_ADDR_NULL          0x00
  39   42  #define AHCI_ADDR_PORT          0x01
  40   43  #define AHCI_ADDR_PMPORT        0x02
  41   44  #define AHCI_ADDR_PMULT         0x04
  42   45  #define AHCI_ADDR_VALID         (AHCI_ADDR_PORT | \
  43   46                                  AHCI_ADDR_PMULT | \
  44   47                                  AHCI_ADDR_PMPORT)
  45   48  
  46   49  /*
  47   50   * AHCI address structure.
  48   51   */
  49   52  struct ahci_addr {
  50   53  
  51   54          /* HBA port number */
  52   55          uint8_t                 aa_port;
  53   56  
  54   57          /* Port multiplier port number */
  55   58          uint8_t                 aa_pmport;
  56   59  
  57   60          /*
  58   61           * AHCI_ADDR_NULL
  59   62           * AHCI_ADDR_PORT
  60   63           * AHCI_ADDR_PMPORT
  61   64           * AHCI_ADDR_PMULT
  62   65           */
  63   66          uint8_t                 aa_qual;
  64   67  };
  65   68  typedef struct ahci_addr ahci_addr_t;
  66   69  
  67   70  _NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr))
  68   71  
  69   72  #define AHCI_ADDR_IS_PORT(addrp)                                        \
  70   73          ((addrp)->aa_qual & AHCI_ADDR_PORT)
  71   74  #define AHCI_ADDR_IS_PMPORT(addrp)                                      \
  72   75          ((addrp)->aa_qual & AHCI_ADDR_PMPORT)
  73   76  #define AHCI_ADDR_IS_PMULT(addrp)                                       \
  74   77          ((addrp)->aa_qual & AHCI_ADDR_PMULT)
  75   78  #define AHCI_ADDR_IS_VALID(addrp)                                       \
  76   79          ((addrp)->aa_port < SATA_MAX_CPORTS) &&                         \
  77   80          ((addrp)->aa_pmport < SATA_MAX_PMPORTS) &&                      \
  78   81          ((addrp)->aa_qual & AHCI_ADDR_VALID)
  79   82  
  80   83  #define AHCI_ADDR_SET(addrp, port, pmport, qual)                        \
  81   84          {                                                               \
  82   85                  (addrp)->aa_port = port;                                \
  83   86                  (addrp)->aa_pmport = pmport;                            \
  84   87                  (addrp)->aa_qual = qual;                                \
  85   88          }
  86   89  #define AHCI_ADDR_SET_PORT(addrp, port)                                 \
  87   90          AHCI_ADDR_SET(addrp, port, 0, AHCI_ADDR_PORT)
  88   91  #define AHCI_ADDR_SET_PMPORT(addrp, port, pmport)                       \
  89   92          AHCI_ADDR_SET(addrp, port, pmport, AHCI_ADDR_PMPORT)
  90   93  #define AHCI_ADDR_SET_PMULT(addrp, port)                                \
  91   94          AHCI_ADDR_SET(addrp, port, SATA_PMULT_HOSTPORT, AHCI_ADDR_PMULT)
  92   95  
  93   96  /* Type for argument of event handler */
  94   97  typedef struct ahci_event_arg {
  95   98          void            *ahciea_ctlp;
  96   99          void            *ahciea_portp;
  97  100          void            *ahciea_addrp;
  98  101          uint32_t        ahciea_event;
  99  102  } ahci_event_arg_t;
 100  103  
 101  104  /* Warlock annotation */
 102  105  _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp))
 103  106  _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp))
 104  107  _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_addrp))
 105  108  _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event))
 106  109  
 107  110  
 108  111  /*
 109  112   * ahci_pmult_info stores the information of a port multiplier and its
 110  113   * sub-devices in case a port multiplier is attached to an HBA port.
 111  114   */
 112  115  struct ahci_pmult_info {
 113  116  
 114  117          /* Number of the device ports */
 115  118          int                     ahcipmi_num_dev_ports;
 116  119  
 117  120          /* Device type of the sub-devices of the port multipler */
 118  121          uint8_t                 ahcipmi_device_type[SATA_MAX_PMPORTS];
 119  122  
 120  123          /* State of port multiplier port */
 121  124          uint32_t                ahcipmi_port_state[SATA_MAX_PMPORTS];
 122  125  
 123  126          /*
 124  127           * Port multiplier port on which there is outstanding NCQ
 125  128           * commands. Only make sense in command based switching mode.
 126  129           */
 127  130          uint8_t                 ahcipmi_ncq_pmport;
 128  131  
 129  132          /* Pending asynchronous notification events tags */
 130  133          uint32_t                ahcipmi_snotif_tags;
 131  134  };
 132  135  typedef struct ahci_pmult_info ahci_pmult_info_t;
 133  136  
 134  137  /*
 135  138   * flags for ahciport_flags
 136  139   *
 137  140   * AHCI_PORT_FLAG_MOPPING: this flag will be set when the HBA is stopped,
 138  141   * and all the outstanding commands need to be aborted and sent to upper
 139  142   * layers.
 140  143   *
 141  144   * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is
 142  145   * disabled, and the command is executed in POLLING mode.
 143  146   *
 144  147   * AHCI_PORT_FLAG_RQSENSE: this flag will be set when a REQUEST SENSE which
 145  148   * is used to retrieve sense data is being executed.
 146  149   *
 147  150   * AHCI_PORT_FLAG_STARTED: this flag will be set when the port is started,
 148  151   * that is PxCMD.ST is set with '1', and be cleared when the port is put into
 149  152   * idle, that is PxCMD.ST is changed from '1' to '0'.
 150  153   *
 151  154   * AHCI_PORT_FLAG_RDLOGEXT: this flag will be set when a READ LOG EXT which
 152  155   * is used to retrieve NCQ failure context is being executed.
 153  156   *
 154  157   * AHCI_PORT_FLAG_NODEV: this flag will be set when a device is found gone
 155  158   * during ahci_restart_port_wait_till_ready process.
 156  159   *
 157  160   * AHCI_PORT_FLAG_RDWR_PMULT: this flag will be set when a READ/WRITE
 158  161   * PORTMULT command is being executed.
 159  162   *
 160  163   * AHCI_PORT_FLAG_IGNORE_IPMS: this flag will be set when enumerating a port
 161  164   * multiplier. According AHCI spec, IPMS error should be ignore during
 162  165   * enumeration of port multiplier.
 163  166   *
 164  167   * AHCI_PORT_FLAG_PMULT_SNTF: this flag will be set when the a asynchronous
 165  168   * notification event on the port multiplier is being handled.
 166  169   *
 167  170   * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is
 168  171   * being handled.
 169  172   *
 170  173   * AHCI_PORT_FLAG_ERRPRINT: this flag will be set when error recovery message
 171  174   * will be printed. Note that, for INDENTIFY DEVICE command sent to ATAPI
 172  175   * device or ATAPI PACKET command, this flag won't be set.
 173  176   */
 174  177  #define AHCI_PORT_FLAG_MOPPING          0x02
 175  178  #define AHCI_PORT_FLAG_POLLING          0x04
 176  179  #define AHCI_PORT_FLAG_RQSENSE          0x08
 177  180  #define AHCI_PORT_FLAG_STARTED          0x10
 178  181  #define AHCI_PORT_FLAG_RDLOGEXT         0x20
 179  182  #define AHCI_PORT_FLAG_NODEV            0x40
 180  183  #define AHCI_PORT_FLAG_RDWR_PMULT       0x80
 181  184  #define AHCI_PORT_FLAG_IGNORE_IPMS      0x100
 182  185  #define AHCI_PORT_FLAG_PMULT_SNTF       0x200
 183  186  #define AHCI_PORT_FLAG_HOTPLUG          0x400
 184  187  #define AHCI_PORT_FLAG_ERRPRINT         0x800
 185  188  
 186  189  typedef struct ahci_port {
 187  190          /* The physical port number */
 188  191          uint8_t                 ahciport_port_num;
 189  192  
 190  193          /* Type of the device attached to the port */
 191  194          uint8_t                 ahciport_device_type;
 192  195          /* State of the port */
 193  196          uint32_t                ahciport_port_state;
 194  197  
 195  198          /* Port multiplier struct */
 196  199          ahci_pmult_info_t       *ahciport_pmult_info;
 197  200  
 198  201          /*
 199  202           * AHCI_PORT_FLAG_MOPPING
 200  203           * AHCI_PORT_FLAG_POLLING
 201  204           * AHCI_PORT_FLAG_RQSENSE
 202  205           * AHCI_PORT_FLAG_STARTED
 203  206           * AHCI_PORT_FLAG_RDLOGEXT
 204  207           * AHCI_PORT_FLAG_NODEV
 205  208           * AHCI_PORT_FLAG_RDWR_PMULT
 206  209           * AHCI_PORT_FLAG_IGNORE_IPMS
 207  210           * AHCI_PORT_FLAG_PMULT_SNTF
 208  211           * AHCI_PORT_FLAG_HOTPLUG
 209  212           * AHCI_PORT_FLAG_ERRPRINT
 210  213           */
 211  214          int                     ahciport_flags;
 212  215  
 213  216          /* Pointer to received FIS structure */
 214  217          ahci_rcvd_fis_t         *ahciport_rcvd_fis;
 215  218          ddi_dma_handle_t        ahciport_rcvd_fis_dma_handle;
 216  219          ddi_acc_handle_t        ahciport_rcvd_fis_acc_handle;
 217  220          ddi_dma_cookie_t        ahciport_rcvd_fis_dma_cookie;
 218  221  
 219  222          /* Pointer to command list structure */
 220  223          ahci_cmd_header_t       *ahciport_cmd_list;
 221  224          ddi_dma_handle_t        ahciport_cmd_list_dma_handle;
 222  225          ddi_acc_handle_t        ahciport_cmd_list_acc_handle;
 223  226          ddi_dma_cookie_t        ahciport_cmd_list_dma_cookie;
 224  227  
 225  228          /* Pointer to cmmand table structure */
 226  229          ahci_cmd_table_t        \
 227  230                          *ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS];
 228  231          ddi_dma_handle_t        \
 229  232                          ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS];
 230  233          ddi_acc_handle_t        \
 231  234                          ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS];
 232  235  
 233  236          /* Condition variable used for sync mode commands */
 234  237          kcondvar_t              ahciport_cv;
 235  238  
 236  239          /* The whole mutex for the port structure */
 237  240          kmutex_t                ahciport_mutex;
 238  241  
 239  242          /* The maximum number of tags for native queuing command transfers */
 240  243          int                     ahciport_max_ncq_tags;
 241  244  
 242  245          /* Keep the tags of all pending non-ncq commands */
 243  246          uint32_t                ahciport_pending_tags;
 244  247  
 245  248          /*
 246  249           * Keep the tags of all pending ncq commands
 247  250           * (READ/WRITE FPDMA QUEUED)
 248  251           */
 249  252          uint32_t                ahciport_pending_ncq_tags;
 250  253  
 251  254          /* Keep all the pending sata packets */
 252  255          sata_pkt_t              *ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
 253  256  
 254  257          /* Used to check whether corresponding packet is timeout */
 255  258          int                     ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
 256  259  
 257  260          /* Queue of completed (done) sata packet */
 258  261          sata_pkt_t              *ahciport_doneq;
 259  262  
 260  263          /* Pointer of the tail of completed sata packet queue */
 261  264          sata_pkt_t              **ahciport_doneqtail;
 262  265  
 263  266          /* the length of the completed sata packet queue */
 264  267          uint32_t                ahciport_doneq_len;
 265  268  
 266  269          /* Keep the byte count of all PRD entries for every sata packet */
 267  270          uint32_t                \
 268  271                          ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS];
 269  272  
 270  273          /* Keep the error retrieval sata packet */
 271  274          sata_pkt_t              *ahciport_err_retri_pkt;
 272  275  
 273  276          /* Keep the read/write port multiplier packet */
 274  277          sata_pkt_t              *ahciport_rdwr_pmult_pkt;
 275  278  
 276  279          /*
 277  280           * SATA HBA driver is supposed to remember and maintain device
 278  281           * reset state. While the reset is in progress, it doesn't accept
 279  282           * any more commands until receiving the command with
 280  283           * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE.
 281  284           */
 282  285          int                     ahciport_reset_in_progress;
 283  286  
 284  287          /* Taskq for handling event */
 285  288          ddi_taskq_t             *ahciport_event_taskq;
 286  289  
 287  290          /* This is for error recovery handler */
 288  291          ahci_event_arg_t        *ahciport_event_args;
 289  292  
 290  293          /* This is to calculate how many mops are in progress */
 291  294          int                     ahciport_mop_in_progress;
 292  295  } ahci_port_t;
 293  296  
 294  297  /* Warlock annotation */
 295  298  _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle))
 296  299  _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle))
 297  300  _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle))
 298  301  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 299  302                                      ahci_port_t::ahciport_device_type))
 300  303  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 301  304                                      ahci_port_t::ahciport_port_state))
 302  305  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 303  306                                      ahci_port_t::ahciport_flags))
 304  307  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 305  308                                      ahci_port_t::ahciport_pending_tags))
 306  309  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 307  310                                      ahci_port_t::ahciport_slot_pkts))
 308  311  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 309  312                                      ahci_port_t::ahciport_slot_timeout))
 310  313  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 311  314                                      ahci_port_t::ahciport_doneq))
 312  315  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 313  316                                      ahci_port_t::ahciport_doneqtail))
 314  317  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 315  318                                      ahci_port_t::ahciport_doneq_len))
 316  319  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 317  320                                      ahci_port_t::ahciport_reset_in_progress))
 318  321  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 319  322                                      ahci_port_t::ahciport_mop_in_progress))
 320  323  _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
 321  324                                      ahci_port_t::ahciport_event_taskq))
 322  325  
 323  326  #define AHCI_NUM_PORTS(ctlp)                                            \
 324  327          (ctlp)->ahcictl_num_ports
 325  328  
 326  329  #define AHCIPORT_NUM_PMPORTS(portp)                                     \
 327  330          (portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
 328  331  
 329  332  #define AHCIPORT_NCQ_PMPORT(ahci_portp)                                 \
 330  333          (ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
 331  334  
 332  335  #define AHCIPORT_DEV_TYPE(portp, addrp)                                 \
 333  336          (portp)->ahciport_device_type
 334  337  
 335  338  #define AHCIPORT_PMDEV_TYPE(portp, addrp)                               \
 336  339          (portp)->ahciport_pmult_info->ahcipmi_device_type               \
 337  340          [(addrp)->aa_pmport]
 338  341  
 339  342  #define AHCIPORT_GET_DEV_TYPE(portp, addrp)                             \
 340  343          (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?         \
 341  344          AHCIPORT_DEV_TYPE(portp, addrp) :                               \
 342  345          AHCIPORT_PMDEV_TYPE(portp, addrp))
 343  346  
 344  347  #define AHCIPORT_SET_DEV_TYPE(portp, addrp, type)                       \
 345  348          if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))       \
 346  349                  AHCIPORT_DEV_TYPE(portp, addrp) = type;                 \
 347  350          else                                                            \
 348  351                  AHCIPORT_PMDEV_TYPE(portp, addrp) = type;
 349  352  
 350  353  #define AHCIPORT_STATE(portp, addrp)                                    \
 351  354          (portp)->ahciport_port_state
 352  355  
 353  356  #define AHCIPORT_PMSTATE(portp, addrp)                                  \
 354  357          (portp)->ahciport_pmult_info->ahcipmi_port_state                \
 355  358          [(addrp)->aa_pmport]
 356  359  
  
    | 
      ↓ open down ↓ | 
    312 lines elided | 
    
      ↑ open up ↑ | 
  
 357  360  #define AHCIPORT_GET_STATE(portp, addrp)                                \
 358  361          (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?         \
 359  362          AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp))
 360  363  
 361  364  #define AHCIPORT_SET_STATE(portp, addrp, state)                         \
 362  365          if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))       \
 363  366                  AHCIPORT_STATE(portp, addrp) = state;                   \
 364  367          else                                                            \
 365  368                  AHCIPORT_PMSTATE(portp, addrp) = state;
 366  369  
      370 +typedef enum ahci_em_flags {
      371 +        AHCI_EM_PRESENT         = 1 << 0,
      372 +        AHCI_EM_RESETTING       = 1 << 1,
      373 +        AHCI_EM_TIMEOUT         = 1 << 2,
      374 +        AHCI_EM_QUIESCE         = 1 << 3,
      375 +        AHCI_EM_READY           = 1 << 4,
      376 +} ahci_em_flags_t;
      377 +
      378 +#define AHCI_EM_USABLE          (AHCI_EM_PRESENT | AHCI_EM_READY)
      379 +
 367  380  typedef struct ahci_ctl {
 368  381          dev_info_t              *ahcictl_dip;
 369  382  
 370  383          ushort_t                ahcictl_venid;
 371  384          ushort_t                ahcictl_devid;
 372  385  
 373  386          /* To map port number to cport number */
 374  387          uint8_t                 ahcictl_port_to_cport[AHCI_MAX_PORTS];
 375  388          /* To map cport number to port number */
 376  389          uint8_t                 ahcictl_cport_to_port[AHCI_MAX_PORTS];
 377  390  
 378  391          /* Number of controller ports */
 379  392          int                     ahcictl_num_ports;
 380  393          /* Number of command slots */
 381  394          int                     ahcictl_num_cmd_slots;
 382  395          /* Number of implemented ports */
 383  396          int                     ahcictl_num_implemented_ports;
 384  397          /* Bit map to indicate which port is implemented */
 385  398          uint32_t                ahcictl_ports_implemented;
 386  399          ahci_port_t             *ahcictl_ports[AHCI_MAX_PORTS];
 387  400  
 388  401          int                     ahcictl_flags;
 389  402          int                     ahcictl_power_level;
 390  403          off_t                   ahcictl_pmcsr_offset;
 391  404  
 392  405          /*
 393  406           * AHCI_CAP_PIO_MDRQ
 394  407           * AHCI_CAP_NO_MCMDLIST_NONQUEUE
 395  408           * AHCI_CAP_NCQ
 396  409           * AHCI_CAP_PM
 397  410           * AHCI_CAP_BUF_32BIT_DMA
 398  411           * AHCI_CAP_SCLO
 399  412           * AHCI_CAP_COMMU_32BIT_DMA
 400  413           * AHCI_CAP_INIT_PORT_RESET
 401  414           * AHCI_CAP_SNTF
 402  415           * AHCI_CAP_PMULT_CBSS
 403  416           * AHCI_CAP_PMULT_FBSS
 404  417           * AHCI_CAP_SRST_NO_HOSTPORT
 405  418           */
 406  419          int                     ahcictl_cap;
 407  420  
 408  421          /* Pci configuration space handle */
 409  422          ddi_acc_handle_t        ahcictl_pci_conf_handle;
 410  423  
 411  424          /* Mapping into bar 5 - AHCI base address */
 412  425          ddi_acc_handle_t        ahcictl_ahci_acc_handle;
 413  426          uintptr_t               ahcictl_ahci_addr;
 414  427  
 415  428          /* Pointer used for sata hba framework registration */
 416  429          struct sata_hba_tran    *ahcictl_sata_hba_tran;
 417  430  
 418  431          /* DMA attributes for the data buffer */
 419  432          ddi_dma_attr_t          ahcictl_buffer_dma_attr;
 420  433          /* DMA attributes for the rcvd FIS */
 421  434          ddi_dma_attr_t          ahcictl_rcvd_fis_dma_attr;
 422  435          /* DMA attributes for the command list */
 423  436          ddi_dma_attr_t          ahcictl_cmd_list_dma_attr;
 424  437          /* DMA attributes for command tables */
 425  438          ddi_dma_attr_t          ahcictl_cmd_table_dma_attr;
 426  439  
 427  440          /* Used for watchdog handler */
 428  441          timeout_id_t            ahcictl_timeout_id;
 429  442  
 430  443          /* Per controller mutex */
 431  444          kmutex_t                ahcictl_mutex;
 432  445  
  
    | 
      ↓ open down ↓ | 
    56 lines elided | 
    
      ↑ open up ↑ | 
  
 433  446          /* Components for interrupt */
 434  447          ddi_intr_handle_t       *ahcictl_intr_htable;   /* For array of intrs */
 435  448          int                     ahcictl_intr_type; /* What type of interrupt */
 436  449          int                     ahcictl_intr_cnt;  /* # of intrs returned */
 437  450          size_t                  ahcictl_intr_size; /* Size of intr array */
 438  451          uint_t                  ahcictl_intr_pri;  /* Intr priority */
 439  452          int                     ahcictl_intr_cap;  /* Intr capabilities */
 440  453  
 441  454          /* FMA capabilities */
 442  455          int                     ahcictl_fm_cap;
      456 +
      457 +        /*
      458 +         * Enclosure information
      459 +         */
      460 +        uint32_t                ahcictl_em_loc;
      461 +        uint32_t                ahcictl_em_ctl;
      462 +        uintptr_t               ahcictl_em_tx_off;
      463 +        ahci_em_flags_t         ahcictl_em_flags;
      464 +        ddi_taskq_t             *ahcictl_em_taskq;
      465 +        ahci_em_led_state_t     ahcictl_em_state[AHCI_MAX_PORTS];
 443  466  } ahci_ctl_t;
 444  467  
 445  468  /* Warlock annotation */
 446  469  _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
 447  470  _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
 448  471  _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
 449  472  
 450  473  _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
 451  474                                          ahci_ctl_t::ahcictl_power_level))
 452  475  _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
 453  476                                          ahci_ctl_t::ahcictl_flags))
 454  477  _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
 455  478                                          ahci_ctl_t::ahcictl_timeout_id))
 456  479  
 457  480  #define AHCI_SUCCESS    (0)  /* Successful return */
 458  481  #define AHCI_TIMEOUT    (1)  /* Timed out */
 459  482  #define AHCI_FAILURE    (-1) /* Unsuccessful return */
 460  483  
 461  484  /* Flags for ahcictl_flags */
 462  485  #define AHCI_ATTACH             0x1
 463  486  #define AHCI_DETACH             0x2
 464  487  #define AHCI_SUSPEND            0x4
 465  488  #define AHCI_QUIESCE            0x8
 466  489  
 467  490  /* Values for ahcictl_cap */
 468  491  /* PIO Multiple DRQ Block */
 469  492  #define AHCI_CAP_PIO_MDRQ               0x1
 470  493  /*
 471  494   * Multiple command slots in the command list cannot be used for
 472  495   * non-queued commands
 473  496   */
 474  497  #define AHCI_CAP_NO_MCMDLIST_NONQUEUE   0x2
 475  498  /* Native Command Queuing (NCQ) */
 476  499  #define AHCI_CAP_NCQ                    0x4
 477  500  /* Power Management (PM) */
 478  501  #define AHCI_CAP_PM                     0x8
 479  502  /* 32-bit DMA addressing for buffer block */
 480  503  #define AHCI_CAP_BUF_32BIT_DMA          0x10
 481  504  /* Supports Command List Override */
 482  505  #define AHCI_CAP_SCLO                   0x20
 483  506  /* 32-bit DMA addressing for communication memory descriptors */
 484  507  #define AHCI_CAP_COMMU_32BIT_DMA        0x40
  
    | 
      ↓ open down ↓ | 
    32 lines elided | 
    
      ↑ open up ↑ | 
  
 485  508  /* Port reset is needed for initialization */
 486  509  #define AHCI_CAP_INIT_PORT_RESET        0x80
 487  510  /* Port Asychronous Notification */
 488  511  #define AHCI_CAP_SNTF                   0x100
 489  512  /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
 490  513  #define AHCI_CAP_PMULT_CBSS             0x200
 491  514  /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
 492  515  #define AHCI_CAP_PMULT_FBSS             0x400
 493  516  /* Software Reset FIS cannot set pmport with 0xf for direct access device */
 494  517  #define AHCI_CAP_SRST_NO_HOSTPORT       0x800
      518 +/* Enclosure Management Services available */
      519 +#define AHCI_CAP_EMS                    0x1000
 495  520  
 496  521  /* Flags controlling the restart port behavior */
 497  522  #define AHCI_PORT_RESET         0x0001  /* Reset the port */
 498  523  #define AHCI_RESET_NO_EVENTS_UP 0x0002  /* Don't send reset events up */
 499  524  
 500  525  #define ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)           \
 501  526          (ahci_portp->ahciport_flags &                   \
 502  527          (AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
 503  528  
 504  529  #define RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)          \
 505  530          (ahci_portp->ahciport_flags &                   \
 506  531          AHCI_PORT_FLAG_RDWR_PMULT)
 507  532  
 508  533  #define NON_NCQ_CMD_IN_PROGRESS(ahci_portp)             \
 509  534          (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&      \
 510  535          ahci_portp->ahciport_pending_tags != 0 &&       \
 511  536          ahci_portp->ahciport_pending_ncq_tags == 0)
 512  537  
 513  538  #define NCQ_CMD_IN_PROGRESS(ahci_portp)                 \
 514  539          (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&      \
 515  540          ahci_portp->ahciport_pending_ncq_tags != 0)
 516  541  
 517  542  /* Command type for ahci_claim_free_slot routine */
 518  543  #define AHCI_NON_NCQ_CMD        0x0
 519  544  #define AHCI_NCQ_CMD            0x1
 520  545  #define AHCI_ERR_RETRI_CMD      0x2
 521  546  #define AHCI_RDWR_PMULT_CMD     0x4
 522  547  
 523  548  /* State values for ahci_attach */
  
    | 
      ↓ open down ↓ | 
    19 lines elided | 
    
      ↑ open up ↑ | 
  
 524  549  #define AHCI_ATTACH_STATE_NONE                  (0x1 << 0)
 525  550  #define AHCI_ATTACH_STATE_STATEP_ALLOC          (0x1 << 1)
 526  551  #define AHCI_ATTACH_STATE_FMA                   (0x1 << 2)
 527  552  #define AHCI_ATTACH_STATE_REG_MAP               (0x1 << 3)
 528  553  #define AHCI_ATTACH_STATE_PCICFG_SETUP          (0x1 << 4)
 529  554  #define AHCI_ATTACH_STATE_INTR_ADDED            (0x1 << 5)
 530  555  #define AHCI_ATTACH_STATE_MUTEX_INIT            (0x1 << 6)
 531  556  #define AHCI_ATTACH_STATE_PORT_ALLOC            (0x1 << 7)
 532  557  #define AHCI_ATTACH_STATE_HW_INIT               (0x1 << 8)
 533  558  #define AHCI_ATTACH_STATE_TIMEOUT_ENABLED       (0x1 << 9)
      559 +#define AHCI_ATTACH_STATE_ENCLOSURE             (0x1 << 10)
 534  560  
 535  561  /* Interval used for delay */
 536  562  #define AHCI_10MS_TICKS (drv_usectohz(10000))   /* ticks in 10 ms */
 537  563  #define AHCI_1MS_TICKS  (drv_usectohz(1000))    /* ticks in 1 ms */
 538  564  #define AHCI_100US_TICKS        (drv_usectohz(100))     /* ticks in 100 us */
 539  565  #define AHCI_10MS_USECS         (10000)         /* microsecs in 10 millisec */
 540  566  #define AHCI_1MS_USECS          (1000)          /* microsecs in 1 millisec */
 541  567  #define AHCI_100US_USECS        (100)
 542  568  
 543  569  /*
 544  570   * The following values are the numbers of times to retry polled requests.
 545  571   */
 546  572  #define AHCI_POLLRATE_HBA_RESET         100
 547  573  #define AHCI_POLLRATE_PORT_SSTATUS      10
 548  574  #define AHCI_POLLRATE_PORT_TFD_ERROR    1100
 549  575  #define AHCI_POLLRATE_PORT_IDLE         50
 550  576  #define AHCI_POLLRATE_PORT_SOFTRESET    100
 551  577  #define AHCI_POLLRATE_GET_SPKT          100
 552  578  #define AHCI_POLLRATE_PORT_IDLE_FR      500
 553  579  
 554  580  
 555  581  /* Clearing & setting the n'th bit in a given tag */
 556  582  #define CLEAR_BIT(tag, bit)     (tag &= ~(0x1<<bit))
 557  583  #define SET_BIT(tag, bit)       (tag |= (0x1<<bit))
 558  584  
 559  585  
 560  586  #if DEBUG
 561  587  
 562  588  #define AHCI_DEBUG              1
 563  589  
 564  590  #endif
 565  591  
 566  592  #define AHCIDBG_INIT            0x0001
 567  593  #define AHCIDBG_ENTRY           0x0002
 568  594  #define AHCIDBG_PRDT            0x0004
 569  595  #define AHCIDBG_EVENT           0x0008
 570  596  #define AHCIDBG_POLL_LOOP       0x0010
 571  597  #define AHCIDBG_PKTCOMP         0x0020
 572  598  #define AHCIDBG_TIMEOUT         0x0040
 573  599  #define AHCIDBG_INFO            0x0080
 574  600  #define AHCIDBG_VERBOSE         0x0100
 575  601  #define AHCIDBG_INTR            0x0200
 576  602  #define AHCIDBG_ERRS            0x0400
 577  603  #define AHCIDBG_ATACMD          0x0800
 578  604  #define AHCIDBG_ATAPICMD        0x1000
 579  605  #define AHCIDBG_SENSEDATA       0x2000
 580  606  #define AHCIDBG_NCQ             0x4000
 581  607  #define AHCIDBG_PM              0x8000
 582  608  #define AHCIDBG_UNDERFLOW       0x10000
 583  609  #define AHCIDBG_MSI             0x20000
 584  610  #define AHCIDBG_PMULT           0x40000
 585  611  
 586  612  extern uint32_t ahci_debug_flags;
 587  613  
 588  614  #if DEBUG
 589  615  
 590  616  #define AHCIDBG(flag, ahci_ctlp, fmt, args ...)                 \
 591  617          if (ahci_debug_flags & (flag)) {                        \
 592  618                  ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);     \
 593  619                  if (ahci_ctlp == NULL)                          \
 594  620                          sata_trace_debug(NULL, fmt, ## args);   \
 595  621                  else                                            \
 596  622                          sata_trace_debug(ahci_ctlp->ahcictl_dip,\
 597  623                              fmt, ## args);                      \
 598  624          }
 599  625  
 600  626  #else
 601  627  
 602  628  #define AHCIDBG(flag, ahci_ctlp, fmt, args ...)                 \
  
    | 
      ↓ open down ↓ | 
    59 lines elided | 
    
      ↑ open up ↑ | 
  
 603  629          if (ahci_debug_flags & (flag)) {                        \
 604  630                  if (ahci_ctlp == NULL)                          \
 605  631                          sata_trace_debug(NULL, fmt, ## args);   \
 606  632                  else                                            \
 607  633                          sata_trace_debug(ahci_ctlp->ahcictl_dip,\
 608  634                              fmt, ## args);                      \
 609  635          }
 610  636  
 611  637  #endif /* DEBUG */
 612  638  
      639 +/*
      640 + * Minimum size required for the enclosure message buffer. This value is in
      641 + * 4-byte quantities. So we need to multiply it by two.
      642 + */
      643 +#define AHCI_EM_BUFFER_MIN      2
 613  644  
      645 +/*
      646 + * Enclosure Management LED message format values
      647 + */
      648 +#define AHCI_LED_OFF    0
      649 +#define AHCI_LED_ON     1
      650 +
      651 +#define AHCI_LED_ACTIVITY_OFF   0
      652 +#define AHCI_LED_IDENT_OFF      3
      653 +#define AHCI_LED_FAULT_OFF      6
      654 +
      655 +#define AHCI_LED_MASK   0x7
      656 +
      657 +#define AHCI_EM_MSG_TYPE_LED    0
      658 +#define AHCI_EM_MSG_TYPE_SAFTE  1
      659 +#define AHCI_EM_MSG_TYPE_SES    2
      660 +#define AHCI_EM_MSG_TYPE_SGPIO  3
      661 +
      662 +#pragma pack(1)
      663 +typedef struct ahci_em_led_msg {
      664 +        uint8_t         alm_hba;
      665 +        uint8_t         alm_pminfo;
      666 +        uint16_t        alm_value;
      667 +} ahci_em_led_msg_t;
      668 +
      669 +typedef struct ahci_em_msg_hdr {
      670 +        uint8_t         aemh_rsvd;
      671 +        uint8_t         aemh_mlen;
      672 +        uint8_t         aemh_dlen;
      673 +        uint8_t         aemh_mtype;
      674 +} ahci_em_msg_hdr_t;
      675 +#pragma pack()
      676 +
 614  677  #ifdef  __cplusplus
 615  678  }
 616  679  #endif
 617  680  
 618  681  #endif /* _AHCIVAR_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX