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
NEX-5834 panic in sata module while running trim
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-4418 SATA inquiry property generation doesn't work as advertised
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
1787 SATL fails to handle returned SMART sense data
Reviewed by: Richard Elling <richard.elling@richardelling.com>
Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
re #12164 Marvell 88SE9128: Appliance hard hangs on boot probing duplicated ahci device

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/sata/impl/sata.c
          +++ new/usr/src/uts/common/io/sata/impl/sata.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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      - */
  25      -/*
  26      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright 2016 Nexenta Systems, Inc.
  27   25   * Copyright 2016 Argo Technologies SA
       26 + * Copyright (c) 2018, Joyent, Inc.
  28   27   */
  29   28  
  30   29  /*
  31   30   * SATA Framework
  32   31   * Generic SATA Host Adapter Implementation
  33   32   */
  34   33  
  35   34  #include <sys/conf.h>
  36   35  #include <sys/file.h>
  37   36  #include <sys/ddi.h>
↓ open down ↓ 1304 lines elided ↑ open up ↑
1342 1341          case DEVCTL_DEVICE_REMOVE:
1343 1342          case DEVCTL_BUS_GETSTATE:
1344 1343                  /*
1345 1344                   * There may be more cases that we want to pass to default
1346 1345                   * handler rather than fail them.
1347 1346                   */
1348 1347                  return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
1349 1348          }
1350 1349  
1351 1350          /* read devctl ioctl data */
1352      -        if (cmd != DEVCTL_AP_CONTROL) {
     1351 +        if (cmd != DEVCTL_AP_CONTROL && cmd >= DEVCTL_IOC &&
     1352 +            cmd <= DEVCTL_IOC_MAX) {
1353 1353                  if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1354 1354                          return (EFAULT);
1355 1355  
1356 1356                  if ((comp_port = sata_get_port_num(sata_hba_inst, dcp)) ==
1357 1357                      -1) {
1358 1358                          if (dcp)
1359 1359                                  ndi_dc_freehdl(dcp);
1360 1360                          return (EINVAL);
1361 1361                  }
1362 1362  
↓ open down ↓ 307 lines elided ↑ open up ↑
1670 1670                          rv = rval;
1671 1671                  }
1672 1672                  break;
1673 1673          }
1674 1674  
1675 1675          } /* End of main IOCTL switch */
1676 1676  
1677 1677          if (dcp) {
1678 1678                  ndi_dc_freehdl(dcp);
1679 1679          }
1680      -        mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
1681      -        cportinfo->cport_event_flags &= ~SATA_APCTL_LOCK_PORT_BUSY;
1682      -        mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
1683 1680  
     1681 +        if (cmd >= DEVCTL_IOC && cmd <= DEVCTL_IOC_MAX) {
     1682 +                mutex_enter(&SATA_CPORT_INFO(sata_hba_inst,
     1683 +                    cport)->cport_mutex);
     1684 +                cportinfo->cport_event_flags &= ~SATA_APCTL_LOCK_PORT_BUSY;
     1685 +                mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
     1686 +        }
     1687 +
1684 1688          return (rv);
1685 1689  }
1686 1690  
1687 1691  
1688 1692  /*
1689 1693   * Create error retrieval sata packet
1690 1694   *
1691 1695   * A sata packet is allocated and set-up to contain specified error retrieval
1692 1696   * command and appropriate dma-able data buffer.
1693 1697   * No association with any scsi packet is made and no callback routine is
↓ open down ↓ 3144 lines elided ↑ open up ↑
4838 4842  
4839 4843          /*
4840 4844           * Need to modify bp to have TRIM data instead of UNMAP data.
4841 4845           * Start by getting the block descriptor data length by subtracting
4842 4846           * the 8 byte parameter list header from the parameter list length.
4843 4847           * The block descriptor size has to be a multiple of 16 bytes.
4844 4848           */
4845 4849          bdlen = scsipkt->pkt_cdbp[7];
4846 4850          bdlen = (bdlen << 8) + scsipkt->pkt_cdbp[8] - paramlen;
4847 4851          if ((bdlen < 0) || ((bdlen % 16) != 0) ||
4848      -            (bdlen > (bp->b_bcount - paramlen))) {
     4852 +            ((bp != NULL) && (bdlen > (bp->b_bcount - paramlen)))) {
4849 4853                  SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst,
4850 4854                      "sata_txlt_unmap: invalid block descriptor length", NULL);
4851 4855                  mutex_exit(cport_mutex);
4852 4856                  return ((sata_txlt_check_condition(spx, KEY_ILLEGAL_REQUEST,
4853 4857                      SD_SCSI_ASC_INVALID_FIELD_IN_CDB)));
4854 4858          }
4855 4859          /*
4856 4860           * If there are no parameter data or block descriptors, it is not
4857 4861           * considered an error so just complete the command without sending
4858 4862           * TRIM.
↓ open down ↓ 4348 lines elided ↑ open up ↑
9207 9211   *
9208 9212   * ID FLAG THRESH VALUE WORST RAW on start/stop counter attribute
9209 9213   *
9210 9214   * Takes a sata_drive_info t * and the address of a buffer
9211 9215   * in which to create the page information as well as a sata_hba_inst_t *.
9212 9216   *
9213 9217   * Returns the number of bytes valid in the buffer.
9214 9218   */
9215 9219  static  int
9216 9220  sata_build_lsense_page_0e(sata_drive_info_t *sdinfo, uint8_t *buf,
9217      -        sata_pkt_txlate_t *spx)
     9221 +    sata_pkt_txlate_t *spx)
9218 9222  {
9219 9223          struct start_stop_cycle_counter_log *log_page;
9220 9224          int i, rval, index;
9221 9225          uint8_t smart_data[512], id, value, worst, thresh;
9222 9226          uint32_t max_count, cycles;
9223 9227  
9224 9228          /* Now do the SMART READ DATA */
9225 9229          rval = sata_fetch_smart_data(spx->txlt_sata_hba_inst, sdinfo,
9226 9230              (struct smart_data *)smart_data);
9227 9231          if (rval == -1)
↓ open down ↓ 1672 lines elided ↑ open up ↑
10900 10904   * Create scsi target node for attached device, create node properties and
10901 10905   * attach the node.
10902 10906   * The node could be removed if the device onlining fails.
10903 10907   *
10904 10908   * A dev_info_t pointer is returned if operation is successful, NULL is
10905 10909   * returned otherwise.
10906 10910   */
10907 10911  
10908 10912  static dev_info_t *
10909 10913  sata_create_target_node(dev_info_t *dip, sata_hba_inst_t *sata_hba_inst,
10910      -                        sata_address_t *sata_addr)
     10914 +    sata_address_t *sata_addr)
10911 10915  {
10912 10916          dev_info_t *cdip = NULL;
10913 10917          int rval;
10914 10918          char *nname = NULL;
10915 10919          char **compatible = NULL;
10916 10920          int ncompatible;
10917 10921          struct scsi_inquiry inq;
10918 10922          sata_device_t sata_device;
10919 10923          sata_drive_info_t *sdinfo;
10920 10924          int target;
↓ open down ↓ 167 lines elided ↑ open up ↑
11088 11092              "cannot create target node for SATA device at port %d",
11089 11093              sata_addr->cport);
11090 11094          return (NULL);
11091 11095  }
11092 11096  
11093 11097  /*
11094 11098   * Remove a target node.
11095 11099   */
11096 11100  static void
11097 11101  sata_remove_target_node(sata_hba_inst_t *sata_hba_inst,
11098      -                        sata_address_t *sata_addr)
     11102 +    sata_address_t *sata_addr)
11099 11103  {
11100 11104          dev_info_t *tdip;
11101 11105          uint8_t cport = sata_addr->cport;
11102 11106          uint8_t pmport = sata_addr->pmport;
11103 11107          uint8_t qual = sata_addr->qual;
11104 11108  
11105 11109          /* Note the sata daemon uses the address of the port/pmport */
11106 11110          ASSERT(qual == SATA_ADDR_CPORT || qual == SATA_ADDR_PMPORT);
11107 11111  
11108 11112          /* Remove target node */
↓ open down ↓ 1121 lines elided ↑ open up ↑
12230 12234  /*
12231 12235   * Validate sata address.
12232 12236   * Specified cport, pmport and qualifier has to match
12233 12237   * passed sata_scsi configuration info.
12234 12238   * The presence of an attached device is not verified.
12235 12239   *
12236 12240   * Returns 0 when address is valid, -1 otherwise.
12237 12241   */
12238 12242  static int
12239 12243  sata_validate_sata_address(sata_hba_inst_t *sata_hba_inst, int cport,
12240      -        int pmport, int qual)
     12244 +    int pmport, int qual)
12241 12245  {
12242 12246          if (qual == SATA_ADDR_DCPORT && pmport != 0)
12243 12247                  goto invalid_address;
12244 12248          if (cport >= SATA_NUM_CPORTS(sata_hba_inst))
12245 12249                  goto invalid_address;
12246 12250          if ((qual == SATA_ADDR_DPMPORT || qual == SATA_ADDR_PMPORT) &&
12247 12251              ((SATA_CPORT_DEV_TYPE(sata_hba_inst, cport) != SATA_DTYPE_PMULT) ||
12248 12252              (SATA_PMULT_INFO(sata_hba_inst, cport) == NULL) ||
12249 12253              (pmport >= SATA_NUM_PMPORTS(sata_hba_inst, cport))))
12250 12254                  goto invalid_address;
↓ open down ↓ 12 lines elided ↑ open up ↑
12263 12267   * Returns 0 if a scsi target refers to an attached device,
12264 12268   * returns 1 if address is valid but no valid device is attached,
12265 12269   * returns 2 if address is valid but device type is unknown (not valid device),
12266 12270   * returns -1 if bad address or device is of an unsupported type.
12267 12271   * Upon return sata_device argument is set.
12268 12272   *
12269 12273   * Port multiplier is supported now.
12270 12274   */
12271 12275  static int
12272 12276  sata_validate_scsi_address(sata_hba_inst_t *sata_hba_inst,
12273      -        struct scsi_address *ap, sata_device_t *sata_device)
     12277 +    struct scsi_address *ap, sata_device_t *sata_device)
12274 12278  {
12275 12279          int cport, pmport, qual, rval;
12276 12280  
12277 12281          rval = -1;      /* Invalid address */
12278 12282          if (ap->a_lun != 0)
12279 12283                  goto out;
12280 12284  
12281 12285          qual = SCSI_TO_SATA_ADDR_QUAL(ap->a_target);
12282 12286          cport = SCSI_TO_SATA_CPORT(ap->a_target);
12283 12287          pmport = SCSI_TO_SATA_PMPORT(ap->a_target);
↓ open down ↓ 8848 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX