]> err.no Git - linux-2.6/commitdiff
libata: allocate ap separately from shost
authorTejun Heo <htejun@gmail.com>
Tue, 17 Apr 2007 14:44:06 +0000 (23:44 +0900)
committerJeff Garzik <jeff@garzik.org>
Sat, 28 Apr 2007 18:16:02 +0000 (14:16 -0400)
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>
drivers/ata/libata-core.c
include/linux/libata.h

index f368387829caf9232b39f116bfe311f20b077968..c831c9efee607c7f285002fe1b35739f44dad5cb 100644 (file)
@@ -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;
        }
 
index 12237d4b9f9b6705675c69e0ada2265701cbce62..ced9dd54035e3b90bb9b97c7bdb2095d1e55d867 100644 (file)
@@ -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__ */