From owner-svn-src-all@freebsd.org Fri Sep 13 14:43:06 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D25DBF34F7; Fri, 13 Sep 2019 14:43:06 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46VJK65z4jz3Fjb; Fri, 13 Sep 2019 14:43:06 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AFF068B30; Fri, 13 Sep 2019 14:43:06 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x8DEh6qD026781; Fri, 13 Sep 2019 14:43:06 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x8DEh6Vv026778; Fri, 13 Sep 2019 14:43:06 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201909131443.x8DEh6Vv026778@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 13 Sep 2019 14:43:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r352286 - in stable/11: sbin/camcontrol sys/cam/scsi X-SVN-Group: stable-11 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: in stable/11: sbin/camcontrol sys/cam/scsi X-SVN-Commit-Revision: 352286 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Sep 2019 14:43:06 -0000 Author: mav Date: Fri Sep 13 14:43:05 2019 New Revision: 352286 URL: https://svnweb.freebsd.org/changeset/base/352286 Log: Supply SAT layer with valid transfer sizes. This is a rework of r344701, that noticed that number of bytes passes to 8 bit sector count field gets truncated. First decision was to not pass anything, since ATA specs define the field as N/A. But it appeared to be a problem for some SAT devices, that require information about data transfer to operate properly. Some additional investigation shown that it is quite a common practice to set unused fields of ATA commands (fortunately ATA specs formally allow it) to supply the information to SAT layer. I have found SAS-SATA interposer that does not allow pass-through without it. As side effect, reduce code duplication by removing ata_do_28bit_cmd() function, replacing it with more universal ata_do_cmd(). Modified: stable/11/sbin/camcontrol/camcontrol.c stable/11/sbin/camcontrol/fwdownload.c stable/11/sys/cam/scsi/scsi_all.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sbin/camcontrol/camcontrol.c ============================================================================== --- stable/11/sbin/camcontrol/camcontrol.c Fri Sep 13 14:42:37 2019 (r352285) +++ stable/11/sbin/camcontrol/camcontrol.c Fri Sep 13 14:43:05 2019 (r352286) @@ -1730,13 +1730,11 @@ ata_cam_send(struct cam_device *device, union ccb *ccb static int ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries, u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, - u_int8_t tag_action, u_int8_t command, u_int8_t features, - u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, + u_int8_t tag_action, u_int8_t command, u_int16_t features, + u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, int timeout, int quiet) { if (data_ptr != NULL) { - ata_flags |= AP_FLAG_BYT_BLOK_BYTES | - AP_FLAG_TLEN_SECT_CNT; if (flags & CAM_DIR_OUT) ata_flags |= AP_FLAG_TDIR_TO_DEV; else @@ -1787,44 +1785,10 @@ ata_try_pass_16(struct cam_device *device) } static int -ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries, - u_int32_t flags, u_int8_t protocol, u_int8_t tag_action, - u_int8_t command, u_int8_t features, u_int32_t lba, - u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, - int timeout, int quiet) -{ - - - switch (ata_try_pass_16(device)) { - case -1: - return (1); - case 1: - /* Try using SCSI Passthrough */ - return ata_do_pass_16(device, ccb, retries, flags, protocol, - 0, tag_action, command, features, lba, - sector_count, data_ptr, dxfer_len, - timeout, quiet); - } - - CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio); - cam_fill_ataio(&ccb->ataio, - retries, - NULL, - flags, - tag_action, - data_ptr, - dxfer_len, - timeout); - - ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); - return ata_cam_send(device, ccb, quiet); -} - -static int ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries, u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, - u_int8_t tag_action, u_int8_t command, u_int8_t features, - u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, + u_int8_t tag_action, u_int8_t command, u_int16_t features, + u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, int timeout, int force48bit) { int retval; @@ -2071,14 +2035,15 @@ atahpa_password(struct cam_device *device, int retry_c retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/protocol, - /*ata_flags*/AP_FLAG_CHK_COND, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT | AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_SET_PWD, /*lba*/0, - /*sector_count*/0, + /*sector_count*/sizeof(*pwd) / 512, /*data_ptr*/(u_int8_t*)pwd, - /*dxfer_len*/sizeof(struct ata_set_max_pwd), + /*dxfer_len*/sizeof(*pwd), timeout ? timeout : 1000, is48bit); @@ -2138,14 +2103,15 @@ atahpa_unlock(struct cam_device *device, int retry_cou retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/protocol, - /*ata_flags*/AP_FLAG_CHK_COND, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT | AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_UNLOCK, /*lba*/0, - /*sector_count*/0, + /*sector_count*/sizeof(*pwd) / 512, /*data_ptr*/(u_int8_t*)pwd, - /*dxfer_len*/sizeof(struct ata_set_max_pwd), + /*dxfer_len*/sizeof(*pwd), timeout ? timeout : 1000, is48bit); @@ -2315,45 +2281,32 @@ ata_do_identify(struct cam_device *device, int retry_c return (1); } - error = ata_do_28bit_cmd(device, - ccb, - /*retries*/retry_count, - /*flags*/CAM_DIR_IN, - /*protocol*/AP_PROTO_PIO_IN, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/command, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)ptr, - /*dxfer_len*/sizeof(struct ata_params), - /*timeout*/timeout ? timeout : 30 * 1000, - /*quiet*/1); +retry: + error = ata_do_cmd(device, + ccb, + /*retries*/retry_count, + /*flags*/CAM_DIR_IN, + /*protocol*/AP_PROTO_PIO_IN, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/command, + /*features*/0, + /*lba*/0, + /*sector_count*/sizeof(struct ata_params) / 512, + /*data_ptr*/(u_int8_t *)ptr, + /*dxfer_len*/sizeof(struct ata_params), + /*timeout*/timeout ? timeout : 30 * 1000, + /*force48bit*/0); if (error != 0) { - if (retry_command == 0) { - free(ptr); - return (1); + if (retry_command != 0) { + command = retry_command; + retry_command = 0; + goto retry; } - error = ata_do_28bit_cmd(device, - ccb, - /*retries*/retry_count, - /*flags*/CAM_DIR_IN, - /*protocol*/AP_PROTO_PIO_IN, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/retry_command, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)ptr, - /*dxfer_len*/sizeof(struct ata_params), - /*timeout*/timeout ? timeout : 30 * 1000, - /*quiet*/0); - - if (error != 0) { - free(ptr); - return (1); - } + free(ptr); + return (1); } error = 1; @@ -2527,20 +2480,21 @@ atasecurity_freeze(struct cam_device *device, union cc if (quiet == 0) atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL); - return ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_NONE, - /*protocol*/AP_PROTO_NON_DATA, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_FREEZE_LOCK, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/NULL, - /*dxfer_len*/0, - /*timeout*/timeout, - /*quiet*/0); + return ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_NONE, + /*protocol*/AP_PROTO_NON_DATA, + /*ata_flags*/0, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_FREEZE_LOCK, + /*features*/0, + /*lba*/0, + /*sector_count*/0, + /*data_ptr*/NULL, + /*dxfer_len*/0, + /*timeout*/timeout, + /*force48bit*/0); } static int @@ -2552,20 +2506,22 @@ atasecurity_unlock(struct cam_device *device, union cc if (quiet == 0) atasecurity_notify(ATA_SECURITY_UNLOCK, pwd); - return ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_OUT, - /*protocol*/AP_PROTO_PIO_OUT, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_UNLOCK, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)pwd, - /*dxfer_len*/sizeof(*pwd), - /*timeout*/timeout, - /*quiet*/0); + return ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_OUT, + /*protocol*/AP_PROTO_PIO_OUT, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_UNLOCK, + /*features*/0, + /*lba*/0, + /*sector_count*/sizeof(*pwd) / 512, + /*data_ptr*/(u_int8_t *)pwd, + /*dxfer_len*/sizeof(*pwd), + /*timeout*/timeout, + /*force48bit*/0); } static int @@ -2576,20 +2532,22 @@ atasecurity_disable(struct cam_device *device, union c if (quiet == 0) atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd); - return ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_OUT, - /*protocol*/AP_PROTO_PIO_OUT, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_DISABLE_PASSWORD, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)pwd, - /*dxfer_len*/sizeof(*pwd), - /*timeout*/timeout, - /*quiet*/0); + return ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_OUT, + /*protocol*/AP_PROTO_PIO_OUT, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_DISABLE_PASSWORD, + /*features*/0, + /*lba*/0, + /*sector_count*/sizeof(*pwd) / 512, + /*data_ptr*/(u_int8_t *)pwd, + /*dxfer_len*/sizeof(*pwd), + /*timeout*/timeout, + /*force48bit*/0); } @@ -2635,20 +2593,21 @@ atasecurity_erase(struct cam_device *device, union ccb if (quiet == 0) atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL); - error = ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_NONE, - /*protocol*/AP_PROTO_NON_DATA, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_ERASE_PREPARE, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/NULL, - /*dxfer_len*/0, - /*timeout*/timeout, - /*quiet*/0); + error = ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_NONE, + /*protocol*/AP_PROTO_NON_DATA, + /*ata_flags*/0, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_ERASE_PREPARE, + /*features*/0, + /*lba*/0, + /*sector_count*/0, + /*data_ptr*/NULL, + /*dxfer_len*/0, + /*timeout*/timeout, + /*force48bit*/0); if (error != 0) return error; @@ -2656,20 +2615,22 @@ atasecurity_erase(struct cam_device *device, union ccb if (quiet == 0) atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd); - error = ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_OUT, - /*protocol*/AP_PROTO_PIO_OUT, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_ERASE_UNIT, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)pwd, - /*dxfer_len*/sizeof(*pwd), - /*timeout*/erase_timeout, - /*quiet*/0); + error = ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_OUT, + /*protocol*/AP_PROTO_PIO_OUT, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_ERASE_UNIT, + /*features*/0, + /*lba*/0, + /*sector_count*/sizeof(*pwd) / 512, + /*data_ptr*/(u_int8_t *)pwd, + /*dxfer_len*/sizeof(*pwd), + /*timeout*/erase_timeout, + /*force48bit*/0); if (error == 0 && quiet == 0) printf("\nErase Complete\n"); @@ -2686,20 +2647,22 @@ atasecurity_set_password(struct cam_device *device, un if (quiet == 0) atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd); - return ata_do_28bit_cmd(device, - ccb, - retry_count, - /*flags*/CAM_DIR_OUT, - /*protocol*/AP_PROTO_PIO_OUT, - /*tag_action*/MSG_SIMPLE_Q_TAG, - /*command*/ATA_SECURITY_SET_PASSWORD, - /*features*/0, - /*lba*/0, - /*sector_count*/0, - /*data_ptr*/(u_int8_t *)pwd, - /*dxfer_len*/sizeof(*pwd), - /*timeout*/timeout, - /*quiet*/0); + return ata_do_cmd(device, + ccb, + retry_count, + /*flags*/CAM_DIR_OUT, + /*protocol*/AP_PROTO_PIO_OUT, + /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | + AP_FLAG_TLEN_SECT_CNT, + /*tag_action*/MSG_SIMPLE_Q_TAG, + /*command*/ATA_SECURITY_SET_PASSWORD, + /*features*/0, + /*lba*/0, + /*sector_count*/sizeof(*pwd) / 512, + /*data_ptr*/(u_int8_t *)pwd, + /*dxfer_len*/sizeof(*pwd), + /*timeout*/timeout, + /*force48bit*/0); } static void @@ -8995,7 +8958,7 @@ atapm(struct cam_device *device, int argc, char **argv /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout ? timeout : 30 * 1000, - /*quiet*/1); + /*force48bit*/0); cam_freeccb(ccb); @@ -9048,11 +9011,12 @@ ataaxm(struct cam_device *device, int argc, char **arg } } - retval = ata_do_28bit_cmd(device, + retval = ata_do_cmd(device, ccb, /*retries*/retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/AP_PROTO_NON_DATA, + /*ata_flags*/0, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SETFEATURES, /*features*/cmd, @@ -9061,7 +9025,7 @@ ataaxm(struct cam_device *device, int argc, char **arg /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout ? timeout : 30 * 1000, - /*quiet*/1); + /*force48bit*/0); cam_freeccb(ccb); return (retval); Modified: stable/11/sbin/camcontrol/fwdownload.c ============================================================================== --- stable/11/sbin/camcontrol/fwdownload.c Fri Sep 13 14:42:37 2019 (r352285) +++ stable/11/sbin/camcontrol/fwdownload.c Fri Sep 13 14:43:05 2019 (r352286) @@ -701,11 +701,11 @@ fw_check_device_ready(struct cam_device *dev, camcontr /*flags*/ CAM_DIR_IN, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*protocol*/ AP_PROTO_PIO_IN, - /*ata_flags*/ AP_FLAG_BYT_BLOK_BYTES | + /*ata_flags*/ AP_FLAG_BYT_BLOK_BLOCKS | AP_FLAG_TLEN_SECT_CNT | AP_FLAG_TDIR_FROM_DEV, /*features*/ 0, - /*sector_count*/ (uint8_t) dxfer_len, + /*sector_count*/ dxfer_len / 512, /*lba*/ 0, /*command*/ ATA_ATA_IDENTIFY, /*auxiliary*/ 0, Modified: stable/11/sys/cam/scsi/scsi_all.c ============================================================================== --- stable/11/sys/cam/scsi/scsi_all.c Fri Sep 13 14:42:37 2019 (r352285) +++ stable/11/sys/cam/scsi/scsi_all.c Fri Sep 13 14:43:05 2019 (r352286) @@ -8266,10 +8266,10 @@ scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t r tag_action, /*protocol*/AP_PROTO_PIO_IN, /*ata_flags*/AP_FLAG_TDIR_FROM_DEV | - AP_FLAG_BYT_BLOK_BYTES | + AP_FLAG_BYT_BLOK_BLOCKS | AP_FLAG_TLEN_SECT_CNT, /*features*/0, - /*sector_count*/dxfer_len, + /*sector_count*/dxfer_len / 512, /*lba*/0, /*command*/ATA_ATA_IDENTIFY, /*device*/ 0,