# HG changeset patch # User pawelw # Date 1189227059 25200 # Node ID 25415d84340203f5c73c36e0d9bd8f28200b159e # Parent 29edb5b549e20ae8a4019b7dc7ff696f72c1ccb0 6495271 SATA module should inform HBA the drive's queue depth 6589306 need a tunable to specify # of multiple concurrent I/Os for NCQ 6594578 sata module emits unnecessary error messages while ATAPI inquiry command fails diff -r 29edb5b549e2 -r 25415d843402 usr/src/uts/common/io/sata/impl/sata.c --- a/usr/src/uts/common/io/sata/impl/sata.c Fri Sep 07 18:41:21 2007 -0700 +++ b/usr/src/uts/common/io/sata/impl/sata.c Fri Sep 07 21:50:59 2007 -0700 @@ -63,6 +63,20 @@ int sata_func_enable = SATA_ENABLE_PROCESS_EVENTS | SATA_ENABLE_QUEUING | SATA_ENABLE_NCQ; +/* + * Global variable setting default maximum queue depth (NCQ or TCQ) + * Note:minimum queue depth is 1 + */ +int sata_max_queue_depth = SATA_MAX_QUEUE_DEPTH; /* max NCQ/TCQ queue depth */ + +/* + * Currently used default NCQ/TCQ queue depth. It is set-up during the driver + * initialization, using value from sata_max_queue_depth + * It is adjusted to minimum supported by the controller and by the device, + * if queueing is enabled. + */ +static int sata_current_max_qdepth; + #ifdef SATA_DEBUG #define SATA_LOG_D(args) sata_log args @@ -711,6 +725,21 @@ */ mutex_enter(&sata_mutex); + if (sata_hba_list == NULL) { + /* + * The first instance of HBA is attached. + * Set current/active default maximum NCQ/TCQ queue depth for + * all SATA devices. It is done here and now, to eliminate the + * possibility of the dynamic, programatic modification of the + * queue depth via global (and public) sata_max_queue_depth + * variable (this would require special handling in HBA drivers) + */ + sata_current_max_qdepth = sata_max_queue_depth; + if (sata_current_max_qdepth > 32) + sata_current_max_qdepth = 32; + else if (sata_current_max_qdepth < 1) + sata_current_max_qdepth = 1; + } sata_hba_inst->satahba_next = NULL; sata_hba_inst->satahba_prev = sata_hba_list_tail; @@ -3010,7 +3039,9 @@ /* * Implementation of scsi tran_start. * Translate scsi cmd into sata operation and return status. - * Supported scsi commands: + * ATAPI CDBs are passed to ATAPI devices - the device determines what commands + * are supported. + * For SATA hard disks, supported scsi commands: * SCMD_INQUIRY * SCMD_TEST_UNIT_READY * SCMD_START_STOP @@ -3452,7 +3483,9 @@ break; case SCSI_CAP_TAGGED_QING: - if (sdinfo->satadrv_features_enabled & SATA_DEV_F_E_TAGGED_QING) + if ((sdinfo->satadrv_features_enabled & + SATA_DEV_F_E_TAGGED_QING) && + (sdinfo->satadrv_max_queue_depth > 1)) rval = 1; /* Tagged queuing available */ else rval = -1; /* Tagged queuing not available */ @@ -3551,7 +3584,8 @@ SATA_FEATURES(sata_hba_inst) & SATA_CTLF_QCMD) || (sata_func_enable & SATA_ENABLE_NCQ && sdinfo->satadrv_features_support & SATA_DEV_F_NCQ && - SATA_FEATURES(sata_hba_inst) & SATA_CTLF_NCQ))) { + SATA_FEATURES(sata_hba_inst) & SATA_CTLF_NCQ)) && + (sdinfo->satadrv_max_queue_depth > 1)) { rval = 1; if (value == 1) { sdinfo->satadrv_features_enabled |= @@ -5349,6 +5383,11 @@ * If SATA_ENABLE_NCQ flag is set in addition to SATA_ENABLE_QUEUING flag and * both the controller and device suport such functionality, the read * request will be translated to READ_FPDMA_QUEUED command. + * In both cases the maximum queue depth is derived as minimum of: + * HBA capability,device capability and sata_max_queue_depth variable setting. + * The value passed to HBA driver is decremented by 1, because only 5 bits are + * used to pass max queue depth value, and the maximum possible queue depth + * is 32. * * Returns TRAN_ACCEPT or code returned by sata_hba_start() and * appropriate values in scsi_pkt fields. @@ -5520,7 +5559,7 @@ scmd->satacmd_cmd_reg = SATAC_READ_DMA_QUEUED; } - } else /* Queuing not supported */ + } else /* NCQ nor legacy queuing not supported */ using_queuing = B_FALSE; /* @@ -5532,8 +5571,33 @@ scmd->satacmd_sec_count_lsb; scmd->satacmd_sec_count_lsb = 0; scmd->satacmd_flags.sata_queued = B_TRUE; - } - } + + /* Set-up maximum queue depth */ + scmd->satacmd_flags.sata_max_queue_depth = + sdinfo->satadrv_max_queue_depth - 1; + } else if (sdinfo->satadrv_features_enabled & + SATA_DEV_F_E_UNTAGGED_QING) { + /* + * Although NCQ/TCQ is not enabled, untagged queuing + * may be still used. + * Set-up the maximum untagged queue depth. + * Use controller's queue depth from sata_hba_tran. + * SATA HBA drivers may ignore this value and rely on + * the internal limits.For drivers that do not + * ignore untaged queue depth, limit the value to + * SATA_MAX_QUEUE_DEPTH (32), as this is the + * largest value that can be passed via + * satacmd_flags.sata_max_queue_depth. + */ + scmd->satacmd_flags.sata_max_queue_depth = + SATA_QDEPTH(shi) <= SATA_MAX_QUEUE_DEPTH ? + SATA_QDEPTH(shi) - 1: SATA_MAX_QUEUE_DEPTH - 1; + + } else { + scmd->satacmd_flags.sata_max_queue_depth = 0; + } + } else + scmd->satacmd_flags.sata_max_queue_depth = 0; SATADBG3(SATA_DBG_HBA_IF, spx->txlt_sata_hba_inst, "sata_txlt_read cmd 0x%2x, lba %llx, sec count %x\n", @@ -5580,6 +5644,20 @@ * Following scsi cdb fields are ignored: * rwprotect, dpo, fua, fua_nv, group_number. * + * If SATA_ENABLE_QUEUING flag is set (in the global SATA HBA framework + * enable variable sata_func_enable), the capability of the controller and + * capability of a device are checked and if both support queueing, write + * request will be translated to WRITE_DMA_QUEUEING or WRITE_DMA_QUEUEING_EXT + * command rather than plain WRITE_XXX command. + * If SATA_ENABLE_NCQ flag is set in addition to SATA_ENABLE_QUEUING flag and + * both the controller and device suport such functionality, the write + * request will be translated to WRITE_FPDMA_QUEUED command. + * In both cases the maximum queue depth is derived as minimum of: + * HBA capability,device capability and sata_max_queue_depth variable setting. + * The value passed to HBA driver is decremented by 1, because only 5 bits are + * used to pass max queue depth value, and the maximum possible queue depth + * is 32. + * * Returns TRAN_ACCEPT or code returned by sata_hba_start() and * appropriate values in scsi_pkt fields. */ @@ -5750,7 +5828,7 @@ scmd->satacmd_cmd_reg = SATAC_WRITE_DMA_QUEUED; } - } else /* Queuing not supported */ + } else /* NCQ nor legacy queuing not supported */ using_queuing = B_FALSE; if (using_queuing) { @@ -5758,8 +5836,32 @@ scmd->satacmd_sec_count_lsb; scmd->satacmd_sec_count_lsb = 0; scmd->satacmd_flags.sata_queued = B_TRUE; - } - } + /* Set-up maximum queue depth */ + scmd->satacmd_flags.sata_max_queue_depth = + sdinfo->satadrv_max_queue_depth - 1; + } else if (sdinfo->satadrv_features_enabled & + SATA_DEV_F_E_UNTAGGED_QING) { + /* + * Although NCQ/TCQ is not enabled, untagged queuing + * may be still used. + * Set-up the maximum untagged queue depth. + * Use controller's queue depth from sata_hba_tran. + * SATA HBA drivers may ignore this value and rely on + * the internal limits. For drivera that do not + * ignore untaged queue depth, limit the value to + * SATA_MAX_QUEUE_DEPTH (32), as this is the + * largest value that can be passed via + * satacmd_flags.sata_max_queue_depth. + */ + scmd->satacmd_flags.sata_max_queue_depth = + SATA_QDEPTH(shi) <= SATA_MAX_QUEUE_DEPTH ? + SATA_QDEPTH(shi) - 1: SATA_MAX_QUEUE_DEPTH - 1; + + } else { + scmd->satacmd_flags.sata_max_queue_depth = 0; + } + } else + scmd->satacmd_flags.sata_max_queue_depth = 0; SATADBG3(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst, "sata_txlt_write cmd 0x%2x, lba %llx, sec count %x\n", @@ -8387,7 +8489,8 @@ * Fetch inquiry data from ATAPI device * Returns SATA_SUCCESS if operation was successfull, SATA_FAILURE otherwise. * - * inqb pointer does not points to a DMA-able buffer. It is a local buffer + * Note: + * inqb pointer does not point to a DMA-able buffer. It is a local buffer * where the caller expects to see the inquiry data. * */ @@ -8403,6 +8506,9 @@ sata_cmd_t *scmd; int rval; uint8_t *rqsp; +#ifdef SATA_DEBUG + char msg_buf[MAXPATHLEN]; +#endif ASSERT(sata_hba != NULL); @@ -8510,44 +8616,51 @@ * ARQ data hopefull show something other than NO SENSE */ rqsp = scmd->satacmd_rqsense; - sata_log(spx->txlt_sata_hba_inst, CE_WARN, - "ATAPI packet completion reason: %02x\n" - "RQSENSE: %02x %02x %02x %02x %02x %02x " - " %02x %02x %02x %02x %02x %02x " - " %02x %02x %02x %02x %02x %02x\n", - spkt->satapkt_reason, - rqsp[0], rqsp[1], rqsp[2], rqsp[3], - rqsp[4], rqsp[5], rqsp[6], rqsp[7], - rqsp[8], rqsp[9], rqsp[10], rqsp[11], - rqsp[12], rqsp[13], rqsp[14], rqsp[15], - rqsp[16], rqsp[17]); +#ifdef SATA_DEBUG + if (sata_debug_flags & SATA_DBG_ATAPI) { + msg_buf[0] = '\0'; + (void) snprintf(msg_buf, MAXPATHLEN, + "ATAPI packet completion reason: %02x\n" + "RQSENSE: %02x %02x %02x %02x %02x %02x\n" + " %02x %02x %02x %02x %02x %02x\n" + " %02x %02x %02x %02x %02x %02x", + spkt->satapkt_reason, + rqsp[0], rqsp[1], rqsp[2], rqsp[3], + rqsp[4], rqsp[5], rqsp[6], rqsp[7], + rqsp[8], rqsp[9], rqsp[10], rqsp[11], + rqsp[12], rqsp[13], rqsp[14], rqsp[15], + rqsp[16], rqsp[17]); + sata_log(spx->txlt_sata_hba_inst, CE_WARN, + "%s", msg_buf); + } +#endif } else { switch (spkt->satapkt_reason) { case SATA_PKT_PORT_ERROR: - sata_log(sata_hba, CE_WARN, + SATADBG1(SATA_DBG_ATAPI, sata_hba, "sata_get_atapi_inquiry_data: " - "packet reason: port error\n"); + "packet reason: port error", NULL); break; case SATA_PKT_TIMEOUT: - sata_log(sata_hba, CE_WARN, + SATADBG1(SATA_DBG_ATAPI, sata_hba, "sata_get_atapi_inquiry_data: " - "packet reason: timeout\n"); + "packet reason: timeout", NULL); break; case SATA_PKT_ABORTED: - sata_log(sata_hba, CE_WARN, + SATADBG1(SATA_DBG_ATAPI, sata_hba, "sata_get_atapi_inquiry_data: " - "packet reason: aborted\n"); + "packet reason: aborted", NULL); break; case SATA_PKT_RESET: - sata_log(sata_hba, CE_WARN, + SATADBG1(SATA_DBG_ATAPI, sata_hba, "sata_get_atapi_inquiry_data: " - "packet reason: reset\n"); + "packet reason: reset\n", NULL); break; default: - sata_log(sata_hba, CE_WARN, + SATADBG1(SATA_DBG_ATAPI, sata_hba, "sata_get_atapi_inquiry_data: " "invalid packet reason: %02x\n", spkt->satapkt_reason); @@ -8678,7 +8791,7 @@ if (spkt->satapkt_reason == SATA_PKT_COMPLETED) { sata_log(sata_hba_inst, CE_WARN, "sata_test_atapi_packet_command: " - "Packet completed successfully\n"); + "Packet completed successfully"); /* * Normal completion - show inquiry data */ @@ -10306,8 +10419,21 @@ cmn_err(CE_CONT, "?\tSATA Gen1 signaling speed (1.5Gbps)\n"); if (sdinfo->satadrv_features_support & (SATA_DEV_F_TCQ | SATA_DEV_F_NCQ)) { - cmn_err(CE_CONT, "?\tQueue depth %d\n", + msg_buf[0] = '\0'; + (void) snprintf(msg_buf, MAXPATHLEN, + "Supported queue depth %d", sdinfo->satadrv_queue_depth); + if (!(sata_func_enable & + (SATA_ENABLE_QUEUING | SATA_ENABLE_NCQ))) + (void) strlcat(msg_buf, + " - queueing disabled globally", MAXPATHLEN); + else if (sdinfo->satadrv_queue_depth > + sdinfo->satadrv_max_queue_depth) { + (void) snprintf(&msg_buf[strlen(msg_buf)], + MAXPATHLEN - strlen(msg_buf), ", limited to %d", + (int)sdinfo->satadrv_max_queue_depth); + } + cmn_err(CE_CONT, "?\t%s\n", msg_buf); } if (sdinfo->satadrv_type == SATA_DTYPE_ATADISK) { @@ -11152,8 +11278,21 @@ sdinfo->satadrv_queue_depth = sdinfo->satadrv_id.ai_qdepth; if ((sdinfo->satadrv_features_support & SATA_DEV_F_NCQ) || - (sdinfo->satadrv_features_support & SATA_DEV_F_TCQ)) + (sdinfo->satadrv_features_support & SATA_DEV_F_TCQ)) { ++sdinfo->satadrv_queue_depth; + /* Adjust according to controller capabilities */ + sdinfo->satadrv_max_queue_depth = MIN( + sdinfo->satadrv_queue_depth, + SATA_QDEPTH(sata_hba_inst)); + /* Adjust according to global queue depth limit */ + sdinfo->satadrv_max_queue_depth = MIN( + sdinfo->satadrv_max_queue_depth, + sata_current_max_qdepth); + if (sdinfo->satadrv_max_queue_depth == 0) + sdinfo->satadrv_max_queue_depth = 1; + } else + sdinfo->satadrv_max_queue_depth = 1; + rval = SATA_SUCCESS; } else { /* @@ -11788,21 +11927,21 @@ bcopy(&sdinfo->satadrv_id.ai_drvser, &hwid[modlen], sizeof (sdinfo->satadrv_id.ai_drvser)); swab(&hwid[modlen], &hwid[modlen], - sizeof (sdinfo->satadrv_id.ai_drvser)); + sizeof (sdinfo->satadrv_id.ai_drvser)); serlen = sata_check_modser(&hwid[modlen], - sizeof (sdinfo->satadrv_id.ai_drvser)); + sizeof (sdinfo->satadrv_id.ai_drvser)); if (serlen == 0) goto err; hwid[modlen + serlen] = 0; /* terminate the hwid string */ /* initialize/register devid */ if ((rval = ddi_devid_init(dip, DEVID_ATA_SERIAL, - (ushort_t)(modlen + serlen), hwid, &devid)) == DDI_SUCCESS) + (ushort_t)(modlen + serlen), hwid, &devid)) == DDI_SUCCESS) rval = ddi_devid_register(dip, devid); if (rval != DDI_SUCCESS) cmn_err(CE_WARN, "sata: failed to create devid for the disk" - " on port %d", sdinfo->satadrv_addr.cport); + " on port %d", sdinfo->satadrv_addr.cport); err: kmem_free(hwid, LEGACY_HWID_LEN); } diff -r 29edb5b549e2 -r 25415d843402 usr/src/uts/common/sys/sata/sata_hba.h --- a/usr/src/uts/common/sys/sata/sata_hba.h Fri Sep 07 18:41:21 2007 -0700 +++ b/usr/src/uts/common/sys/sata/sata_hba.h Fri Sep 07 21:50:59 2007 -0700 @@ -260,6 +260,8 @@ * Upon completion of a command, SATA HBA driver has to update * satacmd_status_reg and satacmd_error_reg to reflect the contents of * the corresponding device status and error registers. + * If the command completed successfully, satacmd_flags.sata_copy_xxx flags + * specify what register fields should be updated in sata_cmd structure. * If the command completed with error, SATA HBA driver has to update * satacmd_sec_count_msb, satacmd_sec_count_lsb, satacmd_lba_low_msb, * satacmd_lba_low_lsb, satacmd_lba_mid_msb, satacmd_lba_mid_lsb, @@ -273,6 +275,9 @@ * points to pre-set request sense cdb that may be used for issuing request * sense data from the device. * + * The sata_max_queue_depth field specifies the maximum allowable queue depth + * minus one, i.e. for maximum queue depth of 32, sata_max_queue_depth would + * be set to value 0x1f. * If FPDMA-type command was sent and command completed with error, the HBA * driver may use pre-set command READ LOG EXTENDED command pointed to * by satacmd_rle_sata_cmd field to retrieve error data from a device. @@ -292,8 +297,9 @@ #define SATA_ATAPI_MAX_CDB_LEN 16 /* Covers both 12 and 16 byte cdbs */ #define SATA_ATAPI_RQSENSE_LEN 24 /* Allocated Request Sense data */ #define SATA_ATAPI_MIN_RQSENSE_LEN 18 /* Min Fixed size Request Sense data */ +#define SATA_ATAPI_RQSENSE_CDB_LEN 6 /* Request Sense CDB length */ -#define SATA_ATAPI_RQSENSE_CDB_LEN 6 /* Request Sense CDB length */ +#define SATA_MAX_QUEUE_DEPTH 32 /* Default max queue depth */ struct sata_cmd { int satacmd_rev; /* version */