Commit d85fc67d authored by Gwendal Grignou's avatar Gwendal Grignou Committed by Tejun Heo

libata: transport: Remove circular dependency at free time

Without this patch, failed probe would not free resources like irq.

ata port tdev object currently hold a reference to the ata port
object.  Therefore the ata port object release function will not get
called until the ata_tport_release is called. But that would never
happen, releasing the last reference of ata port dev is done by
scsi_host_release, which is called by ata_host_release when the ata
port object is released.

The ata device objects actually do not need to explicitly hold a
reference to their real counterpart, given the transport objects are
the children of these objects and device_add() is call for each child.
We know the parent will not be deleted until we call the child's
device_del().
Reported-by: default avatarMatthew Whitehead <tedheadster@gmail.com>
Tested-by: default avatarMatthew Whitehead <tedheadster@gmail.com>
Suggested-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarGwendal Grignou <gwendal@chromium.org>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent c1ae3cfa
...@@ -224,7 +224,6 @@ static DECLARE_TRANSPORT_CLASS(ata_port_class, ...@@ -224,7 +224,6 @@ static DECLARE_TRANSPORT_CLASS(ata_port_class,
static void ata_tport_release(struct device *dev) static void ata_tport_release(struct device *dev)
{ {
put_device(dev->parent);
} }
/** /**
...@@ -284,7 +283,7 @@ int ata_tport_add(struct device *parent, ...@@ -284,7 +283,7 @@ int ata_tport_add(struct device *parent,
device_initialize(dev); device_initialize(dev);
dev->type = &ata_port_type; dev->type = &ata_port_type;
dev->parent = get_device(parent); dev->parent = parent;
dev->release = ata_tport_release; dev->release = ata_tport_release;
dev_set_name(dev, "ata%d", ap->print_id); dev_set_name(dev, "ata%d", ap->print_id);
transport_setup_device(dev); transport_setup_device(dev);
...@@ -348,7 +347,6 @@ static DECLARE_TRANSPORT_CLASS(ata_link_class, ...@@ -348,7 +347,6 @@ static DECLARE_TRANSPORT_CLASS(ata_link_class,
static void ata_tlink_release(struct device *dev) static void ata_tlink_release(struct device *dev)
{ {
put_device(dev->parent);
} }
/** /**
...@@ -410,7 +408,7 @@ int ata_tlink_add(struct ata_link *link) ...@@ -410,7 +408,7 @@ int ata_tlink_add(struct ata_link *link)
int error; int error;
device_initialize(dev); device_initialize(dev);
dev->parent = get_device(&ap->tdev); dev->parent = &ap->tdev;
dev->release = ata_tlink_release; dev->release = ata_tlink_release;
if (ata_is_host_link(link)) if (ata_is_host_link(link))
dev_set_name(dev, "link%d", ap->print_id); dev_set_name(dev, "link%d", ap->print_id);
...@@ -589,7 +587,6 @@ static DECLARE_TRANSPORT_CLASS(ata_dev_class, ...@@ -589,7 +587,6 @@ static DECLARE_TRANSPORT_CLASS(ata_dev_class,
static void ata_tdev_release(struct device *dev) static void ata_tdev_release(struct device *dev)
{ {
put_device(dev->parent);
} }
/** /**
...@@ -662,7 +659,7 @@ static int ata_tdev_add(struct ata_device *ata_dev) ...@@ -662,7 +659,7 @@ static int ata_tdev_add(struct ata_device *ata_dev)
int error; int error;
device_initialize(dev); device_initialize(dev);
dev->parent = get_device(&link->tdev); dev->parent = &link->tdev;
dev->release = ata_tdev_release; dev->release = ata_tdev_release;
if (ata_is_host_link(link)) if (ata_is_host_link(link))
dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno); dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment