[U-Boot] [PATCH v2] x86: ahci: Make sure interface is not busy after enabling the port

Each time U-Boot boots on Intel Crown Bay board, the displayed hard drive information is wrong. It could be either wrong capacity or just a 'Capacity: not available' message. After enabling the debug switch, we can see the scsi inquiry command did not execute successfully. However, doing a 'scsi scan' in the U-Boot shell does not expose this issue.
SCSI: Target spinup took 0 ms. SATA link 1 timeout. AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst scanning bus for devices... ahci_device_data_io: 0 byte transferred. <--- scsi inquiry fails ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. Device 0: (0:0) Vendor: ATA Prod.: Rev: ?8 Type: Hard Disk Capacity: 912968.3 MB = 891.5 GB (1869759264 x 512) Found 1 device(s).
So uninitialized contents on the stack were passed to dev_print() to display those wrong information.
The symptom were observed on two hard drives (one is Seagate, the other one is Western Digital). The fix is to make sure the AHCI interface is not busy by checking the error and status information from task file register after enabling the port in ahci_port_start() before proceeding other operations like scsi_scan().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - Return error codes in ahci_port_start() when timeout - Use get_timer() instead of plain loop when checking tfdata status
drivers/block/ahci.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index c9a3beb..bbc7e7d 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -500,6 +500,20 @@ static void ahci_set_feature(u8 port) } #endif
+static int wait_spinup(volatile u8 *port_mmio) +{ + ulong start; + u32 tf_data; + + start = get_timer(0); + do { + tf_data = readl(port_mmio + PORT_TFDATA); + if (!(tf_data & ATA_BUSY)) + return 0; + } while (get_timer(start) < WAIT_MS_SPINUP); + + return -ETIMEDOUT; +}
static int ahci_port_start(u8 port) { @@ -566,7 +580,11 @@ static int ahci_port_start(u8 port)
debug("Exit start port %d\n", port);
- return 0; + /* + * Make sure interface is not busy based on error and status + * information from task file data register before proceeding + */ + return wait_spinup(port_mmio); }

On 31 December 2014 at 02:18, Bin Meng bmeng.cn@gmail.com wrote:
Each time U-Boot boots on Intel Crown Bay board, the displayed hard drive information is wrong. It could be either wrong capacity or just a 'Capacity: not available' message. After enabling the debug switch, we can see the scsi inquiry command did not execute successfully. However, doing a 'scsi scan' in the U-Boot shell does not expose this issue.
SCSI: Target spinup took 0 ms. SATA link 1 timeout. AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst scanning bus for devices... ahci_device_data_io: 0 byte transferred. <--- scsi inquiry fails ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. Device 0: (0:0) Vendor: ATA Prod.: Rev: ?8 Type: Hard Disk Capacity: 912968.3 MB = 891.5 GB (1869759264 x 512) Found 1 device(s).
So uninitialized contents on the stack were passed to dev_print() to display those wrong information.
The symptom were observed on two hard drives (one is Seagate, the other one is Western Digital). The fix is to make sure the AHCI interface is not busy by checking the error and status information from task file register after enabling the port in ahci_port_start() before proceeding other operations like scsi_scan().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Return error codes in ahci_port_start() when timeout
- Use get_timer() instead of plain loop when checking tfdata status
Reviewed-by: Simon Glass sjg@chromium.org
drivers/block/ahci.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)

Hi,
On 2 January 2015 at 13:08, Simon Glass sjg@chromium.org wrote:
On 31 December 2014 at 02:18, Bin Meng bmeng.cn@gmail.com wrote:
Each time U-Boot boots on Intel Crown Bay board, the displayed hard drive information is wrong. It could be either wrong capacity or just a 'Capacity: not available' message. After enabling the debug switch, we can see the scsi inquiry command did not execute successfully. However, doing a 'scsi scan' in the U-Boot shell does not expose this issue.
SCSI: Target spinup took 0 ms. SATA link 1 timeout. AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst scanning bus for devices... ahci_device_data_io: 0 byte transferred. <--- scsi inquiry fails ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. Device 0: (0:0) Vendor: ATA Prod.: Rev: ?8 Type: Hard Disk Capacity: 912968.3 MB = 891.5 GB (1869759264 x 512) Found 1 device(s).
So uninitialized contents on the stack were passed to dev_print() to display those wrong information.
The symptom were observed on two hard drives (one is Seagate, the other one is Western Digital). The fix is to make sure the AHCI interface is not busy by checking the error and status information from task file register after enabling the port in ahci_port_start() before proceeding other operations like scsi_scan().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Return error codes in ahci_port_start() when timeout
- Use get_timer() instead of plain loop when checking tfdata status
Reviewed-by: Simon Glass sjg@chromium.org
drivers/block/ahci.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
This is assigned to me in patchwork - I am going to pick it up for x86.
Regards, Simon

On 14 January 2015 at 10:15, Simon Glass sjg@chromium.org wrote:
Hi,
On 2 January 2015 at 13:08, Simon Glass sjg@chromium.org wrote:
On 31 December 2014 at 02:18, Bin Meng bmeng.cn@gmail.com wrote:
Each time U-Boot boots on Intel Crown Bay board, the displayed hard drive information is wrong. It could be either wrong capacity or just a 'Capacity: not available' message. After enabling the debug switch, we can see the scsi inquiry command did not execute successfully. However, doing a 'scsi scan' in the U-Boot shell does not expose this issue.
SCSI: Target spinup took 0 ms. SATA link 1 timeout. AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst scanning bus for devices... ahci_device_data_io: 0 byte transferred. <--- scsi inquiry fails ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. Device 0: (0:0) Vendor: ATA Prod.: Rev: ?8 Type: Hard Disk Capacity: 912968.3 MB = 891.5 GB (1869759264 x 512) Found 1 device(s).
So uninitialized contents on the stack were passed to dev_print() to display those wrong information.
The symptom were observed on two hard drives (one is Seagate, the other one is Western Digital). The fix is to make sure the AHCI interface is not busy by checking the error and status information from task file register after enabling the port in ahci_port_start() before proceeding other operations like scsi_scan().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Return error codes in ahci_port_start() when timeout
- Use get_timer() instead of plain loop when checking tfdata status
Reviewed-by: Simon Glass sjg@chromium.org
drivers/block/ahci.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
This is assigned to me in patchwork - I am going to pick it up for x86.
Applied to u-boot-x86, thanks!
participants (2)
-
Bin Meng
-
Simon Glass