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;
|