From: Tejun Heo Date: Tue, 17 Apr 2007 14:44:06 +0000 (+0900) Subject: libata: allocate ap separately from shost X-Git-Tag: v2.6.22-rc1~1111^2~23 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4911487a34baa89ec5b5f09a661761b73091fbec;p=linux-2.6 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 Signed-off-by: Jeff Garzik --- diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f368387829..c831c9efee 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; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 12237d4b9f..ced9dd5403 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1231,7 +1231,7 @@ static inline void ata_pad_free(struct ata_port *ap, struct device *dev) 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__ */