libata: allocate ap separately from shost

Don't embed ap inside shost.  Allocate it separately and point it back
from shosts's hostdata.  This makes port allocation more flexible and
allows regular ATA and SAS share host alloc/init paths.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f368387..c831c9e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5792,13 +5792,18 @@
 		return NULL;
 	}
 
-	shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
-	if (!shost)
+	ap = kzalloc(sizeof(struct ata_port), GFP_KERNEL);
+	if (!ap)
 		return NULL;
 
-	shost->transportt = &ata_scsi_transport_template;
+	shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port *));
+	if (!shost) {
+		kfree(ap);
+		return NULL;
+	}
 
-	ap = ata_shost_to_port(shost);
+	*(struct ata_port **)&shost->hostdata[0] = ap;
+	shost->transportt = &ata_scsi_transport_template;
 
 	ata_port_init(ap, host, ent, port_no);
 	ata_port_init_shost(ap, shost);
@@ -5824,9 +5829,13 @@
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		if (ap)
+		if (!ap)
+			continue;
+
+		if (ap->scsi_host)
 			scsi_host_put(ap->scsi_host);
 
+		kfree(ap);
 		host->ports[i] = NULL;
 	}
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 12237d4..ced9dd5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1231,7 +1231,7 @@
 
 static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
 {
-	return (struct ata_port *) &host->hostdata[0];
+	return *(struct ata_port **)&host->hostdata[0];
 }
 
 #endif /* __LINUX_LIBATA_H__ */