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