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  */
  25 /*
  26  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright 2016 Argo Technologies SA
  28  */
  29 
  30 /*
  31  * SATA Framework
  32  * Generic SATA Host Adapter Implementation
  33  */
  34 
  35 #include <sys/conf.h>
  36 #include <sys/file.h>
  37 #include <sys/ddi.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/modctl.h>
  40 #include <sys/cmn_err.h>
  41 #include <sys/errno.h>
  42 #include <sys/thread.h>
  43 #include <sys/kstat.h>
  44 #include <sys/note.h>
  45 #include <sys/sysevent.h>
  46 #include <sys/sysevent/eventdefs.h>
  47 #include <sys/sysevent/dr.h>
 
 
1332                 return (ENXIO);
1333 
1334         if (sata_hba_inst->satahba_tran == NULL)
1335                 return (ENXIO);
1336 
1337         switch (cmd) {
1338 
1339         case DEVCTL_DEVICE_GETSTATE:
1340         case DEVCTL_DEVICE_ONLINE:
1341         case DEVCTL_DEVICE_OFFLINE:
1342         case DEVCTL_DEVICE_REMOVE:
1343         case DEVCTL_BUS_GETSTATE:
1344                 /*
1345                  * There may be more cases that we want to pass to default
1346                  * handler rather than fail them.
1347                  */
1348                 return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
1349         }
1350 
1351         /* read devctl ioctl data */
1352         if (cmd != DEVCTL_AP_CONTROL) {
1353                 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1354                         return (EFAULT);
1355 
1356                 if ((comp_port = sata_get_port_num(sata_hba_inst, dcp)) ==
1357                     -1) {
1358                         if (dcp)
1359                                 ndi_dc_freehdl(dcp);
1360                         return (EINVAL);
1361                 }
1362 
1363                 /*
1364                  * According to SCSI_TO_SATA_ADDR_QUAL, qual should be either
1365                  * SATA_ADDR_DCPORT or SATA_ADDR_DPMPORT.
1366                  */
1367                 cport = SCSI_TO_SATA_CPORT(comp_port);
1368                 pmport = SCSI_TO_SATA_PMPORT(comp_port);
1369                 qual = SCSI_TO_SATA_ADDR_QUAL(comp_port);
1370 
1371                 if (sata_validate_sata_address(sata_hba_inst, cport, pmport,
1372                     qual) != 0) {
 
1660                     "passthrough to HBA", cmd);
1661 
1662                 if (sata_tran->sata_tran_ioctl == NULL) {
1663                         rv = EINVAL;
1664                         break;
1665                 }
1666                 rval = (*sata_tran->sata_tran_ioctl)(mydip, cmd, arg);
1667                 if (rval != 0) {
1668                         SATADBG1(SATA_DBG_IOCTL_IF, sata_hba_inst,
1669                             "IOCTL 0x%2x failed in HBA", cmd);
1670                         rv = rval;
1671                 }
1672                 break;
1673         }
1674 
1675         } /* End of main IOCTL switch */
1676 
1677         if (dcp) {
1678                 ndi_dc_freehdl(dcp);
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 
1684         return (rv);
1685 }
1686 
1687 
1688 /*
1689  * Create error retrieval sata packet
1690  *
1691  * A sata packet is allocated and set-up to contain specified error retrieval
1692  * command and appropriate dma-able data buffer.
1693  * No association with any scsi packet is made and no callback routine is
1694  * specified.
1695  *
1696  * Returns a pointer to sata packet upon successful packet creation.
1697  * Returns NULL, if packet cannot be created.
1698  */
1699 sata_pkt_t *
1700 sata_get_error_retrieval_pkt(dev_info_t *dip, sata_device_t *sata_device,
1701     int pkt_type)
1702 {
 
4828                     "DSM support 0x%x, max number of 512 byte blocks of LBA "
4829                     "range entries 0x%x\n", sdinfo->satadrv_id.ai_dsm,
4830                     sdinfo->satadrv_id.ai_maxcount);
4831         }
4832 
4833         rval = sata_txlt_generic_pkt_info(spx, &reason, 1);
4834         if ((rval != TRAN_ACCEPT) || (reason == CMD_DEV_GONE)) {
4835                 mutex_exit(cport_mutex);
4836                 return (rval);
4837         }
4838 
4839         /*
4840          * Need to modify bp to have TRIM data instead of UNMAP data.
4841          * Start by getting the block descriptor data length by subtracting
4842          * the 8 byte parameter list header from the parameter list length.
4843          * The block descriptor size has to be a multiple of 16 bytes.
4844          */
4845         bdlen = scsipkt->pkt_cdbp[7];
4846         bdlen = (bdlen << 8) + scsipkt->pkt_cdbp[8] - paramlen;
4847         if ((bdlen < 0) || ((bdlen % 16) != 0) ||
4848             (bdlen > (bp->b_bcount - paramlen))) {
4849                 SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst,
4850                     "sata_txlt_unmap: invalid block descriptor length", NULL);
4851                 mutex_exit(cport_mutex);
4852                 return ((sata_txlt_check_condition(spx, KEY_ILLEGAL_REQUEST,
4853                     SD_SCSI_ASC_INVALID_FIELD_IN_CDB)));
4854         }
4855         /*
4856          * If there are no parameter data or block descriptors, it is not
4857          * considered an error so just complete the command without sending
4858          * TRIM.
4859          */
4860         if ((bdlen == 0) || (bp == NULL) || (bp->b_un.b_addr == NULL) ||
4861             (bp->b_bcount == 0)) {
4862                 SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst,
4863                     "sata_txlt_unmap: no parameter data or block descriptors",
4864                     NULL);
4865                 mutex_exit(cport_mutex);
4866                 return (sata_txlt_unmap_nodata_cmd(spx));
4867         }
4868         tmpbd = (uint8_t *)bp->b_un.b_addr + paramlen;
 
 | 
 
 
   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 2016 Nexenta Systems, Inc.
  25  * Copyright 2016 Argo Technologies SA
  26  * Copyright (c) 2018, Joyent, Inc.
  27  */
  28 
  29 /*
  30  * SATA Framework
  31  * Generic SATA Host Adapter Implementation
  32  */
  33 
  34 #include <sys/conf.h>
  35 #include <sys/file.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/modctl.h>
  39 #include <sys/cmn_err.h>
  40 #include <sys/errno.h>
  41 #include <sys/thread.h>
  42 #include <sys/kstat.h>
  43 #include <sys/note.h>
  44 #include <sys/sysevent.h>
  45 #include <sys/sysevent/eventdefs.h>
  46 #include <sys/sysevent/dr.h>
 
 
1331                 return (ENXIO);
1332 
1333         if (sata_hba_inst->satahba_tran == NULL)
1334                 return (ENXIO);
1335 
1336         switch (cmd) {
1337 
1338         case DEVCTL_DEVICE_GETSTATE:
1339         case DEVCTL_DEVICE_ONLINE:
1340         case DEVCTL_DEVICE_OFFLINE:
1341         case DEVCTL_DEVICE_REMOVE:
1342         case DEVCTL_BUS_GETSTATE:
1343                 /*
1344                  * There may be more cases that we want to pass to default
1345                  * handler rather than fail them.
1346                  */
1347                 return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
1348         }
1349 
1350         /* read devctl ioctl data */
1351         if (cmd != DEVCTL_AP_CONTROL && cmd >= DEVCTL_IOC &&
1352             cmd <= DEVCTL_IOC_MAX) {
1353                 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1354                         return (EFAULT);
1355 
1356                 if ((comp_port = sata_get_port_num(sata_hba_inst, dcp)) ==
1357                     -1) {
1358                         if (dcp)
1359                                 ndi_dc_freehdl(dcp);
1360                         return (EINVAL);
1361                 }
1362 
1363                 /*
1364                  * According to SCSI_TO_SATA_ADDR_QUAL, qual should be either
1365                  * SATA_ADDR_DCPORT or SATA_ADDR_DPMPORT.
1366                  */
1367                 cport = SCSI_TO_SATA_CPORT(comp_port);
1368                 pmport = SCSI_TO_SATA_PMPORT(comp_port);
1369                 qual = SCSI_TO_SATA_ADDR_QUAL(comp_port);
1370 
1371                 if (sata_validate_sata_address(sata_hba_inst, cport, pmport,
1372                     qual) != 0) {
 
1660                     "passthrough to HBA", cmd);
1661 
1662                 if (sata_tran->sata_tran_ioctl == NULL) {
1663                         rv = EINVAL;
1664                         break;
1665                 }
1666                 rval = (*sata_tran->sata_tran_ioctl)(mydip, cmd, arg);
1667                 if (rval != 0) {
1668                         SATADBG1(SATA_DBG_IOCTL_IF, sata_hba_inst,
1669                             "IOCTL 0x%2x failed in HBA", cmd);
1670                         rv = rval;
1671                 }
1672                 break;
1673         }
1674 
1675         } /* End of main IOCTL switch */
1676 
1677         if (dcp) {
1678                 ndi_dc_freehdl(dcp);
1679         }
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 
1688         return (rv);
1689 }
1690 
1691 
1692 /*
1693  * Create error retrieval sata packet
1694  *
1695  * A sata packet is allocated and set-up to contain specified error retrieval
1696  * command and appropriate dma-able data buffer.
1697  * No association with any scsi packet is made and no callback routine is
1698  * specified.
1699  *
1700  * Returns a pointer to sata packet upon successful packet creation.
1701  * Returns NULL, if packet cannot be created.
1702  */
1703 sata_pkt_t *
1704 sata_get_error_retrieval_pkt(dev_info_t *dip, sata_device_t *sata_device,
1705     int pkt_type)
1706 {
 
4832                     "DSM support 0x%x, max number of 512 byte blocks of LBA "
4833                     "range entries 0x%x\n", sdinfo->satadrv_id.ai_dsm,
4834                     sdinfo->satadrv_id.ai_maxcount);
4835         }
4836 
4837         rval = sata_txlt_generic_pkt_info(spx, &reason, 1);
4838         if ((rval != TRAN_ACCEPT) || (reason == CMD_DEV_GONE)) {
4839                 mutex_exit(cport_mutex);
4840                 return (rval);
4841         }
4842 
4843         /*
4844          * Need to modify bp to have TRIM data instead of UNMAP data.
4845          * Start by getting the block descriptor data length by subtracting
4846          * the 8 byte parameter list header from the parameter list length.
4847          * The block descriptor size has to be a multiple of 16 bytes.
4848          */
4849         bdlen = scsipkt->pkt_cdbp[7];
4850         bdlen = (bdlen << 8) + scsipkt->pkt_cdbp[8] - paramlen;
4851         if ((bdlen < 0) || ((bdlen % 16) != 0) ||
4852             ((bp != NULL) && (bdlen > (bp->b_bcount - paramlen)))) {
4853                 SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst,
4854                     "sata_txlt_unmap: invalid block descriptor length", NULL);
4855                 mutex_exit(cport_mutex);
4856                 return ((sata_txlt_check_condition(spx, KEY_ILLEGAL_REQUEST,
4857                     SD_SCSI_ASC_INVALID_FIELD_IN_CDB)));
4858         }
4859         /*
4860          * If there are no parameter data or block descriptors, it is not
4861          * considered an error so just complete the command without sending
4862          * TRIM.
4863          */
4864         if ((bdlen == 0) || (bp == NULL) || (bp->b_un.b_addr == NULL) ||
4865             (bp->b_bcount == 0)) {
4866                 SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst,
4867                     "sata_txlt_unmap: no parameter data or block descriptors",
4868                     NULL);
4869                 mutex_exit(cport_mutex);
4870                 return (sata_txlt_unmap_nodata_cmd(spx));
4871         }
4872         tmpbd = (uint8_t *)bp->b_un.b_addr + paramlen;
 
 |