libahci: fix turning on LEDs in ahci_start_port()
If EM Transmit bit is busy during init ata_msleep() is called. It is wrong - msleep() should be used instead of ata_msleep(), because if EM Transmit bit is busy for one port, it will be busy for all other ports too, so using ata_msleep() causes wasting tries for another ports. The most common scenario looks like that now (six ports try to transmit a LED meaasege): - port #0 tries for the 1st time and succeeds - ports #1-5 try for the 1st time and sleeps - port #1 tries for the 2nd time and succeeds - ports #2-5 try for the 2nd time and sleeps - port #2 tries for the 3rd time and succeeds - ports #3-5 try for the 3rd time and sleeps - port #3 tries for the 4th time and succeeds - ports #4-5 try for the 4th time and sleeps - port #4 tries for the 5th time and succeeds - port #5 tries for the 5th time and sleeps At this moment port #5 wasted all its five tries and failed to initialize. Because there are only 5 (EM_MAX_RETRY) tries available usually only five ports succeed to initialize. The sixth port and next ones usually will fail. If msleep() is used instead of ata_msleep() the first port succeeds to initialize in the first try and next ones usually succeed to initialize in the second try. tj: updated comment Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
@@ -778,8 +778,16 @@ static void ahci_start_port(struct ata_port *ap)
|
|||||||
rc = ap->ops->transmit_led_message(ap,
|
rc = ap->ops->transmit_led_message(ap,
|
||||||
emp->led_state,
|
emp->led_state,
|
||||||
4);
|
4);
|
||||||
|
/*
|
||||||
|
* If busy, give a breather but do not
|
||||||
|
* release EH ownership by using msleep()
|
||||||
|
* instead of ata_msleep(). EM Transmit
|
||||||
|
* bit is busy for the whole host and
|
||||||
|
* releasing ownership will cause other
|
||||||
|
* ports to fail the same way.
|
||||||
|
*/
|
||||||
if (rc == -EBUSY)
|
if (rc == -EBUSY)
|
||||||
ata_msleep(ap, 1);
|
msleep(1);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user