Re: [PATCH 1/2] pci_hotplug: add an uevent framework to pci_hotplug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Taku Izumi wrote:
This patch adds an uevent framework to pci_hotplug.

Signed-off-by: Taku Izumi <izumi.taku@xxxxxxxxxxxxxx>

---
 drivers/pci/hotplug/Makefile             |    2
 drivers/pci/hotplug/pci_hotplug_core.c   |    9 +
 drivers/pci/hotplug/pci_hotplug_uevent.c |  169 +++++++++++++++++++++++++++++++
 drivers/pci/hotplug/pci_hotplug_uevent.h |   43 +++++++
 4 files changed, 223 insertions(+)

Index: linux-next.29rc6/drivers/pci/hotplug/Makefile
===================================================================
--- linux-next.29rc6.orig/drivers/pci/hotplug/Makefile
+++ linux-next.29rc6/drivers/pci/hotplug/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakep

 pci_hotplug-objs	:=	pci_hotplug_core.o

+pci_hotplug-objs	+=	pci_hotplug_uevent.o
+
 ifdef CONFIG_HOTPLUG_PCI_CPCI
 pci_hotplug-objs	+=	cpci_hotplug_core.o	\
 				cpci_hotplug_pci.o
Index: linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_core.c
===================================================================
--- linux-next.29rc6.orig/drivers/pci/hotplug/pci_hotplug_core.c
+++ linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_core.c
@@ -42,6 +42,7 @@
 #include <linux/pci_hotplug.h>
 #include <asm/uaccess.h>
 #include "../pci.h"
+#include "pci_hotplug_uevent.h"

 #define MY_NAME	"pci_hotplug"

@@ -658,6 +659,12 @@ static int __init pci_hotplug_init (void
 {
 	int result;

+	result = pcihp_uevent_init();
+	if (result) {
+		err("pcihp_uevent_init with error %d\n", result);
+		goto err_pcihp_uevent;
+	}
+
 	result = cpci_hotplug_init(debug);
 	if (result) {
 		err ("cpci_hotplug_init with error %d\n", result);
@@ -666,6 +673,7 @@ static int __init pci_hotplug_init (void

 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");

+err_pcihp_uevent:
 err_cpci:
 	return result;
 }
@@ -673,6 +681,7 @@ err_cpci:
 static void __exit pci_hotplug_exit (void)
 {
 	cpci_hotplug_exit();
+	pcihp_uevent_exit();
 }

 module_init(pci_hotplug_init);
Index: linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_uevent.c
===================================================================
--- /dev/null
+++ linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_uevent.c
@@ -0,0 +1,169 @@
+/*
+ * PCI Hotplug Uevent Support (pci_hotplug_uevent)
+ *
+ * Copyright (C) 2009 Taku Izumi
+ * Copyright (C) 2009 FUJITSU LIMITED
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/kobject.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+
+#include "pci_hotplug_uevent.h"
+
+#define MY_NAME "pci_hotplug_uevent"
+#define err(format, arg...)                                             \
+		printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...)                                            \
+		printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...)                                            \
+		printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+
+static const struct {
+	enum pcihp_uevent_type type;
+	enum kobject_action action;
+	char *name;

I think we don't need the "type" field. And I also think we don't
need "action" field because we will always use KOBJ_CHANGE. So we
don't need this struct.

+} _pcihp_uevent_type_names[] = {
+	{PHP_UEVT_PRESENCE_ON, KOBJ_CHANGE, "Card Present"},
+	{PHP_UEVT_PRESENCE_OFF, KOBJ_CHANGE, "Card Not Present"},
+	{PHP_UEVT_SWITCH_CLOSE, KOBJ_CHANGE, "Latch Close"},
+	{PHP_UEVT_SWITCH_OPEN, KOBJ_CHANGE, "Latch Open"},
+	{PHP_UEVT_POWER_FAULT, KOBJ_CHANGE, "Power Fault"},
+	{PHP_UEVT_POWER_FAULT_CLEAR, KOBJ_CHANGE, "Power Fault Cleared"},
+	{PHP_UEVT_BUTTON_PRESS, KOBJ_CHANGE, "Attention Button Pressed"},
+};
+
+static struct kmem_cache *_pcihp_uevent_cache;
+

I don't think we need to create new kmem cache.

+struct pcihp_uevent {
+	struct hotplug_slot *slot;
+	enum kobject_action action;
+	struct kobj_uevent_env ku_env;
+};

I think we don't need the "slot" field. And I also think we don't
need "action" field because we will always use KOBJ_CHANGE. So we
don't need struct pcihp_uevent.

+
+static void pcihp_uevent_free(struct pcihp_uevent *event)
+{
+	kmem_cache_free(_pcihp_uevent_cache, event);
+}
+
+static struct pcihp_uevent *pcihp_uevent_create(struct hotplug_slot *slot,
+						enum kobject_action action,
+						const char *event_name)
+{
+	struct pcihp_uevent *event;
+
+	event = kmem_cache_zalloc(_pcihp_uevent_cache, GFP_ATOMIC);

How about adding struct pcihp_uevent (I think we only need struct
kobj_uevent_env though) into struct hotplug_slot? This will remove
memory allocation in each event. Though we need to serialize
pcihp_uevent_create() on each slot.

+	if (!event) {
+		err("%s: kmem_cache_zalloc() failed", __func__);
+		goto err_nomem;
+	}
+
+	event->slot = slot;
+	event->action = action;
+
+	if (add_uevent_var(&event->ku_env,
+			   "PCIHP_SLOT_NAME=%s",
+			   hotplug_slot_name(slot))) {
+		err("%s: add_uevent_var() for PCIHP_SLOT_NAME failed",
+		      __func__);
+		goto err_add;
+	}
+
+	if (add_uevent_var(&event->ku_env,
+			   "PCIHP_SLOT_ADDRESS=%04x:%02x:%02x",
+			    pci_domain_nr(slot->pci_slot->bus),
+			    slot->pci_slot->bus->number,
+			    slot->pci_slot->number)) {
+		err("%s: add_uevent_var() for PCIHP_SLOT_ADDRESS failed",
+		      __func__);
+		goto err_add;
+	}

I don't think we need PCIHP_SLOT_ADDRESS because we can get it
from sys/bus/pci/slots/<slot name>/address file.

+
+	if (add_uevent_var(&event->ku_env,
+			   "PCIHP_DRV_NAME=%s",
+			   slot->ops->owner->name)) {
+		err("%s: add_uevent_var() for PCIHP_DRV_NAME failed",
+		      __func__);
+		goto err_add;
+	}
+

How about adding new file under sys/bus/pci/<slot name> directory
to indicate which php driver manages the slot, instead of adding
PCIHP_DRV_NAME environment variable. I had some experiences that
it was difficult to know the slot was manged by what php driver
in debugging. So the new file will be useful for debugging too.


+	if (add_uevent_var(&event->ku_env,
+			   "PCIHP_EVENT_TYPE=%s",
+			   event_name)) {
+		err("%s: add_uevent_var() for PCIHP_EVENT_TYPE failed\n",
+		    __func__);
+		goto err_add;
+	}
+
+	return event;
+
+err_add:
+	pcihp_uevent_free(event);
+err_nomem:
+	return ERR_PTR(-ENOMEM);
+}
+
+static void pcihp_uevent_send(struct pcihp_uevent *event, struct kobject *kobj)
+{
+	int ret;
+
+	ret = kobject_uevent_env(kobj, event->action, event->ku_env.envp);
+	if (ret)
+		err("%s: kobject_uevent_env failed", __func__);
+}
+
+void pcihp_slot_uevent(enum pcihp_uevent_type event_type,
+					   struct hotplug_slot *slot)
+{
+	struct pcihp_uevent *event;
+
+	if (event_type >= ARRAY_SIZE(_pcihp_uevent_type_names)) {
+		err("%s: Invalid event_type %d", __func__, event_type);
+		goto out;
+	}
+
+	event = pcihp_uevent_create(slot,
+				    _pcihp_uevent_type_names[event_type].action,
+				    _pcihp_uevent_type_names[event_type].name);
+	if (IS_ERR(event))
+		goto out;
+
+	pcihp_uevent_send(event, &slot->pci_slot->kobj);
+
+	pcihp_uevent_free(event);
+out:
+	return;
+}
+EXPORT_SYMBOL_GPL(pcihp_slot_uevent);
+
+
+int pcihp_uevent_init(void)
+{
+	_pcihp_uevent_cache = KMEM_CACHE(pcihp_uevent, 0);
+	if (!_pcihp_uevent_cache)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void pcihp_uevent_exit(void)
+{
+	kmem_cache_destroy(_pcihp_uevent_cache);
+}
Index: linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_uevent.h
===================================================================
--- /dev/null
+++ linux-next.29rc6/drivers/pci/hotplug/pci_hotplug_uevent.h
@@ -0,0 +1,43 @@
+/*
+ * PCI Hotplug Uevent Support
+ *
+ * Copyright (C) 2009 Taku Izumi
+ * Copyright (C) 2009 FUJITSU LIMITED
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef PCI_HOTPLUG_UEVENT_H
+#define PCI_HOTPLUG_UEVENT_H
+
+enum pcihp_uevent_type {
+	PHP_UEVT_PRESENCE_ON,
+	PHP_UEVT_PRESENCE_OFF,
+	PHP_UEVT_SWITCH_CLOSE,
+	PHP_UEVT_SWITCH_OPEN,
+	PHP_UEVT_POWER_FAULT,
+	PHP_UEVT_POWER_FAULT_CLEAR,
+	PHP_UEVT_BUTTON_PRESS,
+};

Attention button is used to request several kinds on hotplug
operations.

- Initiate hot-add operation
- Cancel hot-add operation
- Initiate hot-removal operation
- Cancel hot-removal operation

I think PHP_UEVT_BUTTON_PRESS should be divided for each because
userland has no way to identify it. In addition, ACPI doesn't
define attention button, but ACPI Device/Bus check event and
Eject request event can be mapped to "Initiate hot-add operation"
and "Initiate hot-removal operation" respectively in acpiphp.

Thanks,
Kenji Kaneshige


+
+extern int pcihp_uevent_init(void);
+extern void pcihp_uevent_exit(void);
+extern void pcihp_slot_uevent(enum pcihp_uevent_type event_type,
+			      struct hotplug_slot *slot);
+
+#endif	/* PCI_HOTPLUG_UEVENT_H */

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux