All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] compat: miscellaneous updates for compat
@ 2010-08-07 13:32 Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 1/4] compat: backport n_tty_ioctl_helper Hauke Mehrtens
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 13:32 UTC (permalink / raw)
  To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens

This series contains miscellaneous updates for compat. They are compile
tested with kernel 2.6.26 to 2.6.35. ath9k and b43 were tested with
kernel 2.6.32.

Hauke Mehrtens (4):
  compat: backport n_tty_ioctl_helper
  compat: move va_format to compat-2.6.36.h
  compat: fix compiler warning
  compat: update compat_firmware_class.c

 compat/compat-2.6.28.c         |  128 ++++++++++++++++++
 compat/compat_firmware_class.c |  290 ++++++++++++++++++++-------------------
 include/linux/compat-2.6.27.h  |    2 +
 include/linux/compat-2.6.28.h  |    6 +
 include/linux/compat-2.6.35.h  |    5 -
 include/linux/compat-2.6.36.h  |    5 +
 6 files changed, 290 insertions(+), 146 deletions(-)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] compat: backport n_tty_ioctl_helper
  2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
@ 2010-08-07 13:32 ` Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 2/4] compat: move va_format to compat-2.6.36.h Hauke Mehrtens
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 13:32 UTC (permalink / raw)
  To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens

This function is needed by some bluetooth drivers

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 compat/compat-2.6.28.c        |  128 +++++++++++++++++++++++++++++++++++++++++
 include/linux/compat-2.6.28.h |    6 ++
 2 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/compat/compat-2.6.28.c b/compat/compat-2.6.28.c
index 115bd23..bfb645a 100644
--- a/compat/compat-2.6.28.c
+++ b/compat/compat-2.6.28.c
@@ -13,6 +13,8 @@
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28))
 
 #include <linux/usb.h>
+#include <linux/tty.h>
+#include <asm/poll.h>
 
 /* 2.6.28 compat code goes here */
 
@@ -370,4 +372,130 @@ void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
 }
 EXPORT_SYMBOL(skb_add_rx_frag);
 
+void tty_write_unlock(struct tty_struct *tty)
+{
+	mutex_unlock(&tty->atomic_write_lock);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+}
+
+int tty_write_lock(struct tty_struct *tty, int ndelay)
+{
+	if (!mutex_trylock(&tty->atomic_write_lock)) {
+		if (ndelay)
+			return -EAGAIN;
+		if (mutex_lock_interruptible(&tty->atomic_write_lock))
+			return -ERESTARTSYS;
+	}
+	return 0;
+}
+
+/**
+ *	send_prio_char		-	send priority character
+ *
+ *	Send a high priority character to the tty even if stopped
+ *
+ *	Locking: none for xchar method, write ordering for write method.
+ */
+
+static int send_prio_char(struct tty_struct *tty, char ch)
+{
+	int	was_stopped = tty->stopped;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+	if (tty->ops->send_xchar) {
+		tty->ops->send_xchar(tty, ch);
+#else
+	if (tty->driver->send_xchar) {
+		tty->driver->send_xchar(tty, ch);
+#endif
+		return 0;
+	}
+
+	if (tty_write_lock(tty, 0) < 0)
+		return -ERESTARTSYS;
+
+	if (was_stopped)
+		start_tty(tty);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+	tty->ops->write(tty, &ch, 1);
+#else
+	tty->driver->write(tty, &ch, 1);
+#endif
+	if (was_stopped)
+		stop_tty(tty);
+	tty_write_unlock(tty);
+	return 0;
+}
+
+int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
+		       unsigned int cmd, unsigned long arg)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+	unsigned long flags;
+#endif
+	int retval;
+
+	switch (cmd) {
+	case TCXONC:
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		switch (arg) {
+		case TCOOFF:
+			if (!tty->flow_stopped) {
+				tty->flow_stopped = 1;
+				stop_tty(tty);
+			}
+			break;
+		case TCOON:
+			if (tty->flow_stopped) {
+				tty->flow_stopped = 0;
+				start_tty(tty);
+			}
+			break;
+		case TCIOFF:
+			if (STOP_CHAR(tty) != __DISABLED_CHAR)
+				return send_prio_char(tty, STOP_CHAR(tty));
+			break;
+		case TCION:
+			if (START_CHAR(tty) != __DISABLED_CHAR)
+				return send_prio_char(tty, START_CHAR(tty));
+			break;
+		default:
+			return -EINVAL;
+		}
+		return 0;
+	case TCFLSH:
+		return tty_perform_flush(tty, arg);
+	case TIOCPKT:
+	{
+		int pktmode;
+
+		if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
+		    tty->driver->subtype != PTY_TYPE_MASTER)
+			return -ENOTTY;
+		if (get_user(pktmode, (int __user *) arg))
+			return -EFAULT;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+		spin_lock_irqsave(&tty->ctrl_lock, flags);
+#endif
+		if (pktmode) {
+			if (!tty->packet) {
+				tty->packet = 1;
+				tty->link->ctrl_status = 0;
+			}
+		} else
+			tty->packet = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+#endif
+		return 0;
+	}
+	default:
+		/* Try the mode commands */
+		return tty_mode_ioctl(tty, file, cmd, arg);
+	}
+}
+EXPORT_SYMBOL(n_tty_ioctl_helper);
+
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */
diff --git a/include/linux/compat-2.6.28.h b/include/linux/compat-2.6.28.h
index 7160548..649fbbc 100644
--- a/include/linux/compat-2.6.28.h
+++ b/include/linux/compat-2.6.28.h
@@ -230,6 +230,12 @@ unsigned long round_jiffies_up(unsigned long j);
 extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
 			    int off, int size);
 
+#define wake_up_interruptible_poll(x, m)			\
+	__wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m))
+
+extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
+		       unsigned int cmd, unsigned long arg);
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) */
 
 #endif /* LINUX_26_28_COMPAT_H */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] compat: move va_format to compat-2.6.36.h
  2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 1/4] compat: backport n_tty_ioctl_helper Hauke Mehrtens
@ 2010-08-07 13:32 ` Hauke Mehrtens
  2010-08-07 15:50   ` Johannes Berg
  2010-08-07 13:32 ` [PATCH 3/4] compat: fix compiler warning Hauke Mehrtens
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 13:32 UTC (permalink / raw)
  To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens

This struct was introduced in kernel 2.6.36 and not 2.6.35.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 include/linux/compat-2.6.35.h |    5 -----
 include/linux/compat-2.6.36.h |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/compat-2.6.35.h b/include/linux/compat-2.6.35.h
index d2e82cc..f0562cd 100644
--- a/include/linux/compat-2.6.35.h
+++ b/include/linux/compat-2.6.35.h
@@ -8,11 +8,6 @@
 #include <net/sock.h>
 #include <linux/types.h>
 
-struct va_format {
-	const char *fmt;
-	va_list *va;
-};
-
 /* added on linux/kernel.h */
 #define USHRT_MAX      ((u16)(~0U))
 #define SHRT_MAX       ((s16)(USHRT_MAX>>1))
diff --git a/include/linux/compat-2.6.36.h b/include/linux/compat-2.6.36.h
index 0307108..b14c772 100644
--- a/include/linux/compat-2.6.36.h
+++ b/include/linux/compat-2.6.36.h
@@ -8,6 +8,11 @@
 #define kparam_block_sysfs_write(a)
 #define kparam_unblock_sysfs_write(a)
 
+struct va_format {
+	const char *fmt;
+	va_list *va;
+};
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) */
 
 #endif /* LINUX_26_36_COMPAT_H */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] compat: fix compiler warning
  2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 1/4] compat: backport n_tty_ioctl_helper Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 2/4] compat: move va_format to compat-2.6.36.h Hauke Mehrtens
@ 2010-08-07 13:32 ` Hauke Mehrtens
  2010-08-07 13:32 ` [PATCH 4/4] compat: update compat_firmware_class.c Hauke Mehrtens
  2010-08-10  1:18 ` [PATCH 0/4] compat: miscellaneous updates for compat Luis R. Rodriguez
  4 siblings, 0 replies; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 13:32 UTC (permalink / raw)
  To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens


Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 include/linux/compat-2.6.27.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/compat-2.6.27.h b/include/linux/compat-2.6.27.h
index d667222..b9d7029 100644
--- a/include/linux/compat-2.6.27.h
+++ b/include/linux/compat-2.6.27.h
@@ -236,6 +236,8 @@ static inline void debugfs_remove_recursive(struct dentry *dentry)
 	_dev;								\
 })
 
+#define dev_name(dev) dev_name((struct device *)dev)
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */
 
 #endif /* LINUX_26_27_COMPAT_H */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] compat: update compat_firmware_class.c
  2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
                   ` (2 preceding siblings ...)
  2010-08-07 13:32 ` [PATCH 3/4] compat: fix compiler warning Hauke Mehrtens
@ 2010-08-07 13:32 ` Hauke Mehrtens
  2010-08-10  1:18 ` [PATCH 0/4] compat: miscellaneous updates for compat Luis R. Rodriguez
  4 siblings, 0 replies; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 13:32 UTC (permalink / raw)
  To: lrodriguez; +Cc: linux-wireless, mcgrof, Hauke Mehrtens

Refresh code based on recent version in linux-next.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 compat/compat_firmware_class.c |  290 ++++++++++++++++++++-------------------
 1 files changed, 149 insertions(+), 141 deletions(-)

diff --git a/compat/compat_firmware_class.c b/compat/compat_firmware_class.c
index 02f38a2..70ab25c 100644
--- a/compat/compat_firmware_class.c
+++ b/compat/compat_firmware_class.c
@@ -88,27 +88,31 @@ static DEFINE_MUTEX(fw_lock);
 
 struct firmware_priv {
 	struct completion completion;
-	struct bin_attribute attr_data;
 	struct firmware *fw;
 	unsigned long status;
 	struct page **pages;
 	int nr_pages;
 	int page_array_size;
 	struct timer_list timeout;
+	struct device dev;
 	bool nowait;
 	char fw_id[];
 };
 
-static void
-fw_load_abort(struct firmware_priv *fw_priv)
+static struct firmware_priv *to_firmware_priv(struct device *dev)
+{
+	return container_of(dev, struct firmware_priv, dev);
+}
+
+static void fw_load_abort(struct firmware_priv *fw_priv)
 {
 	set_bit(FW_STATUS_ABORT, &fw_priv->status);
 	wmb();
 	complete(&fw_priv->completion);
 }
 
-static ssize_t
-firmware_timeout_show(struct class *class, char *buf)
+static ssize_t firmware_timeout_show(struct class *class,
+				     char *buf)
 {
 	return sprintf(buf, "%d\n", loading_timeout);
 }
@@ -125,12 +129,13 @@ firmware_timeout_show(struct class *class, char *buf)
  *
  *	Note: zero means 'wait forever'.
  **/
-static ssize_t
-firmware_timeout_store(struct class *class, const char *buf, size_t count)
+static ssize_t firmware_timeout_store(struct class *class,
+				      const char *buf, size_t count)
 {
 	loading_timeout = simple_strtol(buf, NULL, 10);
 	if (loading_timeout < 0)
 		loading_timeout = 0;
+
 	return count;
 }
 
@@ -142,14 +147,13 @@ static struct class_attribute firmware_class_attrs[] = {
 
 static void fw_dev_release(struct device *dev)
 {
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	int i;
 
 	for (i = 0; i < fw_priv->nr_pages; i++)
 		__free_page(fw_priv->pages[i]);
 	kfree(fw_priv->pages);
 	kfree(fw_priv);
-	kfree(dev);
 
 	module_put(THIS_MODULE);
 }
@@ -157,7 +161,7 @@ static void fw_dev_release(struct device *dev)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
 static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 
 	if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
 		return -ENOMEM;
@@ -172,7 +176,7 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int firmware_uevent(struct device *dev, char **envp,
 			   int num_envp, char *buf, int size)
 {
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	int error, len = 0, i = 0;
 
 	error = add_uevent_var(envp, num_envp, &i,
@@ -209,11 +213,27 @@ static struct class firmware_class = {
 static ssize_t firmware_loading_show(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
+
 	return sprintf(buf, "%d\n", loading);
 }
 
+static void firmware_free_data(const struct firmware *fw)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+	int i;
+	vunmap(fw->data);
+	if (fw->pages) {
+		for (i = 0; i < PFN_UP(fw->size); i++)
+			__free_page(fw->pages[i]);
+		kfree(fw->pages);
+	}
+#else
+	vunmap(fw->data);
+#endif
+}
+
 /* Some architectures don't have PAGE_KERNEL_RO */
 #ifndef PAGE_KERNEL_RO
 #define PAGE_KERNEL_RO PAGE_KERNEL
@@ -221,7 +241,6 @@ static ssize_t firmware_loading_show(struct device *dev,
 /**
  * firmware_loading_store - set value in the 'loading' control file
  * @dev: device pointer
- * @attr: device attribute pointer
  * @buf: buffer to scan for loading control value
  * @count: number of bytes in @buf
  *
@@ -235,7 +254,7 @@ static ssize_t firmware_loading_store(struct device *dev,
 				      struct device_attribute *attr,
 				      const char *buf, size_t count)
 {
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	int loading = simple_strtol(buf, NULL, 10);
 	int i;
 
@@ -246,21 +265,21 @@ static ssize_t firmware_loading_store(struct device *dev,
 			mutex_unlock(&fw_lock);
 			break;
 		}
-		vfree(fw_priv->fw->data);
-		fw_priv->fw->data = NULL;
+		firmware_free_data(fw_priv->fw);
+		memset(fw_priv->fw, 0, sizeof(struct firmware));
+		/* If the pages are not owned by 'struct firmware' */
 		for (i = 0; i < fw_priv->nr_pages; i++)
 			__free_page(fw_priv->pages[i]);
 		kfree(fw_priv->pages);
 		fw_priv->pages = NULL;
 		fw_priv->page_array_size = 0;
 		fw_priv->nr_pages = 0;
-		fw_priv->fw->size = 0;
 		set_bit(FW_STATUS_LOADING, &fw_priv->status);
 		mutex_unlock(&fw_lock);
 		break;
 	case 0:
 		if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
-			vfree(fw_priv->fw->data);
+			vunmap(fw_priv->fw->data);
 			fw_priv->fw->data = vmap(fw_priv->pages,
 						 fw_priv->nr_pages,
 						 0, PAGE_KERNEL_RO);
@@ -268,7 +287,12 @@ static ssize_t firmware_loading_store(struct device *dev,
 				dev_err(dev, "%s: vmap() failed\n", __func__);
 				goto err;
 			}
-			/* Pages will be freed by vfree() */
+			/* Pages are now owned by 'struct firmware' */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+			fw_priv->fw->pages = fw_priv->pages;
+			fw_priv->pages = NULL;
+#endif
+
 			fw_priv->page_array_size = 0;
 			fw_priv->nr_pages = 0;
 			complete(&fw_priv->completion);
@@ -290,12 +314,12 @@ static ssize_t firmware_loading_store(struct device *dev,
 
 static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
 
-static ssize_t
-firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
-		   char *buffer, loff_t offset, size_t count)
+static ssize_t firmware_data_read(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
+				  char *buffer, loff_t offset, size_t count)
 {
 	struct device *dev = to_dev(kobj);
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	struct firmware *fw;
 	ssize_t ret_count;
 
@@ -334,8 +358,7 @@ out:
 	return ret_count;
 }
 
-static int
-fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
 {
 	int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
 
@@ -384,12 +407,12 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
  *	Data written to the 'data' attribute will be later handed to
  *	the driver as a firmware image.
  **/
-static ssize_t
-firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
-		    char *buffer, loff_t offset, size_t count)
+static ssize_t firmware_data_write(struct kobject *kobj,
+				   struct bin_attribute *bin_attr,
+				   char *buffer, loff_t offset, size_t count)
 {
 	struct device *dev = to_dev(kobj);
-	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 	struct firmware *fw;
 	ssize_t retval;
 
@@ -430,116 +453,103 @@ out:
 	return retval;
 }
 
-static struct bin_attribute firmware_attr_data_tmpl = {
-	.attr = {.name = "data", .mode = 0644},
+static struct bin_attribute firmware_attr_data = {
+	.attr = { .name = "data", .mode = 0644 },
 	.size = 0,
 	.read = firmware_data_read,
 	.write = firmware_data_write,
 };
 
-static void
-firmware_class_timeout(u_long data)
+static void firmware_class_timeout(u_long data)
 {
 	struct firmware_priv *fw_priv = (struct firmware_priv *) data;
+
 	fw_load_abort(fw_priv);
 }
 
-static int fw_register_device(struct device **dev_p, const char *fw_name,
-			      struct device *device)
+static struct firmware_priv *
+fw_create_instance(struct firmware *firmware, const char *fw_name,
+		   struct device *device, bool uevent, bool nowait)
 {
-	int retval;
-	struct firmware_priv *fw_priv =
-		kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
-	struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL);
-
-	*dev_p = NULL;
+	struct firmware_priv *fw_priv;
+	struct device *f_dev;
+	int error;
 
-	if (!fw_priv || !f_dev) {
+	fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
+	if (!fw_priv) {
 		dev_err(device, "%s: kmalloc failed\n", __func__);
-		retval = -ENOMEM;
-		goto error_kfree;
+		error = -ENOMEM;
+		goto err_out;
 	}
 
+	fw_priv->fw = firmware;
+	fw_priv->nowait = nowait;
 	strcpy(fw_priv->fw_id, fw_name);
 	init_completion(&fw_priv->completion);
-	fw_priv->attr_data = firmware_attr_data_tmpl;
-	fw_priv->timeout.function = firmware_class_timeout;
-	fw_priv->timeout.data = (u_long) fw_priv;
-	init_timer(&fw_priv->timeout);
+	setup_timer(&fw_priv->timeout,
+		    firmware_class_timeout, (u_long) fw_priv);
 
+	f_dev = &fw_priv->dev;
+
+	device_initialize(f_dev);
 	dev_set_name(f_dev, "%s", dev_name(device));
 	f_dev->parent = device;
 	f_dev->class = &firmware_class;
-	dev_set_drvdata(f_dev, fw_priv);
-	dev_set_uevent_suppress(f_dev, 1);
-	retval = device_register(f_dev);
-	if (retval) {
-		dev_err(device, "%s: device_register failed\n", __func__);
-		put_device(f_dev);
-		return retval;
-	}
-	*dev_p = f_dev;
-	return 0;
-
-error_kfree:
-	kfree(f_dev);
-	kfree(fw_priv);
-	return retval;
-}
 
-static int fw_setup_device(struct firmware *fw, struct device **dev_p,
-			   const char *fw_name, struct device *device,
-			   int uevent, bool nowait)
-{
-	struct device *f_dev;
-	struct firmware_priv *fw_priv;
-	int retval;
-
-	*dev_p = NULL;
-	retval = fw_register_device(&f_dev, fw_name, device);
-	if (retval)
-		goto out;
+	dev_set_uevent_suppress(f_dev, true);
 
 	/* Need to pin this module until class device is destroyed */
 	__module_get(THIS_MODULE);
 
-	fw_priv = dev_get_drvdata(f_dev);
-
-	fw_priv->nowait = nowait;
+	error = device_add(f_dev);
+	if (error) {
+		dev_err(device, "%s: device_register failed\n", __func__);
+		goto err_put_dev;
+	}
 
-	fw_priv->fw = fw;
-	sysfs_bin_attr_init(&fw_priv->attr_data);
-	retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
-	if (retval) {
+	error = device_create_bin_file(f_dev, &firmware_attr_data);
+	if (error) {
 		dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
-		goto error_unreg;
+		goto err_del_dev;
 	}
 
-	retval = device_create_file(f_dev, &dev_attr_loading);
-	if (retval) {
+	error = device_create_file(f_dev, &dev_attr_loading);
+	if (error) {
 		dev_err(device, "%s: device_create_file failed\n", __func__);
-		goto error_unreg;
+		goto err_del_bin_attr;
 	}
 
 	if (uevent)
-		dev_set_uevent_suppress(f_dev, 0);
-	*dev_p = f_dev;
-	goto out;
+		dev_set_uevent_suppress(f_dev, false);
+
+	return fw_priv;
+
+err_del_bin_attr:
+	device_remove_bin_file(f_dev, &firmware_attr_data);
+err_del_dev:
+	device_del(f_dev);
+err_put_dev:
+	put_device(f_dev);
+err_out:
+	return ERR_PTR(error);
+}
+
+static void fw_destroy_instance(struct firmware_priv *fw_priv)
+{
+	struct device *f_dev = &fw_priv->dev;
 
-error_unreg:
+	device_remove_file(f_dev, &dev_attr_loading);
+	device_remove_bin_file(f_dev, &firmware_attr_data);
 	device_unregister(f_dev);
-out:
-	return retval;
 }
 
-static int
-_request_firmware(const struct firmware **firmware_p, const char *name,
-		 struct device *device, int uevent, bool nowait)
+static int _request_firmware(const struct firmware **firmware_p,
+			     const char *name, struct device *device,
+			     bool uevent, bool nowait)
 {
-	struct device *f_dev;
 	struct firmware_priv *fw_priv;
 	struct firmware *firmware;
-	int retval;
+	int retval = 0;
 
 	if (!firmware_p)
 		return -EINVAL;
@@ -560,41 +570,40 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 	if (uevent)
 		dev_dbg(device, "firmware: requesting %s\n", name);
 
-	retval = fw_setup_device(firmware, &f_dev, name, device,
-				 uevent, nowait);
-	if (retval)
-		goto error_kfree_fw;
-
-	fw_priv = dev_get_drvdata(f_dev);
+	fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
+	if (IS_ERR(fw_priv)) {
+		retval = PTR_ERR(fw_priv);
+		goto out;
+	}
 
 	if (uevent) {
-		if (loading_timeout > 0) {
-			fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-			add_timer(&fw_priv->timeout);
-		}
+		if (loading_timeout > 0)
+			mod_timer(&fw_priv->timeout,
+				  round_jiffies_up(jiffies +
+						   loading_timeout * HZ));
+
+		kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
+	}
+
+	wait_for_completion(&fw_priv->completion);
 
-		kobject_uevent(&f_dev->kobj, KOBJ_ADD);
-		wait_for_completion(&fw_priv->completion);
-		set_bit(FW_STATUS_DONE, &fw_priv->status);
-		del_timer_sync(&fw_priv->timeout);
-	} else
-		wait_for_completion(&fw_priv->completion);
+	set_bit(FW_STATUS_DONE, &fw_priv->status);
+	del_timer_sync(&fw_priv->timeout);
 
 	mutex_lock(&fw_lock);
-	if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
+	if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status))
 		retval = -ENOENT;
-		release_firmware(fw_priv->fw);
-		*firmware_p = NULL;
-	}
 	fw_priv->fw = NULL;
 	mutex_unlock(&fw_lock);
-	device_unregister(f_dev);
-	goto out;
 
-error_kfree_fw:
-	kfree(firmware);
-	*firmware_p = NULL;
+	fw_destroy_instance(fw_priv);
+
 out:
+	if (retval) {
+		release_firmware(firmware);
+		firmware_p = NULL;
+	}
+
 	return retval;
 }
 
@@ -629,8 +638,7 @@ void release_firmware(const struct firmware *fw)
 {
 	if (fw) {
 		if (!fw_is_builtin_firmware(fw))
-			vfree(fw->data);
-
+			firmware_free_data(fw);
 		kfree(fw);
 	}
 }
@@ -646,23 +654,24 @@ struct firmware_work {
 	int uevent;
 };
 
-static int
-request_firmware_work_func(void *arg)
+static int request_firmware_work_func(void *arg)
 {
 	struct firmware_work *fw_work = arg;
 	const struct firmware *fw;
 	int ret;
+
 	if (!arg) {
 		WARN_ON(1);
 		return 0;
 	}
-	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
-		fw_work->uevent, true);
 
+	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
+				fw_work->uevent, true);
 	fw_work->cont(fw, fw_work->context);
 
 	module_put(fw_work->module);
 	kfree(fw_work);
+
 	return ret;
 }
 
@@ -690,34 +699,33 @@ request_firmware_nowait(
 	void (*cont)(const struct firmware *fw, void *context))
 {
 	struct task_struct *task;
-	struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-						gfp);
+	struct firmware_work *fw_work;
 
+	fw_work = kzalloc(sizeof (struct firmware_work), gfp);
 	if (!fw_work)
 		return -ENOMEM;
+
+	fw_work->module = module;
+	fw_work->name = name;
+	fw_work->device = device;
+	fw_work->context = context;
+	fw_work->cont = cont;
+	fw_work->uevent = uevent;
+
 	if (!try_module_get(module)) {
 		kfree(fw_work);
 		return -EFAULT;
 	}
 
-	*fw_work = (struct firmware_work) {
-		.module = module,
-		.name = name,
-		.device = device,
-		.context = context,
-		.cont = cont,
-		.uevent = uevent,
-	};
-
 	task = kthread_run(request_firmware_work_func, fw_work,
 			    "firmware/%s", name);
-
 	if (IS_ERR(task)) {
 		fw_work->cont(NULL, fw_work->context);
 		module_put(fw_work->module);
 		kfree(fw_work);
 		return PTR_ERR(task);
 	}
+
 	return 0;
 }
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] compat: move va_format to compat-2.6.36.h
  2010-08-07 13:32 ` [PATCH 2/4] compat: move va_format to compat-2.6.36.h Hauke Mehrtens
@ 2010-08-07 15:50   ` Johannes Berg
  2010-08-07 17:20     ` Hauke Mehrtens
  0 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2010-08-07 15:50 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: lrodriguez, linux-wireless, mcgrof

On Sat, 2010-08-07 at 15:32 +0200, Hauke Mehrtens wrote:
> This struct was introduced in kernel 2.6.36 and not 2.6.35.

I'm confused now:

$ git describe 7db6f5fb
v2.6.35-rc1-928-g7db6f5f

johannes


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] compat: move va_format to compat-2.6.36.h
  2010-08-07 15:50   ` Johannes Berg
@ 2010-08-07 17:20     ` Hauke Mehrtens
  2010-08-08  8:01       ` Johannes Berg
  0 siblings, 1 reply; 9+ messages in thread
From: Hauke Mehrtens @ 2010-08-07 17:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: lrodriguez, linux-wireless, mcgrof

Am 07.08.2010 17:50, schrieb Johannes Berg:
> On Sat, 2010-08-07 at 15:32 +0200, Hauke Mehrtens wrote:
>> This struct was introduced in kernel 2.6.36 and not 2.6.35.
> 
> I'm confused now:
> 
> $ git describe 7db6f5fb
> v2.6.35-rc1-928-g7db6f5f
> 
> johannes
> 
Hi,

I am also confused. ;-) I get the same result for git describe 7db6f5fb
as you.

But include/linux/kernel.h does not contain struct va_format in kernel
2.6.35 it was added sometime later.

Without adding struct va_format to compat-2.6.36.h I get build error
with kernel 2.6.35.

Hauke

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] compat: move va_format to compat-2.6.36.h
  2010-08-07 17:20     ` Hauke Mehrtens
@ 2010-08-08  8:01       ` Johannes Berg
  0 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2010-08-08  8:01 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: lrodriguez, linux-wireless, mcgrof

On Sat, 2010-08-07 at 19:20 +0200, Hauke Mehrtens wrote:
> Am 07.08.2010 17:50, schrieb Johannes Berg:
> > On Sat, 2010-08-07 at 15:32 +0200, Hauke Mehrtens wrote:
> >> This struct was introduced in kernel 2.6.36 and not 2.6.35.
> > 
> > I'm confused now:
> > 
> > $ git describe 7db6f5fb
> > v2.6.35-rc1-928-g7db6f5f
> > 
> > johannes
> > 
> Hi,
> 
> I am also confused. ;-) I get the same result for git describe 7db6f5fb
> as you.
> 
> But include/linux/kernel.h does not contain struct va_format in kernel
> 2.6.35 it was added sometime later.
> 
> Without adding struct va_format to compat-2.6.36.h I get build error
> with kernel 2.6.35.

Ok ... Hmm. I guess this patch got in multiple times or something, since
I can see it in wireless-testing that's based on .35 as well, which was
the reason we moved this to compat-2.6.35 because otherwise it failed
compilation there!

I'm starting to think that we should detect at compile time what
features are present, say by test-compiling a file that contains a use
of the struct.

johannes


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] compat: miscellaneous updates for compat
  2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
                   ` (3 preceding siblings ...)
  2010-08-07 13:32 ` [PATCH 4/4] compat: update compat_firmware_class.c Hauke Mehrtens
@ 2010-08-10  1:18 ` Luis R. Rodriguez
  4 siblings, 0 replies; 9+ messages in thread
From: Luis R. Rodriguez @ 2010-08-10  1:18 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: linux-wireless, mcgrof

On Sat, Aug 7, 2010 at 6:32 AM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> This series contains miscellaneous updates for compat. They are compile
> tested with kernel 2.6.26 to 2.6.35. ath9k and b43 were tested with
> kernel 2.6.32.
>
> Hauke Mehrtens (4):
>  compat: backport n_tty_ioctl_helper
>  compat: move va_format to compat-2.6.36.h
>  compat: fix compiler warning
>  compat: update compat_firmware_class.c
>
>  compat/compat-2.6.28.c         |  128 ++++++++++++++++++
>  compat/compat_firmware_class.c |  290 ++++++++++++++++++++-------------------
>  include/linux/compat-2.6.27.h  |    2 +
>  include/linux/compat-2.6.28.h  |    6 +
>  include/linux/compat-2.6.35.h  |    5 -
>  include/linux/compat-2.6.36.h  |    5 +
>  6 files changed, 290 insertions(+), 146 deletions(-)

Nice, thanks applied all 4 patches to compat and the 2 other patches
to compat-wireless. Sorry for the delay.

  Luis

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-08-10  1:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-07 13:32 [PATCH 0/4] compat: miscellaneous updates for compat Hauke Mehrtens
2010-08-07 13:32 ` [PATCH 1/4] compat: backport n_tty_ioctl_helper Hauke Mehrtens
2010-08-07 13:32 ` [PATCH 2/4] compat: move va_format to compat-2.6.36.h Hauke Mehrtens
2010-08-07 15:50   ` Johannes Berg
2010-08-07 17:20     ` Hauke Mehrtens
2010-08-08  8:01       ` Johannes Berg
2010-08-07 13:32 ` [PATCH 3/4] compat: fix compiler warning Hauke Mehrtens
2010-08-07 13:32 ` [PATCH 4/4] compat: update compat_firmware_class.c Hauke Mehrtens
2010-08-10  1:18 ` [PATCH 0/4] compat: miscellaneous updates for compat Luis R. Rodriguez

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.