summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-04-17 16:44:06 +0200
committerJeff Garzik <jeff@garzik.org>2007-04-28 20:16:02 +0200
commit4911487a34baa89ec5b5f09a661761b73091fbec (patch)
treef79f6fa1a061cbbfcaac9a1581c7cf9600a82441 /drivers/ata
parentahci: add PCI ID for new VIA chip (diff)
downloadlinux-4911487a34baa89ec5b5f09a661761b73091fbec.tar.xz
linux-4911487a34baa89ec5b5f09a661761b73091fbec.zip
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>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f368387829ca..c831c9efee60 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5792,13 +5792,18 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
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 @@ static void ata_host_release(struct device *gendev, void *res)
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;
}