aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c113
1 files changed, 111 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 394edf937cf2..32fa9ee397b6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -74,6 +74,56 @@ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
74const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; 74const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
75const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; 75const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
76 76
77const struct ata_port_operations ata_base_port_ops = {
78 .irq_clear = ata_noop_irq_clear,
79};
80
81const struct ata_port_operations sata_port_ops = {
82 .inherits = &ata_base_port_ops,
83
84 .qc_defer = ata_std_qc_defer,
85 .dev_select = ata_noop_dev_select,
86};
87
88const struct ata_port_operations sata_pmp_port_ops = {
89 .inherits = &sata_port_ops,
90};
91
92const struct ata_port_operations ata_sff_port_ops = {
93 .inherits = &ata_base_port_ops,
94
95 .qc_prep = ata_qc_prep,
96 .qc_issue = ata_qc_issue_prot,
97
98 .freeze = ata_bmdma_freeze,
99 .thaw = ata_bmdma_thaw,
100 .error_handler = ata_bmdma_error_handler,
101 .post_internal_cmd = ata_bmdma_post_internal_cmd,
102
103 .dev_select = ata_std_dev_select,
104 .check_status = ata_check_status,
105 .tf_load = ata_tf_load,
106 .tf_read = ata_tf_read,
107 .exec_command = ata_exec_command,
108 .data_xfer = ata_data_xfer,
109 .irq_on = ata_irq_on,
110
111 .port_start = ata_sff_port_start,
112 .irq_handler = ata_interrupt,
113};
114
115const struct ata_port_operations ata_bmdma_port_ops = {
116 .inherits = &ata_sff_port_ops,
117
118 .mode_filter = ata_pci_default_filter,
119
120 .bmdma_setup = ata_bmdma_setup,
121 .bmdma_start = ata_bmdma_start,
122 .bmdma_stop = ata_bmdma_stop,
123 .bmdma_status = ata_bmdma_status,
124 .irq_clear = ata_bmdma_irq_clear,
125};
126
77static unsigned int ata_dev_init_params(struct ata_device *dev, 127static unsigned int ata_dev_init_params(struct ata_device *dev,
78 u16 heads, u16 sectors); 128 u16 heads, u16 sectors);
79static unsigned int ata_dev_set_xfermode(struct ata_device *dev); 129static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
@@ -6972,6 +7022,56 @@ static void ata_host_stop(struct device *gendev, void *res)
6972} 7022}
6973 7023
6974/** 7024/**
7025 * ata_finalize_port_ops - finalize ata_port_operations
7026 * @ops: ata_port_operations to finalize
7027 *
7028 * An ata_port_operations can inherit from another ops and that
7029 * ops can again inherit from another. This can go on as many
7030 * times as necessary as long as there is no loop in the
7031 * inheritance chain.
7032 *
7033 * Ops tables are finalized when the host is started. NULL or
7034 * unspecified entries are inherited from the closet ancestor
7035 * which has the method and the entry is populated with it.
7036 * After finalization, the ops table directly points to all the
7037 * methods and ->inherits is no longer necessary and cleared.
7038 *
7039 * Using ATA_OP_NULL, inheriting ops can force a method to NULL.
7040 *
7041 * LOCKING:
7042 * None.
7043 */
7044static void ata_finalize_port_ops(struct ata_port_operations *ops)
7045{
7046 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
7047 const struct ata_port_operations *cur;
7048 void **begin = (void **)ops;
7049 void **end = (void **)&ops->inherits;
7050 void **pp;
7051
7052 if (!ops || !ops->inherits)
7053 return;
7054
7055 spin_lock(&lock);
7056
7057 for (cur = ops->inherits; cur; cur = cur->inherits) {
7058 void **inherit = (void **)cur;
7059
7060 for (pp = begin; pp < end; pp++, inherit++)
7061 if (!*pp)
7062 *pp = *inherit;
7063 }
7064
7065 for (pp = begin; pp < end; pp++)
7066 if (IS_ERR(*pp))
7067 *pp = NULL;
7068
7069 ops->inherits = NULL;
7070
7071 spin_unlock(&lock);
7072}
7073
7074/**
6975 * ata_host_start - start and freeze ports of an ATA host 7075 * ata_host_start - start and freeze ports of an ATA host
6976 * @host: ATA host to start ports for 7076 * @host: ATA host to start ports for
6977 * 7077 *
@@ -6996,9 +7096,13 @@ int ata_host_start(struct ata_host *host)
6996 if (host->flags & ATA_HOST_STARTED) 7096 if (host->flags & ATA_HOST_STARTED)
6997 return 0; 7097 return 0;
6998 7098
7099 ata_finalize_port_ops(host->ops);
7100
6999 for (i = 0; i < host->n_ports; i++) { 7101 for (i = 0; i < host->n_ports; i++) {
7000 struct ata_port *ap = host->ports[i]; 7102 struct ata_port *ap = host->ports[i];
7001 7103
7104 ata_finalize_port_ops(ap->ops);
7105
7002 if (!host->ops && !ata_port_is_dummy(ap)) 7106 if (!host->ops && !ata_port_is_dummy(ap))
7003 host->ops = ap->ops; 7107 host->ops = ap->ops;
7004 7108
@@ -7060,7 +7164,7 @@ int ata_host_start(struct ata_host *host)
7060 */ 7164 */
7061/* KILLME - the only user left is ipr */ 7165/* KILLME - the only user left is ipr */
7062void ata_host_init(struct ata_host *host, struct device *dev, 7166void ata_host_init(struct ata_host *host, struct device *dev,
7063 unsigned long flags, const struct ata_port_operations *ops) 7167 unsigned long flags, struct ata_port_operations *ops)
7064{ 7168{
7065 spin_lock_init(&host->lock); 7169 spin_lock_init(&host->lock);
7066 host->dev = dev; 7170 host->dev = dev;
@@ -7749,7 +7853,7 @@ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
7749 return AC_ERR_SYSTEM; 7853 return AC_ERR_SYSTEM;
7750} 7854}
7751 7855
7752const struct ata_port_operations ata_dummy_port_ops = { 7856struct ata_port_operations ata_dummy_port_ops = {
7753 .check_status = ata_dummy_check_status, 7857 .check_status = ata_dummy_check_status,
7754 .check_altstatus = ata_dummy_check_status, 7858 .check_altstatus = ata_dummy_check_status,
7755 .dev_select = ata_noop_dev_select, 7859 .dev_select = ata_noop_dev_select,
@@ -7777,6 +7881,11 @@ const struct ata_port_info ata_dummy_port_info = {
7777EXPORT_SYMBOL_GPL(sata_deb_timing_normal); 7881EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
7778EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); 7882EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
7779EXPORT_SYMBOL_GPL(sata_deb_timing_long); 7883EXPORT_SYMBOL_GPL(sata_deb_timing_long);
7884EXPORT_SYMBOL_GPL(ata_base_port_ops);
7885EXPORT_SYMBOL_GPL(sata_port_ops);
7886EXPORT_SYMBOL_GPL(sata_pmp_port_ops);
7887EXPORT_SYMBOL_GPL(ata_sff_port_ops);
7888EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
7780EXPORT_SYMBOL_GPL(ata_dummy_port_ops); 7889EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
7781EXPORT_SYMBOL_GPL(ata_dummy_port_info); 7890EXPORT_SYMBOL_GPL(ata_dummy_port_info);
7782EXPORT_SYMBOL_GPL(ata_std_bios_param); 7891EXPORT_SYMBOL_GPL(ata_std_bios_param);