From patchwork Wed Sep 2 00:28:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gwendal Grignou X-Patchwork-Id: 32778 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by bilbo.ozlabs.org (Postfix) with ESMTP id B8465B7B68 for ; Wed, 2 Sep 2009 10:29:13 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751647AbZIBA3G (ORCPT ); Tue, 1 Sep 2009 20:29:06 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752499AbZIBA3G (ORCPT ); Tue, 1 Sep 2009 20:29:06 -0400 Received: from smtp-out.google.com ([216.239.33.17]:57197 "EHLO smtp-out.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751647AbZIBA3F (ORCPT ); Tue, 1 Sep 2009 20:29:05 -0400 Received: from wpaz17.hot.corp.google.com (wpaz17.hot.corp.google.com [172.24.198.81]) by smtp-out.google.com with ESMTP id n820SAn5009220; Wed, 2 Sep 2009 01:28:11 +0100 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1251851291; bh=NwnBDBoy+94soloSWjE76CwDfFY=; h=DomainKey-Signature:From:To:Cc:Subject:Date:Message-Id:X-Mailer: In-Reply-To:References; b=ZHDQDohZAhuyiAK6NQ+1czM6TRG7TfR2YAypOPm9 yEkkpro6+0hG7+g4ridTD4nGnVDnjY8PODYYWO1OWLqo0Q== DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=UsmQ7O0qvlwLZ8LaUiakzIShknXgv9PhKN4f2LfVeab98iPNtGXUo3UUrkWVZnKLw XGFuJK3K3N7FHsk895lEg== Received: from localhost (hippo2.mtv.corp.google.com [172.18.118.87]) by wpaz17.hot.corp.google.com with ESMTP id n820S67Q029535; Tue, 1 Sep 2009 17:28:06 -0700 Received: by localhost (Postfix, from userid 60833) id F39145A2AE; Tue, 1 Sep 2009 17:28:05 -0700 (PDT) From: Gwendal Grignou To: tj@kernel.org Cc: linux-ide@vger.kernel.org, Gwendal Grignou Subject: [PATCH] Do not send RW commands to locked disks. Date: Tue, 1 Sep 2009 17:28:05 -0700 Message-Id: <1251851285-9159-1-git-send-email-gwendal@google.com> X-Mailer: git-send-email 1.5.4.3 In-Reply-To: <> References: <> Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org Send a Read/Write command to a locked disk triggers the error handler. Given the disk returns a generic device error code, the error handler can come to the conclusion of reducing the link speed, which is bad. Also, if drives are still locked at boot, this fix speeds up the boot process by returning errors without invoquing the error handler thread. Signed-off-by: Gwendal Grignou --- drivers/ata/libata-core.c | 2 ++ drivers/ata/libata-scsi.c | 6 ++++++ include/linux/ata.h | 3 +++ 3 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 072ba5e..3f80570 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5023,6 +5023,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) qc->tf.feature != SETFEATURES_WC_OFF) break; /* fall through */ + case ATA_CMD_SEC_UNLOCK: /* Read/Write access now work */ + case ATA_CMD_SEC_ERASE_UNIT: /* Read/Write access now work */ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ case ATA_CMD_SET_MULTI: /* multi_count changed */ /* revalidate device */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d0dfeef..8a41767 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1658,6 +1658,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) u32 n_block; int rc; + if (unlikely(ata_id_locked(qc->dev->id))) { + /* Terminate RW commands early when the disk is locked */ + ata_scsi_set_sense(scmd, ABORTED_COMMAND, 0, 0); + return 1; + } + if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16) tf_flags |= ATA_TFLAG_WRITE; diff --git a/include/linux/ata.h b/include/linux/ata.h index 9c75921..5a5642d 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -247,7 +247,9 @@ enum { ATA_CMD_PMP_READ = 0xE4, ATA_CMD_PMP_WRITE = 0xE8, ATA_CMD_CONF_OVERLAY = 0xB1, + ATA_CMD_SEC_ERASE_UNIT = 0xF4, ATA_CMD_SEC_FREEZE_LOCK = 0xF5, + ATA_CMD_SEC_UNLOCK = 0xF2, ATA_CMD_SMART = 0xB0, ATA_CMD_MEDIA_LOCK = 0xDE, ATA_CMD_MEDIA_UNLOCK = 0xDF, @@ -536,6 +538,7 @@ static inline int ata_is_data(u8 prot) ((u64) (id)[(n) + 0]) ) #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) +#define ata_id_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7) static inline bool ata_id_has_hipm(const u16 *id) {