diff options
author | Gwendal Grignou <gwendal@google.com> | 2010-05-25 12:31:38 -0700 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-10-21 20:21:03 -0400 |
commit | d9027470b88631d0956ac37cdadfdeb9cdcf2c99 (patch) | |
tree | b15273e88431ba734a24965dfc81132ac13bc8bd /drivers/ata/libata-core.c | |
parent | f6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff) |
[libata] Add ATA transport class
This is a scheleton for libata transport class.
All information is read only, exporting information from libata:
- ata_port class: one per ATA port
- ata_link class: one per ATA port or 15 for SATA Port Multiplier
- ata_device class: up to 2 for PATA link, usually one for SATA.
Signed-off-by: Gwendal Grignou <gwendal@google.com>
Reviewed-by: Grant Grundler <grundler@google.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 932eaee50245..4012b33e8b8a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -68,7 +68,7 @@ #include <linux/ratelimit.h> #include "libata.h" - +#include "libata-transport.h" /* debounce timing parameters in msecs { interval, duration, timeout } */ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; @@ -1017,7 +1017,7 @@ const char *ata_mode_string(unsigned long xfer_mask) return "<n/a>"; } -static const char *sata_spd_string(unsigned int spd) +const char *sata_spd_string(unsigned int spd) { static const char * const spd_str[] = { "1.5 Gbps", @@ -5517,7 +5517,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp) int i; /* clear everything except for devices */ - memset(link, 0, offsetof(struct ata_link, device[0])); + memset((void *)link + ATA_LINK_CLEAR_BEGIN, 0, + ATA_LINK_CLEAR_END - ATA_LINK_CLEAR_BEGIN); link->ap = ap; link->pmp = pmp; @@ -5591,7 +5592,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap = kzalloc(sizeof(*ap), GFP_KERNEL); if (!ap) return NULL; - + ap->pflags |= ATA_PFLAG_INITIALIZING; ap->lock = &host->lock; ap->print_id = -1; @@ -6093,9 +6094,18 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) for (i = 0; i < host->n_ports; i++) host->ports[i]->print_id = ata_print_id++; + + /* Create associated sysfs transport objects */ + for (i = 0; i < host->n_ports; i++) { + rc = ata_tport_add(host->dev,host->ports[i]); + if (rc) { + goto err_tadd; + } + } + rc = ata_scsi_add_hosts(host, sht); if (rc) - return rc; + goto err_tadd; /* associate with ACPI nodes */ ata_acpi_associate(host); @@ -6136,6 +6146,13 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) } return 0; + + err_tadd: + while (--i >= 0) { + ata_tport_delete(host->ports[i]); + } + return rc; + } /** @@ -6226,6 +6243,13 @@ static void ata_port_detach(struct ata_port *ap) cancel_rearming_delayed_work(&ap->hotplug_task); skip_eh: + if (ap->pmp_link) { + int i; + for (i = 0; i < SATA_PMP_MAX_PORTS; i++) + ata_tlink_delete(&ap->pmp_link[i]); + } + ata_tport_delete(ap); + /* remove the associated SCSI host */ scsi_remove_host(ap->scsi_host); } @@ -6542,7 +6566,7 @@ static void __init ata_parse_force_param(void) static int __init ata_init(void) { - int rc = -ENOMEM; + int rc; ata_parse_force_param(); @@ -6552,12 +6576,25 @@ static int __init ata_init(void) return rc; } + libata_transport_init(); + ata_scsi_transport_template = ata_attach_transport(); + if (!ata_scsi_transport_template) { + ata_sff_exit(); + rc = -ENOMEM; + goto err_out; + } + printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); return 0; + +err_out: + return rc; } static void __exit ata_exit(void) { + ata_release_transport(ata_scsi_transport_template); + libata_transport_exit(); ata_sff_exit(); kfree(ata_force_tbl); } |