From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tejun Heo Subject: [PATCH 06/14] libata-hp-prep: implement ap->hw_sata_spd_limit Date: Fri, 12 May 2006 00:02:35 +0900 Message-ID: <1147359755308-git-send-email-htejun@gmail.com> References: <11473597542442-git-send-email-htejun@gmail.com> Reply-To: Tejun Heo Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT Return-path: Received: from py-out-1112.google.com ([64.233.166.179]:17373 "EHLO py-out-1112.google.com") by vger.kernel.org with ESMTP id S1751833AbWEKPCq (ORCPT ); Thu, 11 May 2006 11:02:46 -0400 Received: by py-out-1112.google.com with SMTP id f28so276359pyf for ; Thu, 11 May 2006 08:02:46 -0700 (PDT) In-Reply-To: <11473597542442-git-send-email-htejun@gmail.com> Sender: linux-ide-owner@vger.kernel.org List-Id: linux-ide@vger.kernel.org To: jgarzik@pobox.com, alan@lxorguk.ukuu.org.uk, axboe@suse.de, albertcc@tw.ibm.com, forrest.zhao@intel.com, efalk@google.com, linux-ide@vger.kernel.org Cc: Tejun Heo Add ap->hw_sata_spd_limit and initialize it once during the boot initialization (or driver load initialization). ap->sata_spd_limit is reset to ap->hw_sata_spd_limit on hotplug. This prevents limits introduced by earlier devices from affecting new devices. --- drivers/scsi/libata-core.c | 21 ++++++++++++--------- include/linux/libata.h | 1 + 2 files changed, 13 insertions(+), 9 deletions(-) 658f9435c1ea00f1222bc0090b4bffe41111604f diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 6accef3..6da1005 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2456,17 +2456,9 @@ static int sata_phy_resume(struct ata_po */ void ata_std_probeinit(struct ata_port *ap) { - u32 scontrol; - /* resume link */ sata_phy_resume(ap); - /* init sata_spd_limit to the current value */ - if (ata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { - int spd = (scontrol >> 4) & 0xf; - ap->sata_spd_limit &= (1 << spd) - 1; - } - /* wait for device */ if (ata_port_online(ap)) ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); @@ -5121,6 +5113,9 @@ void ata_dev_init(struct ata_device *dev struct ata_port *ap = dev->ap; unsigned long flags; + /* SATA spd limit is bound to the first device */ + ap->sata_spd_limit = ap->hw_sata_spd_limit; + /* High bits of dev->flags are used to record warm plug * requests which occur asynchronously. Synchronize using * host_set lock. @@ -5177,7 +5172,7 @@ static void ata_host_init(struct ata_por ap->udma_mask = ent->udma_mask; ap->flags |= ent->host_flags; ap->ops = ent->port_ops; - ap->sata_spd_limit = UINT_MAX; + ap->hw_sata_spd_limit = UINT_MAX; ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; @@ -5340,10 +5335,18 @@ int ata_device_add(const struct ata_prob DPRINTK("probe begin\n"); for (i = 0; i < count; i++) { struct ata_port *ap; + u32 scontrol; int rc; ap = host_set->ports[i]; + /* init sata_spd_limit to the current value */ + if (ata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { + int spd = (scontrol >> 4) & 0xf; + ap->hw_sata_spd_limit &= (1 << spd) - 1; + } + ap->sata_spd_limit = ap->hw_sata_spd_limit; + DPRINTK("ata%u: bus probe begin\n", ap->id); rc = ata_bus_probe(ap); DPRINTK("ata%u: bus probe end\n", ap->id); diff --git a/include/linux/libata.h b/include/linux/libata.h index 99a78cf..6ab988a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -480,6 +480,7 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ + unsigned int hw_sata_spd_limit; unsigned int sata_spd_limit; /* SATA PHY speed limit */ /* record runtime error info, protected by host_set lock */ -- 1.2.4