From 9472316b6eab3500ded544f6e86700c33541ef4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
Date: Wed, 14 Mar 2007 17:34:55 -0400
Subject: [PATCH] firewire: Implement deallocation of address ranges.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
 drivers/firewire/fw-device-cdev.c | 28 ++++++++++++++++++++++++++++
 drivers/firewire/fw-device-cdev.h | 17 +++++++++++------
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/firewire/fw-device-cdev.c b/drivers/firewire/fw-device-cdev.c
index 175ea042ba3f..ebf0d100805e 100644
--- a/drivers/firewire/fw-device-cdev.c
+++ b/drivers/firewire/fw-device-cdev.c
@@ -467,6 +467,32 @@ static int ioctl_allocate(struct client *client, void __user *arg)
 	return 0;
 }
 
+static int ioctl_deallocate(struct client *client, void __user *arg)
+{
+	struct fw_cdev_deallocate request;
+	struct address_handler *handler;
+	unsigned long flags;
+
+	if (copy_from_user(&request, arg, sizeof request))
+		return -EFAULT;
+
+	spin_lock_irqsave(&client->lock, flags);
+	list_for_each_entry(handler, &client->handler_list, link) {
+		if (handler->handler.offset == request.offset) {
+			list_del(&handler->link);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&client->lock, flags);
+
+	if (&handler->link == &client->handler_list)
+		return -EINVAL;
+
+	fw_core_remove_address_handler(&handler->handler);
+
+	return 0;
+}
+
 static int ioctl_send_response(struct client *client, void __user *arg)
 {
 	struct fw_cdev_send_response request;
@@ -696,6 +722,8 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
 		return ioctl_send_request(client, arg);
 	case FW_CDEV_IOC_ALLOCATE:
 		return ioctl_allocate(client, arg);
+	case FW_CDEV_IOC_DEALLOCATE:
+		return ioctl_deallocate(client, arg);
 	case FW_CDEV_IOC_SEND_RESPONSE:
 		return ioctl_send_response(client, arg);
 	case FW_CDEV_IOC_INITIATE_BUS_RESET:
diff --git a/drivers/firewire/fw-device-cdev.h b/drivers/firewire/fw-device-cdev.h
index 3437a360d7dc..10b83222db69 100644
--- a/drivers/firewire/fw-device-cdev.h
+++ b/drivers/firewire/fw-device-cdev.h
@@ -113,12 +113,13 @@ struct fw_cdev_event_iso_interrupt {
 #define FW_CDEV_IOC_GET_INFO		_IO('#', 0x00)
 #define FW_CDEV_IOC_SEND_REQUEST	_IO('#', 0x01)
 #define FW_CDEV_IOC_ALLOCATE		_IO('#', 0x02)
-#define FW_CDEV_IOC_SEND_RESPONSE	_IO('#', 0x03)
-#define FW_CDEV_IOC_INITIATE_BUS_RESET	_IO('#', 0x04)
-#define FW_CDEV_IOC_CREATE_ISO_CONTEXT	_IO('#', 0x05)
-#define FW_CDEV_IOC_QUEUE_ISO		_IO('#', 0x06)
-#define FW_CDEV_IOC_START_ISO		_IO('#', 0x07)
-#define FW_CDEV_IOC_STOP_ISO		_IO('#', 0x08)
+#define FW_CDEV_IOC_DEALLOCATE		_IO('#', 0x03)
+#define FW_CDEV_IOC_SEND_RESPONSE	_IO('#', 0x04)
+#define FW_CDEV_IOC_INITIATE_BUS_RESET	_IO('#', 0x05)
+#define FW_CDEV_IOC_CREATE_ISO_CONTEXT	_IO('#', 0x06)
+#define FW_CDEV_IOC_QUEUE_ISO		_IO('#', 0x07)
+#define FW_CDEV_IOC_START_ISO		_IO('#', 0x08)
+#define FW_CDEV_IOC_STOP_ISO		_IO('#', 0x09)
 
 /* FW_CDEV_VERSION History
  *
@@ -173,6 +174,10 @@ struct fw_cdev_allocate {
 	__u32 length;
 };
 
+struct fw_cdev_deallocate {
+	__u64 offset;
+};
+
 #define FW_CDEV_LONG_RESET	0
 #define FW_CDEV_SHORT_RESET	1
 
-- 
GitLab