+/**
+ * ata_host_start - start and freeze ports of an ATA host
+ * @host: ATA host to start ports for
+ *
+ * Start and then freeze ports of @host. Started status is
+ * recorded in host->flags, so this function can be called
+ * multiple times. Ports are guaranteed to get started only
+ * once.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 if all ports are started successfully, -errno otherwise.
+ */
+int ata_host_start(struct ata_host *host)
+{
+ int i, rc;
+
+ if (host->flags & ATA_HOST_STARTED)
+ return 0;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->ops->port_start) {
+ rc = ap->ops->port_start(ap);
+ if (rc) {
+ ata_port_printk(ap, KERN_ERR, "failed to "
+ "start port (errno=%d)\n", rc);
+ goto err_out;
+ }
+ }
+
+ ata_eh_freeze_port(ap);
+ }
+
+ host->flags |= ATA_HOST_STARTED;
+ return 0;
+
+ err_out:
+ while (--i >= 0) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+ }
+ return rc;
+}
+