Print this page
OS-1997 mpt_sas: expose LED controls to libtopo
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
          +++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
↓ open down ↓ 363 lines elided ↑ open up ↑
 364  364      uint16_t *handle, mptsas_target_t **pptgt);
 365  365  static void mptsas_update_phymask(mptsas_t *mpt);
 366  366  static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd);
 367  367  
 368  368  static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
 369  369      uint32_t *status, uint8_t cmd);
 370  370  static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
 371  371      mptsas_phymask_t *phymask);
 372  372  static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
 373  373      mptsas_phymask_t phymask);
 374      -static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
 375      -    uint32_t slotstatus);
      374 +static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
 376  375  
 377  376  
 378  377  /*
 379  378   * Enumeration / DR functions
 380  379   */
 381  380  static void mptsas_config_all(dev_info_t *pdip);
 382  381  static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
 383  382      dev_info_t **lundip);
 384  383  static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
 385  384      dev_info_t **lundip);
↓ open down ↓ 6060 lines elided ↑ open up ↑
6446 6445                              DDI_PROP_SUCCESS) {
6447 6446                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6448 6447                                      MPTSAS_VIRTUAL_PORT);
6449 6448                                  mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6450 6449                                      "prop update failed");
6451 6450                                  break;
6452 6451                          }
6453 6452                  }
6454 6453  
6455 6454                  mutex_enter(&mpt->m_mutex);
6456      -                if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) {
     6455 +                ptgt->m_led_status = 0;
     6456 +                if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
6457 6457                          NDBG14(("mptsas: clear LED for tgt %x failed",
6458 6458                              ptgt->m_slot_num));
6459 6459                  }
6460 6460                  if (rval == DDI_SUCCESS) {
6461 6461                          mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6462 6462                              ptgt->m_sas_wwn, ptgt->m_phymask);
6463 6463                          ptgt = NULL;
6464 6464                  } else {
6465 6465                          /*
6466 6466                           * clean DR_INTRANSITION flag to allow I/O down to
↓ open down ↓ 5479 lines elided ↑ open up ↑
11946 11946                  }
11947 11947          } else {
11948 11948                  status = EFAULT;
11949 11949          }
11950 11950  
11951 11951          mutex_exit(&mpt->m_mutex);
11952 11952          return (status);
11953 11953  }
11954 11954  
11955 11955  static int
     11956 +led_control(mptsas_t *mpt, intptr_t data, int mode)
     11957 +{
     11958 +        int ret = 0;
     11959 +        mptsas_led_control_t lc;
     11960 +        mptsas_target_t *ptgt;
     11961 +
     11962 +        if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
     11963 +                return (EFAULT);
     11964 +        }
     11965 +
     11966 +        if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
     11967 +             lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
     11968 +             lc.Led < MPTSAS_LEDCTL_LED_IDENT ||
     11969 +             lc.Led > MPTSAS_LEDCTL_LED_OK2RM ||
     11970 +             (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
     11971 +             lc.LedStatus != 1)) {
     11972 +                return (EINVAL);
     11973 +        }
     11974 +
     11975 +        /* Locate the target we're interrogating... */
     11976 +        mutex_enter(&mpt->m_mutex);
     11977 +        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
     11978 +            MPTSAS_HASH_FIRST);
     11979 +        while (ptgt != NULL) {
     11980 +                if (ptgt->m_enclosure == lc.Enclosure &&
     11981 +                    ptgt->m_slot_num == lc.Slot) {
     11982 +                        break;
     11983 +                }
     11984 +                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
     11985 +                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
     11986 +        }
     11987 +        if (ptgt == NULL) {
     11988 +                /* We could not find a target for that enclosure/slot. */
     11989 +                mutex_exit(&mpt->m_mutex);
     11990 +                return (ENOENT);
     11991 +        }
     11992 +
     11993 +        if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
     11994 +                /* Update our internal LED state. */
     11995 +                ptgt->m_led_status &= ~(1 << (lc.Led - 1));
     11996 +                ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
     11997 +
     11998 +                /* Flush it to the controller. */
     11999 +                ret = mptsas_flush_led_status(mpt, ptgt);
     12000 +                mutex_exit(&mpt->m_mutex);
     12001 +                return (ret);
     12002 +        }
     12003 +
     12004 +        /* Return our internal LED state. */
     12005 +        lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
     12006 +        mutex_exit(&mpt->m_mutex);
     12007 +
     12008 +        if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
     12009 +                return (EFAULT);
     12010 +        }
     12011 +
     12012 +        return (0);
     12013 +}
     12014 +
     12015 +static int
11956 12016  get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
11957 12017  {
11958 12018          int i = 0;
11959 12019          int count = 0;
11960 12020          int ret = 0;
11961 12021          mptsas_target_t *ptgt;
11962 12022          mptsas_disk_info_t *di;
11963 12023          STRUCT_DECL(mptsas_get_disk_info, gdi);
11964 12024  
11965 12025          STRUCT_INIT(gdi, get_udatamodel());
↓ open down ↓ 156 lines elided ↑ open up ↑
12122 12182                                      "found", addr));
12123 12183                                  ndi_dc_freehdl(dcp);
12124 12184                                  goto out;
12125 12185                          }
12126 12186                          mutex_enter(&mpt->m_mutex);
12127 12187                          if (cmd == DEVCTL_DEVICE_ONLINE) {
12128 12188                                  ptgt->m_tgt_unconfigured = 0;
12129 12189                          } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12130 12190                                  ptgt->m_tgt_unconfigured = 1;
12131 12191                          }
12132      -                        slotstatus = 0;
12133      -#ifdef MPTSAS_GET_LED
12134      -                        /*
12135      -                         * The get led status can't get a valid/reasonable
12136      -                         * state, so ignore the get led status, and write the
12137      -                         * required value directly
12138      -                         */
12139      -                        if (mptsas_get_led_status(mpt, ptgt, &slotstatus) !=
12140      -                            DDI_SUCCESS) {
12141      -                                NDBG14(("mptsas_ioctl: get LED for tgt %s "
12142      -                                    "failed %x", addr, slotstatus));
12143      -                                slotstatus = 0;
12144      -                        }
12145      -                        NDBG14(("mptsas_ioctl: LED status %x for %s",
12146      -                            slotstatus, addr));
12147      -#endif
12148 12192                          if (cmd == DEVCTL_DEVICE_OFFLINE) {
12149      -                                slotstatus |=
12150      -                                    MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
     12193 +                                ptgt->m_led_status |=
     12194 +                                    (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12151 12195                          } else {
12152      -                                slotstatus &=
12153      -                                    ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
     12196 +                                ptgt->m_led_status &=
     12197 +                                    ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12154 12198                          }
12155      -                        if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
12156      -                            DDI_SUCCESS) {
     12199 +                        if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
12157 12200                                  NDBG14(("mptsas_ioctl: set LED for tgt %s "
12158 12201                                      "failed %x", addr, slotstatus));
12159 12202                          }
12160 12203                          mutex_exit(&mpt->m_mutex);
12161 12204                          ndi_dc_freehdl(dcp);
12162 12205                  }
12163 12206                  goto out;
12164 12207          }
12165 12208          switch (cmd) {
12166 12209                  case MPTIOCTL_GET_DISK_INFO:
12167 12210                          status = get_disk_info(mpt, data, mode);
12168 12211                          break;
     12212 +                case MPTIOCTL_LED_CONTROL:
     12213 +                        status = led_control(mpt, data, mode);
     12214 +                        break;
12169 12215                  case MPTIOCTL_UPDATE_FLASH:
12170 12216                          if (ddi_copyin((void *)data, &flashdata,
12171 12217                                  sizeof (struct mptsas_update_flash), mode)) {
12172 12218                                  status = EFAULT;
12173 12219                                  break;
12174 12220                          }
12175 12221  
12176 12222                          mutex_enter(&mpt->m_mutex);
12177 12223                          if (mptsas_update_flash(mpt,
12178 12224                              (caddr_t)(long)flashdata.PtrBuffer,
↓ open down ↓ 2440 lines elided ↑ open up ↑
14619 14665                          if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14620 14666                                  /*
14621 14667                                   * Same path back online again.
14622 14668                                   */
14623 14669                                  (void) ddi_prop_free(old_guid);
14624 14670                                  if ((!MDI_PI_IS_ONLINE(*pip)) &&
14625 14671                                      (!MDI_PI_IS_STANDBY(*pip)) &&
14626 14672                                      (ptgt->m_tgt_unconfigured == 0)) {
14627 14673                                          rval = mdi_pi_online(*pip, 0);
14628 14674                                          mutex_enter(&mpt->m_mutex);
14629      -                                        (void) mptsas_set_led_status(mpt, ptgt,
14630      -                                            0);
     14675 +                                        ptgt->m_led_status = 0;
     14676 +                                        (void) mptsas_flush_led_status(mpt,
     14677 +                                            ptgt);
14631 14678                                          mutex_exit(&mpt->m_mutex);
14632 14679                                  } else {
14633 14680                                          rval = DDI_SUCCESS;
14634 14681                                  }
14635 14682                                  if (rval != DDI_SUCCESS) {
14636 14683                                          mptsas_log(mpt, CE_WARN, "path:target: "
14637 14684                                              "%x, lun:%x online failed!", target,
14638 14685                                              lun);
14639 14686                                          *pip = NULL;
14640 14687                                          *lun_dip = NULL;
↓ open down ↓ 236 lines elided ↑ open up ↑
14877 14924                          mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14878 14925                              "create phy-num property for target %d lun %d",
14879 14926                              target, lun);
14880 14927                          mdi_rtn = MDI_FAILURE;
14881 14928                          goto virt_create_done;
14882 14929                  }
14883 14930                  NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14884 14931                  mdi_rtn = mdi_pi_online(*pip, 0);
14885 14932                  if (mdi_rtn == MDI_SUCCESS) {
14886 14933                          mutex_enter(&mpt->m_mutex);
14887      -                        if (mptsas_set_led_status(mpt, ptgt, 0) !=
14888      -                            DDI_SUCCESS) {
     14934 +                        ptgt->m_led_status = 0;
     14935 +                        if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
14889 14936                                  NDBG14(("mptsas: clear LED for slot %x "
14890 14937                                      "failed", ptgt->m_slot_num));
14891 14938                          }
14892 14939                          mutex_exit(&mpt->m_mutex);
14893 14940                  }
14894 14941                  if (mdi_rtn == MDI_NOT_SUPPORTED) {
14895 14942                          mdi_rtn = MDI_FAILURE;
14896 14943                  }
14897 14944  virt_create_done:
14898 14945                  if (*pip && mdi_rtn != MDI_SUCCESS) {
↓ open down ↓ 340 lines elided ↑ open up ↑
15239 15286                   * If props were setup ok, online the lun
15240 15287                   */
15241 15288                  if (ndi_rtn == NDI_SUCCESS) {
15242 15289                          /*
15243 15290                           * Try to online the new node
15244 15291                           */
15245 15292                          ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15246 15293                  }
15247 15294                  if (ndi_rtn == NDI_SUCCESS) {
15248 15295                          mutex_enter(&mpt->m_mutex);
15249      -                        if (mptsas_set_led_status(mpt, ptgt, 0) !=
15250      -                            DDI_SUCCESS) {
     15296 +                        ptgt->m_led_status = 0;
     15297 +                        if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
15251 15298                                  NDBG14(("mptsas: clear LED for tgt %x "
15252 15299                                      "failed", ptgt->m_slot_num));
15253 15300                          }
15254 15301                          mutex_exit(&mpt->m_mutex);
15255 15302                  }
15256 15303  
15257 15304                  /*
15258 15305                   * If success set rtn flag, else unwire alloc'd lun
15259 15306                   */
15260 15307                  if (ndi_rtn != NDI_SUCCESS) {
↓ open down ↓ 880 lines elided ↑ open up ↑
16141 16188                  return (NULL);
16142 16189          }
16143 16190          if (addr[0] == 'w') {
16144 16191                  ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16145 16192          } else {
16146 16193                  ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16147 16194          }
16148 16195          return (ptgt);
16149 16196  }
16150 16197  
16151      -#ifdef MPTSAS_GET_LED
16152 16198  static int
16153      -mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
16154      -    uint32_t *slotstatus)
16155      -{
16156      -        return (mptsas_send_sep(mpt, ptgt, slotstatus,
16157      -            MPI2_SEP_REQ_ACTION_READ_STATUS));
16158      -}
16159      -#endif
16160      -static int
16161      -mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus)
     16199 +mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
16162 16200  {
     16201 +        uint32_t slotstatus = 0;
     16202 +
     16203 +        /* Build an MPI2 Slot Status based on our view of the world */
     16204 +        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
     16205 +                slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
     16206 +        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
     16207 +                slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
     16208 +        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
     16209 +                slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
     16210 +
     16211 +        /* Write it to the controller */
16163 16212          NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16164 16213              slotstatus, ptgt->m_slot_num));
16165 16214          return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16166 16215              MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16167 16216  }
     16217 +
16168 16218  /*
16169 16219   *  send sep request, use enclosure/slot addressing
16170 16220   */
16171 16221  static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16172 16222      uint32_t *status, uint8_t act)
16173 16223  {
16174 16224          Mpi2SepRequest_t        req;
16175 16225          Mpi2SepReply_t          rep;
16176 16226          int                     ret;
16177 16227  
↓ open down ↓ 117 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX