summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/dev/drivers/block/ahci.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/linux/dev/drivers/block/ahci.c b/linux/dev/drivers/block/ahci.c
index 88b2ab8..a9d6335 100644
--- a/linux/dev/drivers/block/ahci.c
+++ b/linux/dev/drivers/block/ahci.c
@@ -514,6 +514,15 @@ static struct file_operations ahci_fops = {
.revalidate = NULL,
};
+/* Disk timed out while processing identify, interrupt ahci_probe_port */
+static void identify_timeout(unsigned long data)
+{
+ struct port *port = (void*) data;
+
+ wake_up(&port->q);
+}
+
+static struct timer_list identify_timer = { .function = identify_timeout };
/* Probe one AHCI port */
static void ahci_probe_port(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port)
@@ -671,15 +680,20 @@ static void ahci_probe_port(const volatile struct ahci_host *ahci_host, const vo
writel(1 << slot, &ahci_port->ci);
timeout = jiffies + WAIT_MAX;
+ identify_timer.expires = timeout;
+ identify_timer.data = (unsigned long) port;
+ add_timer(&identify_timer);
while (!port->status) {
- if (jiffies > timeout) {
+ if (jiffies >= timeout) {
printk("sd%u: timeout waiting for ready\n", port-ports);
port->ahci_host = NULL;
port->ahci_port = NULL;
+ del_timer(&identify_timer);
return;
}
sleep_on(&port->q);
}
+ del_timer(&identify_timer);
restore_flags(flags);
if (readl(&ahci_port->is) & PORT_IRQ_TF_ERR)