From owner-svn-src-all@FreeBSD.ORG Sat Jul 12 02:24:53 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5AEA4927; Sat, 12 Jul 2014 02:24:53 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3B19D2159; Sat, 12 Jul 2014 02:24:53 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6C2Orop028228; Sat, 12 Jul 2014 02:24:53 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6C2OqLM028219; Sat, 12 Jul 2014 02:24:52 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201407120224.s6C2OqLM028219@svn.freebsd.org> From: Alexander Motin Date: Sat, 12 Jul 2014 02:24:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r268550 - stable/10/sys/cam/ctl X-SVN-Group: stable-10 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.18 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: Sat, 12 Jul 2014 02:24:53 -0000 Author: mav Date: Sat Jul 12 02:24:52 2014 New Revision: 268550 URL: http://svnweb.freebsd.org/changeset/base/268550 Log: MFC r267905: Add READ BUFFER and improve WRITE BUFFER SCSI commands support. This gives some use to 512KB per-LUN buffers, allocated for Copan-specific processor code and not used. It allows, for example, to test transport performance and/or correctness without accessing the media, as supported by Linux version of sg3_utils. Modified: stable/10/sys/cam/ctl/ctl.c stable/10/sys/cam/ctl/ctl_cmd_table.c stable/10/sys/cam/ctl/ctl_frontend_iscsi.c stable/10/sys/cam/ctl/ctl_private.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl.c ============================================================================== --- stable/10/sys/cam/ctl/ctl.c Sat Jul 12 02:17:10 2014 (r268549) +++ stable/10/sys/cam/ctl/ctl.c Sat Jul 12 02:24:52 2014 (r268550) @@ -4954,7 +4954,8 @@ ctl_config_move_done(union ctl_io *io) /*sks_valid*/ 1, /*retry_count*/ io->io_hdr.port_status); - free(io->scsiio.kern_data_ptr, M_CTL); + if (io->io_hdr.flags & CTL_FLAG_ALLOCATED) + free(io->scsiio.kern_data_ptr, M_CTL); ctl_done(io); goto bailout; } @@ -4967,7 +4968,8 @@ ctl_config_move_done(union ctl_io *io) * S/G list. If we start using S/G lists for config data, * we'll need to know how to clean them up here as well. */ - free(io->scsiio.kern_data_ptr, M_CTL); + if (io->io_hdr.flags & CTL_FLAG_ALLOCATED) + free(io->scsiio.kern_data_ptr, M_CTL); /* Hopefully the user has already set the status... */ ctl_done(io); } else { @@ -5712,26 +5714,40 @@ bailout: } int -ctl_write_buffer(struct ctl_scsiio *ctsio) +ctl_read_buffer(struct ctl_scsiio *ctsio) { - struct scsi_write_buffer *cdb; - struct copan_page_header *header; + struct scsi_read_buffer *cdb; struct ctl_lun *lun; - struct ctl_softc *ctl_softc; int buffer_offset, len; - int retval; + static uint8_t descr[4]; + static uint8_t echo_descr[4] = { 0 }; - header = NULL; + CTL_DEBUG_PRINT(("ctl_read_buffer\n")); - retval = CTL_RETVAL_COMPLETE; + lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_read_buffer *)ctsio->cdb; - CTL_DEBUG_PRINT(("ctl_write_buffer\n")); + if (lun->flags & CTL_LUN_PR_RESERVED) { + uint32_t residx; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; - cdb = (struct scsi_write_buffer *)ctsio->cdb; + /* + * XXX KDM need a lock here. + */ + residx = ctl_get_resindex(&ctsio->io_hdr.nexus); + if ((lun->res_type == SPR_TYPE_EX_AC + && residx != lun->pr_res_idx) + || ((lun->res_type == SPR_TYPE_EX_AC_RO + || lun->res_type == SPR_TYPE_EX_AC_AR) + && !lun->per_res[residx].registered)) { + ctl_set_reservation_conflict(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + } - if ((cdb->byte2 & RWB_MODE) != RWB_MODE_DATA) { + if ((cdb->byte2 & RWB_MODE) != RWB_MODE_DATA && + (cdb->byte2 & RWB_MODE) != RWB_MODE_ECHO_DESCR && + (cdb->byte2 & RWB_MODE) != RWB_MODE_DESCR) { ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, @@ -5755,7 +5771,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsi len = scsi_3btoul(cdb->length); buffer_offset = scsi_3btoul(cdb->offset); - if (len > sizeof(lun->write_buffer)) { + if (buffer_offset + len > sizeof(lun->write_buffer)) { ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, @@ -5766,11 +5782,68 @@ ctl_write_buffer(struct ctl_scsiio *ctsi return (CTL_RETVAL_COMPLETE); } - if (buffer_offset != 0) { + if ((cdb->byte2 & RWB_MODE) == RWB_MODE_DESCR) { + descr[0] = 0; + scsi_ulto3b(sizeof(lun->write_buffer), &descr[1]); + ctsio->kern_data_ptr = descr; + len = min(len, sizeof(descr)); + } else if ((cdb->byte2 & RWB_MODE) == RWB_MODE_ECHO_DESCR) { + ctsio->kern_data_ptr = echo_descr; + len = min(len, sizeof(echo_descr)); + } else + ctsio->kern_data_ptr = lun->write_buffer + buffer_offset; + ctsio->kern_data_len = len; + ctsio->kern_total_len = len; + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + ctsio->kern_sg_entries = 0; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + + return (CTL_RETVAL_COMPLETE); +} + +int +ctl_write_buffer(struct ctl_scsiio *ctsio) +{ + struct scsi_write_buffer *cdb; + struct ctl_lun *lun; + int buffer_offset, len; + + CTL_DEBUG_PRINT(("ctl_write_buffer\n")); + + lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_write_buffer *)ctsio->cdb; + + if ((cdb->byte2 & RWB_MODE) != RWB_MODE_DATA) { + ctl_set_invalid_field(ctsio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 1, + /*bit_valid*/ 1, + /*bit*/ 4); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + if (cdb->buffer_id != 0) { + ctl_set_invalid_field(ctsio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 2, + /*bit_valid*/ 0, + /*bit*/ 0); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + + len = scsi_3btoul(cdb->length); + buffer_offset = scsi_3btoul(cdb->offset); + + if (buffer_offset + len > sizeof(lun->write_buffer)) { ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, - /*field*/ 3, + /*field*/ 6, /*bit_valid*/ 0, /*bit*/ 0); ctl_done((union ctl_io *)ctsio); @@ -5782,7 +5855,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsi * malloc it and tell the caller the data buffer is here. */ if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) { - ctsio->kern_data_ptr = lun->write_buffer; + ctsio->kern_data_ptr = lun->write_buffer + buffer_offset; ctsio->kern_data_len = len; ctsio->kern_total_len = len; ctsio->kern_data_resid = 0; @@ -6993,6 +7066,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -7052,6 +7126,7 @@ ctl_read_capacity(struct ctl_scsiio *cts ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -7114,6 +7189,7 @@ ctl_read_capacity_16(struct ctl_scsiio * ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -7287,6 +7363,7 @@ ctl_maintenance_in(struct ctl_scsiio *ct } } + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; CTL_DEBUG_PRINT(("buf = %x %x %x %x %x %x %x %x\n", @@ -7512,6 +7589,7 @@ retry: } mtx_unlock(&softc->ctl_lock); + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; CTL_DEBUG_PRINT(("buf = %x %x %x %x %x %x %x %x\n", @@ -9225,6 +9303,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio */ ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9351,7 +9430,7 @@ ctl_request_sense(struct ctl_scsiio *cts * parameter data. */ ctsio->sense_len = 0; - + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9380,6 +9459,7 @@ no_sense: * autosense in this case. We're reporting sense as parameter data. */ ctsio->sense_len = 0; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9467,6 +9547,7 @@ ctl_inquiry_evpd_supported(struct ctl_sc ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9535,6 +9616,7 @@ ctl_inquiry_evpd_serial(struct ctl_scsii #endif ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9728,6 +9810,7 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9784,6 +9867,7 @@ ctl_inquiry_evpd_block_limits(struct ctl scsi_u64to8b(UINT64_MAX, bl_ptr->max_write_same_length); ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -9833,6 +9917,7 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio * lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 | SVPD_LBP_WS10; ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); @@ -10117,6 +10202,7 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio ctsio->scsi_status = SCSI_STATUS_OK; if (ctsio->kern_data_len > 0) { + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); } else { Modified: stable/10/sys/cam/ctl/ctl_cmd_table.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_cmd_table.c Sat Jul 12 02:17:10 2014 (r268549) +++ stable/10/sys/cam/ctl/ctl_cmd_table.c Sat Jul 12 02:24:52 2014 (r268550) @@ -314,12 +314,15 @@ struct ctl_cmd_entry ctl_cmd_table[] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 3B WRITE BUFFER */ -{ctl_write_buffer, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_PROC | - CTL_FLAG_DATA_OUT, +{ctl_write_buffer, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_FLAG_DATA_OUT, CTL_LUN_PAT_NONE}, /* 3C READ BUFFER */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_read_buffer, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH | + CTL_FLAG_DATA_IN | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV, + CTL_LUN_PAT_NONE}, /* 3D UPDATE BLOCK */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, Modified: stable/10/sys/cam/ctl/ctl_frontend_iscsi.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_frontend_iscsi.c Sat Jul 12 02:17:10 2014 (r268549) +++ stable/10/sys/cam/ctl/ctl_frontend_iscsi.c Sat Jul 12 02:24:52 2014 (r268550) @@ -2236,6 +2236,7 @@ cfiscsi_devid(struct ctl_scsiio *ctsio, ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); Modified: stable/10/sys/cam/ctl/ctl_private.h ============================================================================== --- stable/10/sys/cam/ctl/ctl_private.h Sat Jul 12 02:17:10 2014 (r268549) +++ stable/10/sys/cam/ctl/ctl_private.h Sat Jul 12 02:24:52 2014 (r268550) @@ -469,6 +469,7 @@ int ctl_scsi_reserve(struct ctl_scsiio * int ctl_start_stop(struct ctl_scsiio *ctsio); int ctl_sync_cache(struct ctl_scsiio *ctsio); int ctl_format(struct ctl_scsiio *ctsio); +int ctl_read_buffer(struct ctl_scsiio *ctsio); int ctl_write_buffer(struct ctl_scsiio *ctsio); int ctl_write_same(struct ctl_scsiio *ctsio); int ctl_unmap(struct ctl_scsiio *ctsio);