From owner-svn-src-head@freebsd.org Tue Sep 29 15:12:42 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F2E51A0CD20; Tue, 29 Sep 2015 15:12:42 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.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 E3CC61FFA; Tue, 29 Sep 2015 15:12:42 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8TFCgTZ035897; Tue, 29 Sep 2015 15:12:42 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8TFCfb1035892; Tue, 29 Sep 2015 15:12:41 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201509291512.t8TFCfb1035892@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 29 Sep 2015 15:12:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288369 - head/sys/cam/ctl X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Sep 2015 15:12:43 -0000 Author: mav Date: Tue Sep 29 15:12:40 2015 New Revision: 288369 URL: https://svnweb.freebsd.org/changeset/base/288369 Log: Really implement PREVENT ALLOW MEDIUM REMOVAL command. Modified: head/sys/cam/ctl/ctl.c head/sys/cam/ctl/ctl_backend_block.c head/sys/cam/ctl/ctl_backend_ramdisk.c head/sys/cam/ctl/ctl_cmd_table.c head/sys/cam/ctl/ctl_private.h Modified: head/sys/cam/ctl/ctl.c ============================================================================== --- head/sys/cam/ctl/ctl.c Tue Sep 29 13:58:27 2015 (r288368) +++ head/sys/cam/ctl/ctl.c Tue Sep 29 15:12:40 2015 (r288369) @@ -5129,30 +5129,43 @@ ctl_start_stop(struct ctl_scsiio *ctsio) lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_start_stop_unit *)ctsio->cdb; - if ((lun->flags & CTL_LUN_PR_RESERVED) - && ((cdb->how & SSS_START)==0)) { - uint32_t residx; + if ((cdb->how & SSS_PC_MASK) == 0) { + if ((lun->flags & CTL_LUN_PR_RESERVED) && + (cdb->how & SSS_START) == 0) { + uint32_t residx; + + residx = ctl_get_initindex(&ctsio->io_hdr.nexus); + if (ctl_get_prkey(lun, residx) == 0 || + (lun->pr_res_idx != residx && lun->res_type < 4)) { - residx = ctl_get_initindex(&ctsio->io_hdr.nexus); - if (ctl_get_prkey(lun, residx) == 0 - || (lun->pr_res_idx!=residx && lun->res_type < 4)) { + ctl_set_reservation_conflict(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + } - ctl_set_reservation_conflict(ctsio); + if ((cdb->how & SSS_LOEJ) && + (lun->flags & CTL_LUN_REMOVABLE) == 0) { + ctl_set_invalid_field(ctsio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 4, + /*bit_valid*/ 1, + /*bit*/ 1); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } - } - if ((cdb->how & SSS_LOEJ) && - (lun->flags & CTL_LUN_REMOVABLE) == 0) { - ctl_set_invalid_field(ctsio, - /*sks_valid*/ 1, - /*command*/ 1, - /*field*/ 4, - /*bit_valid*/ 1, - /*bit*/ 1); - ctl_done((union ctl_io *)ctsio); - return (CTL_RETVAL_COMPLETE); + if ((cdb->how & SSS_START) == 0 && (cdb->how & SSS_LOEJ) && + lun->prevent_count > 0) { + /* "Medium removal prevented" */ + ctl_set_sense(ctsio, /*current_error*/ 1, + /*sense_key*/(lun->flags & CTL_LUN_NO_MEDIA) ? + SSD_KEY_NOT_READY : SSD_KEY_ILLEGAL_REQUEST, + /*asc*/ 0x53, /*ascq*/ 0x02, SSD_ELEM_NONE); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } } retval = lun->backend->config_write((union ctl_io *)ctsio); @@ -5163,11 +5176,14 @@ int ctl_prevent_allow(struct ctl_scsiio *ctsio) { struct ctl_lun *lun; + struct scsi_prevent *cdb; int retval; + uint32_t initidx; CTL_DEBUG_PRINT(("ctl_prevent_allow\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + cdb = (struct scsi_prevent *)ctsio->cdb; if ((lun->flags & CTL_LUN_REMOVABLE) == 0) { ctl_set_invalid_opcode(ctsio); @@ -5175,6 +5191,18 @@ ctl_prevent_allow(struct ctl_scsiio *cts return (CTL_RETVAL_COMPLETE); } + initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); + mtx_lock(&lun->lun_lock); + if ((cdb->how & PR_PREVENT) && + ctl_is_set(lun->prevent, initidx) == 0) { + ctl_set_mask(lun->prevent, initidx); + lun->prevent_count++; + } else if ((cdb->how & PR_PREVENT) == 0 && + ctl_is_set(lun->prevent, initidx)) { + ctl_clear_mask(lun->prevent, initidx); + lun->prevent_count--; + } + mtx_unlock(&lun->lun_lock); retval = lun->backend->config_write((union ctl_io *)ctsio); return (retval); } @@ -11805,9 +11833,7 @@ ctl_do_lun_reset(struct ctl_lun *lun, un #if 0 uint32_t initidx; #endif -#ifdef CTL_WITH_CA int i; -#endif mtx_lock(&lun->lun_lock); /* @@ -11842,6 +11868,9 @@ ctl_do_lun_reset(struct ctl_lun *lun, un for (i = 0; i < CTL_MAX_INITIATORS; i++) ctl_clear_mask(lun->have_ca, i); #endif + lun->prevent_count = 0; + for (i = 0; i < CTL_MAX_INITIATORS; i++) + ctl_clear_mask(lun->prevent, i); mtx_unlock(&lun->lun_lock); return (0); @@ -11987,6 +12016,10 @@ ctl_i_t_nexus_reset(union ctl_io *io) #endif if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx)) lun->flags &= ~CTL_LUN_RESERVED; + if (ctl_is_set(lun->prevent, initidx)) { + ctl_clear_mask(lun->prevent, initidx); + lun->prevent_count--; + } ctl_est_ua(lun, initidx, CTL_UA_I_T_NEXUS_LOSS); mtx_unlock(&lun->lun_lock); } Modified: head/sys/cam/ctl/ctl_backend_block.c ============================================================================== --- head/sys/cam/ctl/ctl_backend_block.c Tue Sep 29 13:58:27 2015 (r288368) +++ head/sys/cam/ctl/ctl_backend_block.c Tue Sep 29 15:12:40 2015 (r288369) @@ -2754,6 +2754,11 @@ ctl_be_block_config_write(union ctl_io * struct ctl_lun_req req; cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; + if ((cdb->how & SSS_PC_MASK) != 0) { + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + } if (cdb->how & SSS_START) { if ((cdb->how & SSS_LOEJ) && be_lun->vn == NULL) { retval = ctl_be_block_open(be_lun, &req); Modified: head/sys/cam/ctl/ctl_backend_ramdisk.c ============================================================================== --- head/sys/cam/ctl/ctl_backend_ramdisk.c Tue Sep 29 13:58:27 2015 (r288368) +++ head/sys/cam/ctl/ctl_backend_ramdisk.c Tue Sep 29 15:12:40 2015 (r288369) @@ -880,6 +880,11 @@ ctl_backend_ramdisk_config_write(union c struct scsi_start_stop_unit *cdb; cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; + if ((cdb->how & SSS_PC_MASK) != 0) { + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + } if (cdb->how & SSS_START) { if (cdb->how & SSS_LOEJ) ctl_lun_has_media(cbe_lun); Modified: head/sys/cam/ctl/ctl_cmd_table.c ============================================================================== --- head/sys/cam/ctl/ctl_cmd_table.c Tue Sep 29 13:58:27 2015 (r288368) +++ head/sys/cam/ctl/ctl_cmd_table.c Tue Sep 29 15:12:40 2015 (r288369) @@ -658,7 +658,7 @@ const struct ctl_cmd_entry ctl_cmd_table CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_FLAG_DATA_NONE | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, - CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0x03, 0x07}}, + CTL_LUN_PAT_NONE, 6, {0x01, 0, 0x0f, 0xf7, 0x07}}, /* 1C RECEIVE DIAGNOSTIC RESULTS */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, Modified: head/sys/cam/ctl/ctl_private.h ============================================================================== --- head/sys/cam/ctl/ctl_private.h Tue Sep 29 13:58:27 2015 (r288368) +++ head/sys/cam/ctl/ctl_private.h Tue Sep 29 15:12:40 2015 (r288369) @@ -397,6 +397,8 @@ struct ctl_lun { int pr_key_count; uint32_t pr_res_idx; uint8_t res_type; + int prevent_count; + uint32_t prevent[(CTL_MAX_INITIATORS+31)/32]; uint8_t *write_buffer; struct ctl_devid *lun_devid; TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists;