aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2007-11-05 11:43:31 -0500
committerLen Brown <len.brown@intel.com>2007-11-14 12:14:28 -0500
commitff102ea99099c36250e93a87a9794b5233801020 (patch)
tree19cf2ac073458b8337e9514589ad2c284407f50b /drivers/acpi/video.c
parentf51e83916a0a022d3d0ea39ae2f877c703032923 (diff)
ACPI: video - remove unsafe uses of list_for_each_safe()
list_for_each_safe() only protects list from list alterations performed by the same thread. One still needs to implement proper locking when list is being accessed from several threads. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Acked-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c71
1 files changed, 34 insertions, 37 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index be66a7c04d38..36b64a751676 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1462,12 +1462,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1462 1462
1463static void acpi_video_device_rebind(struct acpi_video_bus *video) 1463static void acpi_video_device_rebind(struct acpi_video_bus *video)
1464{ 1464{
1465 struct list_head *node, *next; 1465 struct acpi_video_device *dev;
1466 list_for_each_safe(node, next, &video->video_device_list) { 1466
1467 struct acpi_video_device *dev = 1467 down(&video->sem);
1468 container_of(node, struct acpi_video_device, entry); 1468
1469 list_for_each_entry(dev, &video->video_device_list, entry)
1469 acpi_video_device_bind(video, dev); 1470 acpi_video_device_bind(video, dev);
1470 } 1471
1472 up(&video->sem);
1471} 1473}
1472 1474
1473/* 1475/*
@@ -1592,30 +1594,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1592 1594
1593static int acpi_video_switch_output(struct acpi_video_bus *video, int event) 1595static int acpi_video_switch_output(struct acpi_video_bus *video, int event)
1594{ 1596{
1595 struct list_head *node, *next; 1597 struct list_head *node;
1596 struct acpi_video_device *dev = NULL; 1598 struct acpi_video_device *dev = NULL;
1597 struct acpi_video_device *dev_next = NULL; 1599 struct acpi_video_device *dev_next = NULL;
1598 struct acpi_video_device *dev_prev = NULL; 1600 struct acpi_video_device *dev_prev = NULL;
1599 unsigned long state; 1601 unsigned long state;
1600 int status = 0; 1602 int status = 0;
1601 1603
1604 down(&video->sem);
1602 1605
1603 list_for_each_safe(node, next, &video->video_device_list) { 1606 list_for_each(node, &video->video_device_list) {
1604 dev = container_of(node, struct acpi_video_device, entry); 1607 dev = container_of(node, struct acpi_video_device, entry);
1605 status = acpi_video_device_get_state(dev, &state); 1608 status = acpi_video_device_get_state(dev, &state);
1606 if (state & 0x2) { 1609 if (state & 0x2) {
1607 dev_next = 1610 dev_next = container_of(node->next,
1608 container_of(node->next, struct acpi_video_device, 1611 struct acpi_video_device, entry);
1609 entry); 1612 dev_prev = container_of(node->prev,
1610 dev_prev = 1613 struct acpi_video_device, entry);
1611 container_of(node->prev, struct acpi_video_device,
1612 entry);
1613 goto out; 1614 goto out;
1614 } 1615 }
1615 } 1616 }
1617
1616 dev_next = container_of(node->next, struct acpi_video_device, entry); 1618 dev_next = container_of(node->next, struct acpi_video_device, entry);
1617 dev_prev = container_of(node->prev, struct acpi_video_device, entry); 1619 dev_prev = container_of(node->prev, struct acpi_video_device, entry);
1618 out: 1620
1621 out:
1622 up(&video->sem);
1623
1619 switch (event) { 1624 switch (event) {
1620 case ACPI_VIDEO_NOTIFY_CYCLE: 1625 case ACPI_VIDEO_NOTIFY_CYCLE:
1621 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: 1626 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
@@ -1691,24 +1696,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
1691 struct acpi_device *device) 1696 struct acpi_device *device)
1692{ 1697{
1693 int status = 0; 1698 int status = 0;
1694 struct list_head *node, *next; 1699 struct acpi_device *dev;
1695
1696 1700
1697 acpi_video_device_enumerate(video); 1701 acpi_video_device_enumerate(video);
1698 1702
1699 list_for_each_safe(node, next, &device->children) { 1703 list_for_each_entry(dev, &device->children, node) {
1700 struct acpi_device *dev =
1701 list_entry(node, struct acpi_device, node);
1702
1703 if (!dev)
1704 continue;
1705 1704
1706 status = acpi_video_bus_get_one_device(dev, video); 1705 status = acpi_video_bus_get_one_device(dev, video);
1707 if (ACPI_FAILURE(status)) { 1706 if (ACPI_FAILURE(status)) {
1708 ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); 1707 ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
1709 continue; 1708 continue;
1710 } 1709 }
1711
1712 } 1710 }
1713 return status; 1711 return status;
1714} 1712}
@@ -1724,9 +1722,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1724 1722
1725 video = device->video; 1723 video = device->video;
1726 1724
1727 down(&video->sem);
1728 list_del(&device->entry);
1729 up(&video->sem);
1730 acpi_video_device_remove_fs(device->dev); 1725 acpi_video_device_remove_fs(device->dev);
1731 1726
1732 status = acpi_remove_notify_handler(device->dev->handle, 1727 status = acpi_remove_notify_handler(device->dev->handle,
@@ -1734,32 +1729,34 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1734 acpi_video_device_notify); 1729 acpi_video_device_notify);
1735 backlight_device_unregister(device->backlight); 1730 backlight_device_unregister(device->backlight);
1736 video_output_unregister(device->output_dev); 1731 video_output_unregister(device->output_dev);
1732
1737 return 0; 1733 return 0;
1738} 1734}
1739 1735
1740static int acpi_video_bus_put_devices(struct acpi_video_bus *video) 1736static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1741{ 1737{
1742 int status; 1738 int status;
1743 struct list_head *node, *next; 1739 struct acpi_video_device *dev, *next;
1744 1740
1741 down(&video->sem);
1745 1742
1746 list_for_each_safe(node, next, &video->video_device_list) { 1743 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1747 struct acpi_video_device *data =
1748 list_entry(node, struct acpi_video_device, entry);
1749 if (!data)
1750 continue;
1751 1744
1752 status = acpi_video_bus_put_one_device(data); 1745 status = acpi_video_bus_put_one_device(dev);
1753 if (ACPI_FAILURE(status)) 1746 if (ACPI_FAILURE(status))
1754 printk(KERN_WARNING PREFIX 1747 printk(KERN_WARNING PREFIX
1755 "hhuuhhuu bug in acpi video driver.\n"); 1748 "hhuuhhuu bug in acpi video driver.\n");
1756 1749
1757 if (data->brightness) 1750 if (dev->brightness) {
1758 kfree(data->brightness->levels); 1751 kfree(dev->brightness->levels);
1759 kfree(data->brightness); 1752 kfree(dev->brightness);
1760 kfree(data); 1753 }
1754 list_del(&dev->entry);
1755 kfree(dev);
1761 } 1756 }
1762 1757
1758 up(&video->sem);
1759
1763 return 0; 1760 return 0;
1764} 1761}
1765 1762