Skip to content

Commit fad16e7

Browse files
htejunJeff Garzik
authored andcommitted
ahci: fix module refcount breakage introduced by libahci split
libata depends on scsi_host_template for module reference counting and sht's should be owned by each low level driver. During libahci split, the sht was left with libahci.ko leaving the actual low level drivers not reference counted. This made ahci and ahci_platform always unloadable even while they're being actively used. Fix it by defining AHCI_SHT() macro in ahci.h and defining a sht for each low level ahci driver. stable: only applicable to 2.6.35. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Pedro Francisco <pedrogfrancisco@gmail.com> Tested-by: Michael Tokarev <mjt@tls.msk.ru> Cc: stable@kernel.org Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
1 parent 050026f commit fad16e7

File tree

4 files changed

+24
-14
lines changed

4 files changed

+24
-14
lines changed

drivers/ata/ahci.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
9090
static int ahci_pci_device_resume(struct pci_dev *pdev);
9191
#endif
9292

93+
static struct scsi_host_template ahci_sht = {
94+
AHCI_SHT("ahci"),
95+
};
96+
9397
static struct ata_port_operations ahci_vt8251_ops = {
9498
.inherits = &ahci_ops,
9599
.hardreset = ahci_vt8251_hardreset,

drivers/ata/ahci.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,17 @@ struct ahci_host_priv {
298298

299299
extern int ahci_ignore_sss;
300300

301-
extern struct scsi_host_template ahci_sht;
301+
extern struct device_attribute *ahci_shost_attrs[];
302+
extern struct device_attribute *ahci_sdev_attrs[];
303+
304+
#define AHCI_SHT(drv_name) \
305+
ATA_NCQ_SHT(drv_name), \
306+
.can_queue = AHCI_MAX_CMDS - 1, \
307+
.sg_tablesize = AHCI_MAX_SG, \
308+
.dma_boundary = AHCI_DMA_BOUNDARY, \
309+
.shost_attrs = ahci_shost_attrs, \
310+
.sdev_attrs = ahci_sdev_attrs
311+
302312
extern struct ata_port_operations ahci_ops;
303313

304314
void ahci_save_initial_config(struct device *dev,

drivers/ata/ahci_platform.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include <linux/ahci_platform.h>
2424
#include "ahci.h"
2525

26+
static struct scsi_host_template ahci_platform_sht = {
27+
AHCI_SHT("ahci_platform"),
28+
};
29+
2630
static int __init ahci_probe(struct platform_device *pdev)
2731
{
2832
struct device *dev = &pdev->dev;
@@ -145,7 +149,7 @@ static int __init ahci_probe(struct platform_device *pdev)
145149
ahci_print_info(host, "platform");
146150

147151
rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
148-
&ahci_sht);
152+
&ahci_platform_sht);
149153
if (rc)
150154
goto err0;
151155

drivers/ata/libahci.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
121121
static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
122122
ahci_read_em_buffer, ahci_store_em_buffer);
123123

124-
static struct device_attribute *ahci_shost_attrs[] = {
124+
struct device_attribute *ahci_shost_attrs[] = {
125125
&dev_attr_link_power_management_policy,
126126
&dev_attr_em_message_type,
127127
&dev_attr_em_message,
@@ -132,22 +132,14 @@ static struct device_attribute *ahci_shost_attrs[] = {
132132
&dev_attr_em_buffer,
133133
NULL
134134
};
135+
EXPORT_SYMBOL_GPL(ahci_shost_attrs);
135136

136-
static struct device_attribute *ahci_sdev_attrs[] = {
137+
struct device_attribute *ahci_sdev_attrs[] = {
137138
&dev_attr_sw_activity,
138139
&dev_attr_unload_heads,
139140
NULL
140141
};
141-
142-
struct scsi_host_template ahci_sht = {
143-
ATA_NCQ_SHT("ahci"),
144-
.can_queue = AHCI_MAX_CMDS - 1,
145-
.sg_tablesize = AHCI_MAX_SG,
146-
.dma_boundary = AHCI_DMA_BOUNDARY,
147-
.shost_attrs = ahci_shost_attrs,
148-
.sdev_attrs = ahci_sdev_attrs,
149-
};
150-
EXPORT_SYMBOL_GPL(ahci_sht);
142+
EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
151143

152144
struct ata_port_operations ahci_ops = {
153145
.inherits = &sata_pmp_port_ops,

0 commit comments

Comments
 (0)