Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a04bf4b authored by Tejun Heo's avatar Tejun Heo
Browse files

[PATCH] libata-hp-prep: implement ap->hw_sata_spd_limit



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 spd limits
introduced by earlier devices from affecting new devices.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent 31534363
Loading
Loading
Loading
Loading
+12 −9
Original line number Original line Diff line number Diff line
@@ -2466,17 +2466,9 @@ static int sata_phy_resume(struct ata_port *ap)
 */
 */
void ata_std_probeinit(struct ata_port *ap)
void ata_std_probeinit(struct ata_port *ap)
{
{
	u32 scontrol;

	/* resume link */
	/* resume link */
	sata_phy_resume(ap);
	sata_phy_resume(ap);


	/* init sata_spd_limit to the current value */
	if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
		int spd = (scontrol >> 4) & 0xf;
		ap->sata_spd_limit &= (1 << spd) - 1;
	}

	/* wait for device */
	/* wait for device */
	if (ata_port_online(ap))
	if (ata_port_online(ap))
		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
@@ -5155,6 +5147,9 @@ void ata_dev_init(struct ata_device *dev)
	struct ata_port *ap = dev->ap;
	struct ata_port *ap = dev->ap;
	unsigned long flags;
	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
	/* High bits of dev->flags are used to record warm plug
	 * requests which occur asynchronously.  Synchronize using
	 * requests which occur asynchronously.  Synchronize using
	 * host_set lock.
	 * host_set lock.
@@ -5210,7 +5205,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
	ap->udma_mask = ent->udma_mask;
	ap->udma_mask = ent->udma_mask;
	ap->flags |= ent->host_flags;
	ap->flags |= ent->host_flags;
	ap->ops = ent->port_ops;
	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->active_tag = ATA_TAG_POISON;
	ap->last_ctl = 0xFF;
	ap->last_ctl = 0xFF;
	ap->msg_enable = ATA_MSG_DRV;
	ap->msg_enable = ATA_MSG_DRV;
@@ -5375,10 +5370,18 @@ int ata_device_add(const struct ata_probe_ent *ent)
	DPRINTK("probe begin\n");
	DPRINTK("probe begin\n");
	for (i = 0; i < count; i++) {
	for (i = 0; i < count; i++) {
		struct ata_port *ap;
		struct ata_port *ap;
		u32 scontrol;
		int rc;
		int rc;


		ap = host_set->ports[i];
		ap = host_set->ports[i];


		/* init sata_spd_limit to the current value */
		if (sata_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);
		DPRINTK("ata%u: bus probe begin\n", ap->id);
		rc = ata_bus_probe(ap);
		rc = ata_bus_probe(ap);
		DPRINTK("ata%u: bus probe end\n", ap->id);
		DPRINTK("ata%u: bus probe end\n", ap->id);
+1 −0
Original line number Original line Diff line number Diff line
@@ -489,6 +489,7 @@ struct ata_port {
	unsigned int		mwdma_mask;
	unsigned int		mwdma_mask;
	unsigned int		udma_mask;
	unsigned int		udma_mask;
	unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
	unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
	unsigned int		hw_sata_spd_limit;
	unsigned int		sata_spd_limit;	/* SATA PHY speed limit */
	unsigned int		sata_spd_limit;	/* SATA PHY speed limit */


	/* record runtime error info, protected by host_set lock */
	/* record runtime error info, protected by host_set lock */