1*f11c7f63SJim Harris /*- 2*f11c7f63SJim Harris * This file is provided under a dual BSD/GPLv2 license. When using or 3*f11c7f63SJim Harris * redistributing this file, you may do so under either license. 4*f11c7f63SJim Harris * 5*f11c7f63SJim Harris * GPL LICENSE SUMMARY 6*f11c7f63SJim Harris * 7*f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8*f11c7f63SJim Harris * 9*f11c7f63SJim Harris * This program is free software; you can redistribute it and/or modify 10*f11c7f63SJim Harris * it under the terms of version 2 of the GNU General Public License as 11*f11c7f63SJim Harris * published by the Free Software Foundation. 12*f11c7f63SJim Harris * 13*f11c7f63SJim Harris * This program is distributed in the hope that it will be useful, but 14*f11c7f63SJim Harris * WITHOUT ANY WARRANTY; without even the implied warranty of 15*f11c7f63SJim Harris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16*f11c7f63SJim Harris * General Public License for more details. 17*f11c7f63SJim Harris * 18*f11c7f63SJim Harris * You should have received a copy of the GNU General Public License 19*f11c7f63SJim Harris * along with this program; if not, write to the Free Software 20*f11c7f63SJim Harris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21*f11c7f63SJim Harris * The full GNU General Public License is included in this distribution 22*f11c7f63SJim Harris * in the file called LICENSE.GPL. 23*f11c7f63SJim Harris * 24*f11c7f63SJim Harris * BSD LICENSE 25*f11c7f63SJim Harris * 26*f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27*f11c7f63SJim Harris * All rights reserved. 28*f11c7f63SJim Harris * 29*f11c7f63SJim Harris * Redistribution and use in source and binary forms, with or without 30*f11c7f63SJim Harris * modification, are permitted provided that the following conditions 31*f11c7f63SJim Harris * are met: 32*f11c7f63SJim Harris * 33*f11c7f63SJim Harris * * Redistributions of source code must retain the above copyright 34*f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer. 35*f11c7f63SJim Harris * * Redistributions in binary form must reproduce the above copyright 36*f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer in 37*f11c7f63SJim Harris * the documentation and/or other materials provided with the 38*f11c7f63SJim Harris * distribution. 39*f11c7f63SJim Harris * 40*f11c7f63SJim Harris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41*f11c7f63SJim Harris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42*f11c7f63SJim Harris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43*f11c7f63SJim Harris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44*f11c7f63SJim Harris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45*f11c7f63SJim Harris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46*f11c7f63SJim Harris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47*f11c7f63SJim Harris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48*f11c7f63SJim Harris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49*f11c7f63SJim Harris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50*f11c7f63SJim Harris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51*f11c7f63SJim Harris */ 52*f11c7f63SJim Harris 53*f11c7f63SJim Harris #include <sys/cdefs.h> 54*f11c7f63SJim Harris __FBSDID("$FreeBSD$"); 55*f11c7f63SJim Harris 56*f11c7f63SJim Harris /** 57*f11c7f63SJim Harris * @file 58*f11c7f63SJim Harris * @brief This file contains all of the defintions for the SATI remote 59*f11c7f63SJim Harris * device object. Some translations require information to be 60*f11c7f63SJim Harris * remembered on a per device basis. This information is stored 61*f11c7f63SJim Harris * in the object defined in this file. 62*f11c7f63SJim Harris */ 63*f11c7f63SJim Harris 64*f11c7f63SJim Harris #include <dev/isci/scil/sati_device.h> 65*f11c7f63SJim Harris #include <dev/isci/scil/sci_util.h> // Move this file. 66*f11c7f63SJim Harris #include <dev/isci/scil/sati_unmap.h> 67*f11c7f63SJim Harris #include <dev/isci/scil/intel_scsi.h> 68*f11c7f63SJim Harris 69*f11c7f63SJim Harris /** 70*f11c7f63SJim Harris * @brief This method simply initializes the data members in the device 71*f11c7f63SJim Harris * object to their appropriate values. 72*f11c7f63SJim Harris * 73*f11c7f63SJim Harris * @param[in] device This parameter specifies the device for which to 74*f11c7f63SJim Harris * initialize the data members. 75*f11c7f63SJim Harris * @param[in] is_ncq_enabled This parameter specifies if NCQ is to be 76*f11c7f63SJim Harris * utilized for this particular SATI device. 77*f11c7f63SJim Harris * @param[in] max_ncq_depth This parameter specifies the maximum desired 78*f11c7f63SJim Harris * NCQ depth. Once this value is set it can never be increased. 79*f11c7f63SJim Harris * @param[in] ignore_fua This parameter specifies FUA is to be ignored and not 80*f11c7f63SJim Harris * sent to the end device. Some OS (Windows) has quirky behaviors with FUA 81*f11c7f63SJim Harris * and recommend driver developers ignore the bit. 82*f11c7f63SJim Harris * 83*f11c7f63SJim Harris * @return none 84*f11c7f63SJim Harris */ 85*f11c7f63SJim Harris void sati_device_construct( 86*f11c7f63SJim Harris SATI_DEVICE_T * device, 87*f11c7f63SJim Harris BOOL is_ncq_enabled, 88*f11c7f63SJim Harris U8 max_ncq_depth, 89*f11c7f63SJim Harris BOOL ignore_fua 90*f11c7f63SJim Harris ) 91*f11c7f63SJim Harris { 92*f11c7f63SJim Harris device->state = SATI_DEVICE_STATE_OPERATIONAL; 93*f11c7f63SJim Harris device->capabilities = 0; 94*f11c7f63SJim Harris device->descriptor_sense_enable = SCSI_MODE_PAGE_CONTROL_D_SENSE_DISABLE; 95*f11c7f63SJim Harris 96*f11c7f63SJim Harris // The user requested that NCQ be utilized if it is supported by 97*f11c7f63SJim Harris // the device. 98*f11c7f63SJim Harris if (is_ncq_enabled == TRUE) 99*f11c7f63SJim Harris device->capabilities |= SATI_DEVICE_CAP_NCQ_REQUESTED_ENABLE; 100*f11c7f63SJim Harris 101*f11c7f63SJim Harris device->ncq_depth = max_ncq_depth; 102*f11c7f63SJim Harris 103*f11c7f63SJim Harris // The user requested that FUA is ignored (windows performance issue) 104*f11c7f63SJim Harris if (ignore_fua == TRUE) 105*f11c7f63SJim Harris device->capabilities |= SATI_DEVICE_CAP_IGNORE_FUA; 106*f11c7f63SJim Harris 107*f11c7f63SJim Harris } 108*f11c7f63SJim Harris 109*f11c7f63SJim Harris /** 110*f11c7f63SJim Harris * @brief This method will update the SATI_DEVICE capabilities based on 111*f11c7f63SJim Harris * the supplied ATA_IDENTIFY_DEVICE_DATA. 112*f11c7f63SJim Harris * 113*f11c7f63SJim Harris * @param[in] device This parameter specifies the device for which to update 114*f11c7f63SJim Harris * the supported capabilities. 115*f11c7f63SJim Harris * @param[in] identify This parameter specifies the ata identify device 116*f11c7f63SJim Harris * information from which to extract the capabilities of the 117*f11c7f63SJim Harris * device. 118*f11c7f63SJim Harris * 119*f11c7f63SJim Harris * @return none 120*f11c7f63SJim Harris */ 121*f11c7f63SJim Harris void sati_device_update_capabilities( 122*f11c7f63SJim Harris SATI_DEVICE_T * device, 123*f11c7f63SJim Harris ATA_IDENTIFY_DEVICE_DATA_T * identify 124*f11c7f63SJim Harris ) 125*f11c7f63SJim Harris { 126*f11c7f63SJim Harris U16 capabilities = 0; 127*f11c7f63SJim Harris 128*f11c7f63SJim Harris if (identify->capabilities1 & ATA_IDENTIFY_CAPABILITIES1_NORMAL_DMA_ENABLE) 129*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_UDMA_ENABLE; 130*f11c7f63SJim Harris 131*f11c7f63SJim Harris if (identify->command_set_supported1 132*f11c7f63SJim Harris & ATA_IDENTIFY_COMMAND_SET_SUPPORTED1_48BIT_ENABLE) 133*f11c7f63SJim Harris { 134*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_48BIT_ENABLE; 135*f11c7f63SJim Harris } 136*f11c7f63SJim Harris 137*f11c7f63SJim Harris if (identify->command_set_supported0 138*f11c7f63SJim Harris & ATA_IDENTIFY_COMMAND_SET_SUPPORTED0_SMART_ENABLE) 139*f11c7f63SJim Harris { 140*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_SMART_SUPPORT; 141*f11c7f63SJim Harris } 142*f11c7f63SJim Harris 143*f11c7f63SJim Harris if (identify->command_set_enabled0 144*f11c7f63SJim Harris & ATA_IDENTIFY_COMMAND_SET_SUPPORTED0_SMART_ENABLE) 145*f11c7f63SJim Harris { 146*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_SMART_ENABLE; 147*f11c7f63SJim Harris } 148*f11c7f63SJim Harris 149*f11c7f63SJim Harris // Save the NCQ related capabilities information. 150*f11c7f63SJim Harris if (identify->serial_ata_capabilities 151*f11c7f63SJim Harris & ATA_IDENTIFY_SATA_CAPABILITIES_NCQ_ENABLE) 152*f11c7f63SJim Harris { 153*f11c7f63SJim Harris if (device->capabilities & SATI_DEVICE_CAP_NCQ_REQUESTED_ENABLE) 154*f11c7f63SJim Harris { 155*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_NCQ_REQUESTED_ENABLE; 156*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE; 157*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_DMA_FUA_ENABLE; 158*f11c7f63SJim Harris device->ncq_depth = MIN( 159*f11c7f63SJim Harris device->ncq_depth, 160*f11c7f63SJim Harris (U8) (identify->queue_depth 161*f11c7f63SJim Harris & ATA_IDENTIFY_NCQ_QUEUE_DEPTH_ENABLE) + 1 162*f11c7f63SJim Harris ); 163*f11c7f63SJim Harris } 164*f11c7f63SJim Harris } 165*f11c7f63SJim Harris 166*f11c7f63SJim Harris // if the user requested that FUA is ignored; transfer it so we don't lose on update. 167*f11c7f63SJim Harris if (device->capabilities & SATI_DEVICE_CAP_IGNORE_FUA) 168*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_IGNORE_FUA; 169*f11c7f63SJim Harris 170*f11c7f63SJim Harris if (identify->general_config_bits & ATA_IDENTIFY_REMOVABLE_MEDIA_ENABLE) 171*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_REMOVABLE_MEDIA; 172*f11c7f63SJim Harris 173*f11c7f63SJim Harris if(identify->command_set_supported2 & ATA_IDENTIFY_WRITE_UNCORRECTABLE_SUPPORT ) 174*f11c7f63SJim Harris { 175*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_WRITE_UNCORRECTABLE_ENABLE; 176*f11c7f63SJim Harris } 177*f11c7f63SJim Harris 178*f11c7f63SJim Harris if(identify->physical_logical_sector_info & 179*f11c7f63SJim Harris ATA_IDENTIFY_LOGICAL_SECTOR_PER_PHYSICAL_SECTOR_ENABLE) 180*f11c7f63SJim Harris { 181*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_MULTIPLE_SECTORS_PER_PHYSCIAL_SECTOR; 182*f11c7f63SJim Harris } 183*f11c7f63SJim Harris 184*f11c7f63SJim Harris if(identify->command_set_supported_extention & 185*f11c7f63SJim Harris ATA_IDENTIFY_COMMAND_SET_SMART_SELF_TEST_SUPPORTED) 186*f11c7f63SJim Harris { 187*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT; 188*f11c7f63SJim Harris } 189*f11c7f63SJim Harris 190*f11c7f63SJim Harris if (identify->nominal_media_rotation_rate == 1) 191*f11c7f63SJim Harris { 192*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_SSD; 193*f11c7f63SJim Harris } 194*f11c7f63SJim Harris 195*f11c7f63SJim Harris // Save off the logical block size reported by the drive 196*f11c7f63SJim Harris // See if Word 106 is valid and reports a logical sector size 197*f11c7f63SJim Harris if ((identify->physical_logical_sector_info & 0x5000) == 0x5000) 198*f11c7f63SJim Harris { 199*f11c7f63SJim Harris device->logical_block_size = (identify->words_per_logical_sector[3] << 24) | 200*f11c7f63SJim Harris (identify->words_per_logical_sector[2] << 16) | 201*f11c7f63SJim Harris (identify->words_per_logical_sector[1] << 8) | 202*f11c7f63SJim Harris (identify->words_per_logical_sector[0]); 203*f11c7f63SJim Harris } 204*f11c7f63SJim Harris else 205*f11c7f63SJim Harris { 206*f11c7f63SJim Harris device->logical_block_size = 512; 207*f11c7f63SJim Harris } 208*f11c7f63SJim Harris 209*f11c7f63SJim Harris // Determine DSM TRIM capabilities 210*f11c7f63SJim Harris // Defend against SSDs which report TRIM support, but set 211*f11c7f63SJim Harris // max_lba_range_entry_blocks to zero, by disabling TRIM for 212*f11c7f63SJim Harris // those SSDs. 213*f11c7f63SJim Harris if ( 214*f11c7f63SJim Harris (identify->data_set_management & ATA_IDENTIFY_COMMAND_SET_DSM_TRIM_SUPPORTED) 215*f11c7f63SJim Harris && (identify->max_lba_range_entry_blocks > 0) 216*f11c7f63SJim Harris ) 217*f11c7f63SJim Harris { 218*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_DSM_TRIM_SUPPORT; 219*f11c7f63SJim Harris device->max_lba_range_entry_blocks = identify->max_lba_range_entry_blocks; 220*f11c7f63SJim Harris } 221*f11c7f63SJim Harris 222*f11c7f63SJim Harris if (identify->additional_supported 223*f11c7f63SJim Harris & ATA_IDENTIFY_COMMAND_ADDL_SUPPORTED_DETERMINISTIC_READ) 224*f11c7f63SJim Harris { 225*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_DETERMINISTIC_READ_AFTER_TRIM; 226*f11c7f63SJim Harris } 227*f11c7f63SJim Harris 228*f11c7f63SJim Harris if (identify->additional_supported 229*f11c7f63SJim Harris & ATA_IDENTIFY_COMMAND_ADDL_SUPPORTED_READ_ZERO) 230*f11c7f63SJim Harris { 231*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_READ_ZERO_AFTER_TRIM; 232*f11c7f63SJim Harris } 233*f11c7f63SJim Harris 234*f11c7f63SJim Harris if (identify->capabilities1 235*f11c7f63SJim Harris & ATA_IDENTIFY_CAPABILITIES1_STANDBY_ENABLE) 236*f11c7f63SJim Harris { 237*f11c7f63SJim Harris capabilities |= SATI_DEVICE_CAP_STANDBY_ENABLE; 238*f11c7f63SJim Harris } 239*f11c7f63SJim Harris 240*f11c7f63SJim Harris device->min_blocks_per_microcode_command = identify->min_num_blocks_per_microcode; 241*f11c7f63SJim Harris device->max_blocks_per_microcode_command = identify->max_num_blocks_per_microcode; 242*f11c7f63SJim Harris 243*f11c7f63SJim Harris device->capabilities = capabilities; 244*f11c7f63SJim Harris } 245*f11c7f63SJim Harris 246