From patchwork Thu Aug 9 19:41:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 10561859 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DB6113BB for ; Thu, 9 Aug 2018 19:42:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D5AB2B979 for ; Thu, 9 Aug 2018 19:42:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 816882B97F; Thu, 9 Aug 2018 19:42:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8FDAB2B979 for ; Thu, 9 Aug 2018 19:42:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727025AbeHIWIa (ORCPT ); Thu, 9 Aug 2018 18:08:30 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:1352 "EHLO esa1.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726744AbeHIWIa (ORCPT ); Thu, 9 Aug 2018 18:08:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1533843732; x=1565379732; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=pbMXdEWeUW4tvLeIQHDxjdCjtxl4S3H9A0eBlQedDlo=; b=lFBuMc19o0EURmDH4RX5N9DuGuVDLG3xRyuSv+4rVOZuihQ+P9A+aj2O OmSipLd94crKuJs0WtdJkzTI42ki7yBamBDusHCosvh05abpFGWCF/s9A J7q3KV7XQBXNsfwo9qO0mXyjD9bOSpp0KaCisWcQYRsw6tDAodRcMeKXR rSGdg+PLO7bADboagOzG8gCg5c5NveI2295PevdFUi1Pn0adzra78zldz 8Ld/q+fsWUFDvERbguGjgKyBVH916kKZbwdtBnXciqqVXda4SAwJLmKfJ R8QLMk4TqV5miV3fj8/t8NfCt6cglSck9Tw8L+WhRil8APsEHLTyzrVkO Q==; X-IronPort-AV: E=Sophos;i="5.53,215,1531756800"; d="scan'208";a="191119596" Received: from mail-sn1nam01lp0115.outbound.protection.outlook.com (HELO NAM01-SN1-obe.outbound.protection.outlook.com) ([207.46.163.115]) by ob1.hgst.iphmx.com with ESMTP; 10 Aug 2018 03:42:11 +0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector1-wdc-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UIhtvZyjT3MesRVGauD7qo/IrxCVCgke7YSs08HYsvY=; b=NIoH1nRQ9tC9YFB9gTEhsV0yujTnOYCU7pKtWeVv2FGrm2goRUsBq9MUl20GlWhFgOOPuZ3HlOEbfOeAA8hvSCjVv6fUkTiYYj/s5UaLkv0SD/wDu/wfklmxP6nE+HpnPwsusJc1iFk4QiUEvjF9Ho73aiJbIrfgRnqW/4SPKHU= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Bart.VanAssche@wdc.com; Received: from asus.hsd1.ca.comcast.net (174.62.111.89) by MWHPR04MB1198.namprd04.prod.outlook.com (2603:10b6:300:71::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1038.23; Thu, 9 Aug 2018 19:42:06 +0000 From: Bart Van Assche To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Bart Van Assche , "Martin K . Petersen" , Ming Lei , Jianchao Wang , Hannes Reinecke , Johannes Thumshirn , Alan Stern Subject: [PATCH v6 04/12] scsi: Introduce the SDEV_SUSPENDED device status Date: Thu, 9 Aug 2018 12:41:41 -0700 Message-Id: <20180809194149.15285-5-bart.vanassche@wdc.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180809194149.15285-1-bart.vanassche@wdc.com> References: <20180809194149.15285-1-bart.vanassche@wdc.com> MIME-Version: 1.0 X-Originating-IP: [174.62.111.89] X-ClientProxiedBy: MWHPR2201CA0066.namprd22.prod.outlook.com (2603:10b6:301:5e::19) To MWHPR04MB1198.namprd04.prod.outlook.com (2603:10b6:300:71::23) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ae75a4f8-d8bc-4aca-b1ac-08d5fe3030d4 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989117)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);SRVR:MWHPR04MB1198; X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB1198;3:2OTjQ4Oaxtt7cSuoofFn0j1Oaftew+atRswuOHyfcd41VTxKwMofTNW3AgRncbrld2Nq67MAOmaMLoxWwvAs2dBruwu4HF1TkjqnIEEtPMx0LZ27+fBXvaOJbVG0Y9f1dABjor2wn8fNm1zvc9ijmbqsslVjj4nhGyiOAUfPly9RUKGEEu5dJqfT8HYcTEGgmzEHaaMcpDTHBtT8d9lBY3axykfiel1HPKph3OUqba8oC2c4BPiVgZHAfTPyeBYa;25:lS7B0r1lC1fhUku+qKAAC5wz66EP0UgTJRzVrzNtSrOqye2dWeuurKG4fdlYJ9cXK0+V1X5HULUMPob2Hcou2c23ZeQwNF7rwDaxgcnjeWA5VXg2jIeSiiyiecnl6UpXNuU8AdQxZ9rzRP2oNVaMzQhYL9aAMkDqegenPcEg5phB6p0YzUekF19wUMGFWZMPhPVXy6irgEMSKI0NxvjAkznHn3JW5V5xJm1o+OVVN1SoCZX+fIXjm/mdQsUeVAhgxGlHWu4BwN64GDpQBN7wwCzxDwluWrQjNW0RP2xza1j0gs4nDyO71y8+hXgTlaUPSXM5qXYFQYnQEnTph+M+Kg==;31:Ad8bUO2DfQK6MCnZZnWoyYTXibp3GUckV2hVcW5+uBfhppMTcyqDCGgOEhMXZHaygCLYs5qv2mh0xELOGDaKmHl/zHW+zlhAIAk+hbULF+0iM9FaCa5tW9+1jO0PUMFUnTkumCf6Vi4cA5bvDElCNNRCL3G5ixNoNUal6aKAIAKFHqIN/jf1KP64phKe4ap8ClGLMv0muI4KeRyd+qL1Hty0MgXlQe4ptUWq0iFQ+To= X-MS-TrafficTypeDiagnostic: MWHPR04MB1198: WDCIPOUTBOUND: EOP-TRUE X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB1198;20:DbEOaXq9mPn3+ZsV1yAyd97lGasbXZIK/vbidsTTK1R+t6e9ntMEdFeMiv3ZifAmVBHcLMi8kuMLGRncPQXXixkh3Pd8V0w6OhXFWNCdWabY8xZ9yE03VH1Pw7JBRh86o8JQTYCaSMnuxmzmtsLNTEnrED+wplMXl8g2wVfr5P4NeOfKnvFCmMYtZYqxSbvSpnLBsPDxVB/5Q2cTdAGbMwtfn/S+04xHQd5W4D+6jown5opoqtO7VJbcavLE9kKYkU7zPjcqLpOTN0REEx9V8xs1clVjA4ixscmvnREJRT9sRvAgIJOtbiCOkbAKNY06tOtP899QNB1M9bBAuBzhtipA2LZ/rkC/PDj4Tl3159bAKZRQyqhVp39lqDTcyvKRJvYk+rfSvXFArcGG8hKSfmz9dAWBSC1x8DXDyyaqkFuNF5T79iegrsaVoLCu2Kx1OzYCdHPUXPhQc/GUl5iPQwNvt4cF4t3V5sqbpvO9fPpTBOcExvomPOBiQ34ps+Er;4:STxzFNGoE6+BMi2Aeedv8yf/LaMa7TPXpj8IMmMOV+olpHlJxQ96jEKf7a9VBVV3V/tIeW11AQZgOBybNu/aucC2ujJ8nRp6fcruKCDd9CN+2rfQ63QuZsBM+LoZMaTxyaqnCvA2Ss5u+9BUlU2CXkAnovFAhvcHKH1bLs+yf8OFkDyDRKmnTrD0m+HR+w/03Z9M0y9LAjQXqgVXvPbW2YB3sz0CwA0JVZFnk3lVzo832xTOaMDBmAK70/TdhgnoKgddx4HqpoTtk/bVq2c6KEzR4niPLy6OtZSdkOeoa7TmpUMX+fjAV/yOUf/seJkH6Koyh9liUscMX+N2+D0ey45L5k1ch6LJSSqlnQwmiTg= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(35762410373642)(146099531331640); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231311)(944501410)(52105095)(3002001)(10201501046)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(20161123564045)(20161123560045)(6072148)(201708071742011)(7699016);SRVR:MWHPR04MB1198;BCL:0;PCL:0;RULEID:;SRVR:MWHPR04MB1198; X-Forefront-PRVS: 0759F7A50A X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(396003)(39860400002)(136003)(366004)(346002)(376002)(199004)(189003)(966005)(76176011)(50466002)(476003)(51416003)(4326008)(478600001)(52116002)(6486002)(105586002)(72206003)(48376002)(5660300001)(47776003)(305945005)(2616005)(956004)(7736002)(6916009)(6666003)(486006)(8936002)(2906002)(68736007)(36756003)(66066001)(186003)(446003)(81166006)(50226002)(8676002)(81156014)(316002)(6506007)(386003)(106356001)(97736004)(25786009)(11346002)(16586007)(54906003)(14444005)(6116002)(1076002)(3846002)(86362001)(26005)(16526019)(53936002)(6512007)(6306002);DIR:OUT;SFP:1102;SCL:1;SRVR:MWHPR04MB1198;H:asus.hsd1.ca.comcast.net;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB1198;23:xI7jS/CbhVhDdHvWDdl4287iGwXd6LQoXDCemsM44Exj7Ieeeth2qZ7CfQSdNQC21Jd9SD+nwrmZMVHj25BFqTnzi9nPCZZcf0EYt4Pm/w09E9UytumJh84RXRpoIUHswo6XJw6kZDroaZ8XX3o25ZDPrgbcXpwvyyfmBU1FjLUvUsXHceKrC0ipzGUqOraTevyI/EzpzUY8eemFNA1LTCqN9ixG/J5fRtIlMvKI/2FjLvK8Vm/w58IHwuHiYFOFgI6eNgJDquR1zdZ6iWFgu+Yo9F4IVfil+TXwJ4cFWDtxRLY18Tzd8//dkHDgszkSiM/usEZ2dhN4B2svZtMy7Yi7IqKz1O9vKRww+3V23WTvSpXhOYA+xMvbWI9viqIw9+AucNuzLHVosxoGuflfc+IMAzSnF5z64G86CGMHrJyBUMP81zaN9W9qgYEgKd+2I0PoQ7hI559SF8nl+J/ern+Pf6coa7Iw7HmYvvgC1Ih8cAPU4T0fahrUo5s5RtspJddsDTGR5C++8y150yF7yV9EKCukSEVNbofdXaJglbc5MGFQBXFPknV5Z0IOQHRJ7VE8JPIzxTLeATqamrln5tY0u2nZTeXrc0nGsBMhT3l/OSS31PVClPOE5nSyumHq8T0x9OvNr+ZLdzvHCc86azNlZa+s1B+3LYA92I7QuWfvWGg7UfyI/bWSzzMOGDeWf8vYxnNRFl3cuhyoxQ9xtY7dFDM+nwm1u7QpZ+G+xwLkS3nzzoLrliTXX3RPiK+rpXbUwPqwDhZgbVEuf99DMUocGHjfggcZeQXQ6ZWJ2sFHli51/Vhc+EOS2xp+XpF9QE58DI8rSNFELsBhV0z7Ic9Q2IQpLXLJsZJc89BbTBhaMzGEwqA8K03r80IwtJyMoZCX7kiA755mApNg6tlJmXpzUTuu4K15DY1bbt98dLp7rF1RMVxfIHwys1HNxH2mYEZ68AZg8CEsVULvk4vcXIsN5WbdeSgbC+Z+M7gdFhhOVDuzGM5FOnOz7YDhMn6bXlMYY+HA7oIHJdbiovqVWMzmsIIT9TFfcllTW4XJRUG9/9AMpeVlZfHFT4zshM1RLDpim4YDTTFkfwFOHmpbScYf5x/e8DWdZ7VZ7nQs8QNQDqsOUc6oCVnTAgWZLA6tByDwbvuCKGt/aAI/3WoBB8wiHeZmYmE0QWRI8eQEuc2SX2c8LRIW1g30DOEKrrz/sEcNA//uzFyQClEM/gvWBgVTa/RddSgNsQqDF7R29MFPQ8+9fQjSM47cRrhyTuVPrAEe+fZX7ba9mVrnEIA3OQ== X-Microsoft-Antispam-Message-Info: /SlMP0i1buEVKAKcbynnaVUmI7avs+lRjmxosL7yezmSPS9IS5E+69FD2l+l+9QKa4PHh3bf9ysteR2O/gwAV92sTCqpWA1cXn1ahqw8C7mPwJ63OdywlsereT64aTVt5KGBYsM1vIipPbRZdgLqwenovxnbg56w+q99oUeEdjHcfZvOIg0QP7bbxG3iJ7MdDTUQ7Au/pnYr2czyH0UHcLpFQVyWVWsUHkMg1By5smJofXsejE2eQrMA8NL1lj64c7B1KH0E7yYgdV39iml/PcYYyqMirosrtno/ReQ1o4l6UkAtAXEpE7RsyF2PTXGP+5un7PbKi4ANEZsB2sCASy9w+gevM0VsGkmvHVo+1pM= X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB1198;6:OI5Kl0wbWsUwIEOPvULC93aYFU8Aol0xzWIZPpDmd1kxqfbt0GmWlzixqmk437QIUirVanu9KiVzdj+UVMJFhkh85ze6HMoB2xxRMKCkQkbL86kvEyIq5ZWpbD4QH3zXMpc+IPshFFQpxch5Jtmeq9zu27FNBaNBbHXWmnnrRTQLSUYKUydpDXl4FHuAylWyupYTZjQIeU8p/qS2MWIPUGUHLB6QCL1XiMJYb8m4gm4fDCBLE6B8lJFtHV1wzchhfZxPZ0u0187ceG0N369Dzq+G2TSt5sIPKcf5ji1gNwkNVeB4DY5zOsVV+3uY3FCH/HljQf9zOWFt/WfliEzSEKM9xpEwrl99iSvJ29MhQcZro1E4oKYkpcQehsRYEByJA82q+g8YugY6s/JRU4qKlsYarq47rampYpSG5jG+XicaNRkdfQ7tMpAHl/AfNr8N2JLnzCfCZX06wW6fTZk3Tw==;5:Zk/VTrxAXIX+1zVaKP8/PIEC4Ex4NluRrXdSnayztlx31EIwsdkxBlupQW+2S4kLTjDBQ82JBvwBkr67ws2PtxEM3L+Oubz3pepWgSPpUDuvnHxRCyYSEayHIprkQf1SLTgZVAkD+OuyzSbjH7DOBFcfqI3fCpySa1DNXzABxmk=;7:yhTGcrcLNnt+vPsRezOqyZqYIYnkUZlV+Vd8d0oTK8ZdICH29DHaw0QgVOKI/CM941mTZee9fM2VaVx4rSxeFXORLdVnJ7FzBoZSAeNkr3cgSpEg8/agKgNtQXoMqfwGENxL3BrNBHTwm9d9g4WIF5vluRpH4v+vmmpCP6aP4OA+bWQor6PLZof4pOZ/E/cL3ttj9tM/ZuFiA7AIZHftQf7BGBo+VlWO1QRHD8fMPqXI+4jnNniNNdbttjPAgh68 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB1198;20:q/hl3cOjL3K9DAVnHuaeJjsfMhopFCCd6GZshygPv8owpPILIJlqOgqKdTn0G1ws/OwtqtcGXzADVUieiiutYTUt6Z1ezWozc/NakfkqSbZZSy80yl0Sb6p33zR+1TkOBwm8NrExxucI/sbEKeMH4NaRuH2rul1bK5niucVUDcQ= X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Aug 2018 19:42:06.9900 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ae75a4f8-d8bc-4aca-b1ac-08d5fe3030d4 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR04MB1198 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Instead of using the SDEV_QUIESCE state for both SCSI domain validation and runtime suspend, use the SDEV_QUIESCE state only for SCSI domain validation. Keep using scsi_device_quiesce() and scsi_device_unquiesce() for SCSI domain validation. Add new functions scsi_device_suspend() and scsi_device_unsuspend() for power management. Rename scsi_device_resume() into scsi_device_unquiesce() to avoid confusion. Signed-off-by: Bart Van Assche Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: Ming Lei Cc: Jianchao Wang Cc: Hannes Reinecke Cc: Johannes Thumshirn Cc: Alan Stern --- drivers/scsi/scsi_lib.c | 138 ++++++++++++++++++++++++------ drivers/scsi/scsi_pm.c | 6 +- drivers/scsi/scsi_sysfs.c | 1 + drivers/scsi/scsi_transport_spi.c | 2 +- include/scsi/scsi_device.h | 13 +-- 5 files changed, 125 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4d7411a7985f..eb914d8e17fd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1365,6 +1365,11 @@ scsi_prep_state_check(struct scsi_device *sdev, struct request *req) if (!(req->rq_flags & (RQF_PM | RQF_DV))) ret = BLKPREP_DEFER; break; + case SDEV_SUSPENDED: + /* Process RQF_PM requests only. */ + if (!(req->rq_flags & RQF_PM)) + ret = BLKPREP_DEFER; + break; case SDEV_CANCEL: /* Only allow RQF_PM requests. */ if (!(req->rq_flags & RQF_PM)) @@ -2669,6 +2674,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) case SDEV_OFFLINE: case SDEV_TRANSPORT_OFFLINE: case SDEV_QUIESCE: + case SDEV_SUSPENDED: case SDEV_BLOCK: break; default: @@ -2677,6 +2683,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) break; case SDEV_QUIESCE: + case SDEV_SUSPENDED: switch (oldstate) { case SDEV_RUNNING: case SDEV_OFFLINE: @@ -2970,19 +2977,103 @@ static void scsi_wait_for_queuecommand(struct scsi_device *sdev) } /** - * scsi_device_quiesce - Block user issued commands. - * @sdev: scsi device to quiesce. + * scsi_device_suspend - only process RQF_PM requests + * @sdev: scsi device to suspend. + * + * This works by trying to transition to the SDEV_SUSPENDED state (which must be + * a legal transition). When the device is in this state, only RQF_DV + * requests will be accepted, all others will be deferred. + * + * Must be called with user context, may sleep. + * + * Returns zero if unsuccessful or an error if not. + */ +int +scsi_device_suspend(struct scsi_device *sdev) +{ + struct request_queue *q = sdev->request_queue; + int err; + + if (sdev->sdev_state == SDEV_SUSPENDED) + return 0; + + blk_set_preempt_only(q); + + blk_mq_freeze_queue(q); + /* + * Ensure that the effect of blk_set_preempt_only() will be visible + * for percpu_ref_tryget() callers that occur after the queue + * unfreeze even if the queue was already frozen before this function + * was called. See also https://lwn.net/Articles/573497/. + */ + synchronize_rcu(); + blk_mq_unfreeze_queue(q); + + mutex_lock(&sdev->state_mutex); + err = scsi_device_set_state(sdev, SDEV_SUSPENDED); + if (err) + blk_clear_preempt_only(q); + mutex_unlock(&sdev->state_mutex); + + return err; +} +EXPORT_SYMBOL(scsi_device_suspend); + +/** + * scsi_device_unsuspend - unsuspend processing non-RQF_DV requests + * @sdev: scsi device to unsuspend. * - * This works by trying to transition to the SDEV_QUIESCE state - * (which must be a legal transition). When the device is in this - * state, only special requests will be accepted, all others will - * be deferred. Since special requests may also be requeued requests, - * a successful return doesn't guarantee the device will be - * totally quiescent. + * Moves the device from suspended back to running and restarts the queues. * - * Must be called with user context, may sleep. + * Must be called with user context, may sleep. + */ +void scsi_device_unsuspend(struct scsi_device *sdev) +{ + mutex_lock(&sdev->state_mutex); + blk_clear_preempt_only(sdev->request_queue); + if (sdev->sdev_state == SDEV_SUSPENDED) + scsi_device_set_state(sdev, SDEV_RUNNING); + mutex_unlock(&sdev->state_mutex); +} +EXPORT_SYMBOL(scsi_device_unsuspend); + +static void +device_suspend_fn(struct scsi_device *sdev, void *data) +{ + scsi_device_suspend(sdev); +} + +void +scsi_target_suspend(struct scsi_target *starget) +{ + starget_for_each_device(starget, NULL, device_suspend_fn); +} +EXPORT_SYMBOL(scsi_target_suspend); + +static void +device_unsuspend_fn(struct scsi_device *sdev, void *data) +{ + scsi_device_unsuspend(sdev); +} + +void +scsi_target_unsuspend(struct scsi_target *starget) +{ + starget_for_each_device(starget, NULL, device_unsuspend_fn); +} +EXPORT_SYMBOL(scsi_target_unsuspend); + +/** + * scsi_device_quiesce - only process RQF_DV requests + * @sdev: scsi device to quiesce. * - * Returns zero if unsuccessful or an error if not. + * This works by trying to transition to the SDEV_QUIESCE state (which must be + * a legal transition). When the device is in this state, only RQF_DV + * requests will be accepted, all others will be deferred. + * + * Must be called with user context, may sleep. + * + * Returns zero if unsuccessful or an error if not. */ int scsi_device_quiesce(struct scsi_device *sdev) @@ -3022,20 +3113,15 @@ scsi_device_quiesce(struct scsi_device *sdev) EXPORT_SYMBOL(scsi_device_quiesce); /** - * scsi_device_resume - Restart user issued commands to a quiesced device. - * @sdev: scsi device to resume. + * scsi_device_unquiesce - unquiesce processing non-RQF_DV requests + * @sdev: scsi device to unquiesce. * - * Moves the device from quiesced back to running and restarts the - * queues. + * Moves the device from quiesced back to running and restarts the queues. * - * Must be called with user context, may sleep. + * Must be called with user context, may sleep. */ -void scsi_device_resume(struct scsi_device *sdev) +void scsi_device_unquiesce(struct scsi_device *sdev) { - /* check if the device state was mutated prior to resume, and if - * so assume the state is being managed elsewhere (for example - * device deleted during suspend) - */ mutex_lock(&sdev->state_mutex); WARN_ON_ONCE(!sdev->quiesced_by); sdev->quiesced_by = NULL; @@ -3044,7 +3130,7 @@ void scsi_device_resume(struct scsi_device *sdev) scsi_device_set_state(sdev, SDEV_RUNNING); mutex_unlock(&sdev->state_mutex); } -EXPORT_SYMBOL(scsi_device_resume); +EXPORT_SYMBOL(scsi_device_unquiesce); static void device_quiesce_fn(struct scsi_device *sdev, void *data) @@ -3060,17 +3146,17 @@ scsi_target_quiesce(struct scsi_target *starget) EXPORT_SYMBOL(scsi_target_quiesce); static void -device_resume_fn(struct scsi_device *sdev, void *data) +device_unquiesce_fn(struct scsi_device *sdev, void *data) { - scsi_device_resume(sdev); + scsi_device_unquiesce(sdev); } void -scsi_target_resume(struct scsi_target *starget) +scsi_target_unquiesce(struct scsi_target *starget) { - starget_for_each_device(starget, NULL, device_resume_fn); + starget_for_each_device(starget, NULL, device_unquiesce_fn); } -EXPORT_SYMBOL(scsi_target_resume); +EXPORT_SYMBOL(scsi_target_unquiesce); /** * scsi_internal_device_block_nowait - try to transition to the SDEV_BLOCK state diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index b44c1bb687a2..6300e168701d 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -57,11 +57,11 @@ static int scsi_dev_type_suspend(struct device *dev, /* flush pending in-flight resume operations, suspend is synchronous */ async_synchronize_full_domain(&scsi_sd_pm_domain); - err = scsi_device_quiesce(to_scsi_device(dev)); + err = scsi_device_suspend(to_scsi_device(dev)); if (err == 0) { err = cb(dev, pm); if (err) - scsi_device_resume(to_scsi_device(dev)); + scsi_device_unsuspend(to_scsi_device(dev)); } dev_dbg(dev, "scsi suspend: %d\n", err); return err; @@ -74,7 +74,7 @@ static int scsi_dev_type_resume(struct device *dev, int err = 0; err = cb(dev, pm); - scsi_device_resume(to_scsi_device(dev)); + scsi_device_unsuspend(to_scsi_device(dev)); dev_dbg(dev, "scsi resume: %d\n", err); if (err == 0) { diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 7943b762c12d..496c5eff4859 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -36,6 +36,7 @@ static const struct { { SDEV_CANCEL, "cancel" }, { SDEV_DEL, "deleted" }, { SDEV_QUIESCE, "quiesce" }, + { SDEV_SUSPENDED, "suspended" }, { SDEV_OFFLINE, "offline" }, { SDEV_TRANSPORT_OFFLINE, "transport-offline" }, { SDEV_BLOCK, "blocked" }, diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index bf6b18768e79..16bec4884249 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -1048,7 +1048,7 @@ spi_dv_device(struct scsi_device *sdev) mutex_unlock(&spi_dv_mutex(starget)); spi_dv_pending(starget) = 0; - scsi_target_resume(starget); + scsi_target_unquiesce(starget); spi_initial_dv(starget) = 1; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 440834f4252e..a2e3edf8be12 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -42,9 +42,8 @@ enum scsi_device_state { * Only error handler commands allowed */ SDEV_DEL, /* device deleted * no commands allowed */ - SDEV_QUIESCE, /* Device quiescent. No block commands - * will be accepted, only specials (which - * originate in the mid-layer) */ + SDEV_QUIESCE, /* Only RQF_DV requests are accepted. */ + SDEV_SUSPENDED, /* Only RQF_PM requests are accepted. */ SDEV_OFFLINE, /* Device offlined (by error handling or * user request */ SDEV_TRANSPORT_OFFLINE, /* Offlined by transport class error handler */ @@ -415,9 +414,13 @@ extern void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt); extern void sdev_evt_send_simple(struct scsi_device *sdev, enum scsi_device_event evt_type, gfp_t gfpflags); extern int scsi_device_quiesce(struct scsi_device *sdev); -extern void scsi_device_resume(struct scsi_device *sdev); +extern void scsi_device_unquiesce(struct scsi_device *sdev); extern void scsi_target_quiesce(struct scsi_target *); -extern void scsi_target_resume(struct scsi_target *); +extern void scsi_target_unquiesce(struct scsi_target *); +extern int scsi_device_suspend(struct scsi_device *sdev); +extern void scsi_device_unsuspend(struct scsi_device *sdev); +extern void scsi_target_suspend(struct scsi_target *); +extern void scsi_target_unsuspend(struct scsi_target *); extern void scsi_scan_target(struct device *parent, unsigned int channel, unsigned int id, u64 lun, enum scsi_scan_mode rescan);