|
@@ -2472,6 +2472,67 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ahci_set_em_messages);
|
|
EXPORT_SYMBOL_GPL(ahci_set_em_messages);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * ahci_host_activate - start AHCI host, request IRQs and register it
|
|
|
|
+ * @host: target ATA host
|
|
|
|
+ * @irq: base IRQ number to request
|
|
|
|
+ * @sht: scsi_host_template to use when registering the host
|
|
|
|
+ *
|
|
|
|
+ * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
|
|
|
|
+ * when multiple MSIs were allocated. That is one MSI per port, starting
|
|
|
|
+ * from @irq.
|
|
|
|
+ *
|
|
|
|
+ * LOCKING:
|
|
|
|
+ * Inherited from calling layer (may sleep).
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success, -errno otherwise.
|
|
|
|
+ */
|
|
|
|
+int ahci_host_activate(struct ata_host *host, int irq,
|
|
|
|
+ struct scsi_host_template *sht)
|
|
|
|
+{
|
|
|
|
+ int i, rc;
|
|
|
|
+
|
|
|
|
+ rc = ata_host_start(host);
|
|
|
|
+ if (rc)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < host->n_ports; i++) {
|
|
|
|
+ struct ahci_port_priv *pp = host->ports[i]->private_data;
|
|
|
|
+
|
|
|
|
+ /* Do not receive interrupts sent by dummy ports */
|
|
|
|
+ if (!pp) {
|
|
|
|
+ disable_irq(irq + i);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rc = devm_request_threaded_irq(host->dev, irq + i,
|
|
|
|
+ ahci_hw_interrupt,
|
|
|
|
+ ahci_thread_fn, IRQF_SHARED,
|
|
|
|
+ pp->irq_desc, host->ports[i]);
|
|
|
|
+ if (rc)
|
|
|
|
+ goto out_free_irqs;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < host->n_ports; i++)
|
|
|
|
+ ata_port_desc(host->ports[i], "irq %d", irq + i);
|
|
|
|
+
|
|
|
|
+ rc = ata_host_register(host, sht);
|
|
|
|
+ if (rc)
|
|
|
|
+ goto out_free_all_irqs;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+out_free_all_irqs:
|
|
|
|
+ i = host->n_ports;
|
|
|
|
+out_free_irqs:
|
|
|
|
+ for (i--; i >= 0; i--)
|
|
|
|
+ devm_free_irq(host->dev, irq + i, host->ports[i]);
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL_GPL(ahci_host_activate);
|
|
|
|
+
|
|
MODULE_AUTHOR("Jeff Garzik");
|
|
MODULE_AUTHOR("Jeff Garzik");
|
|
MODULE_DESCRIPTION("Common AHCI SATA low-level routines");
|
|
MODULE_DESCRIPTION("Common AHCI SATA low-level routines");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_LICENSE("GPL");
|