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
↓ 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)
↓ 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];
↓ 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,
↓ 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)          \
↓ 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  /*
↓ 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