public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.5] pcmcia: alternative setting of resources
@ 2003-03-29 16:19 Dominik Brodowski
  0 siblings, 0 replies; only message in thread
From: Dominik Brodowski @ 2003-03-29 16:19 UTC (permalink / raw)
  To: rmk; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5938 bytes --]

With cardmgr being deprecated soon, there's a need for a different way to 
set the iomem/ioport/irq resources the PCMCIA drivers (and the PCMCIA core 
service) may use.

A sample new-style /etc/rc.d/pcmcia file which is based on
pcmcia-cs-3.2.3/etc/config.opts is attached. Don't rely on it yet, in-kernel
driver & device matching and hotplug support is not yet ready but will
follow soon.

	Dominik

 ds.c       |  160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rsrc_mgr.c |    3 -
 2 files changed, 160 insertions(+), 3 deletions(-)

diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- linux-original/drivers/pcmcia/ds.c	2003-03-29 15:41:01.000000000 +0100
+++ linux/drivers/pcmcia/ds.c	2003-03-29 16:38:23.000000000 +0100
@@ -1213,12 +1213,171 @@
 EXPORT_SYMBOL(pcmcia_bus_type);
 
 
+#define add_MANAGED_RESOURCE ADD_MANAGED_RESOURCE
+#define remove_MANAGED_RESOURCE REMOVE_MANAGED_RESOURCE
+
+#define store_iomem(action)						\
+static ssize_t store_iomem_##action (const char *buf, size_t count)	\
+{									\
+	ssize_t ret = -EINVAL;						\
+	unsigned long from, to;						\
+	adjust_t adj;							\
+									\
+	ret = sscanf (buf, "0x%lx-0x%lx", &from, &to);			\
+	if (ret != 2)							\
+		return -EINVAL;						\
+									\
+	if (to <= from) 						\
+		return -EINVAL;						\
+									\
+	adj.Action = action##_MANAGED_RESOURCE;				\
+	adj.Resource = RES_MEMORY_RANGE;				\
+	adj.resource.memory.Base = from;				\
+	adj.resource.memory.Size = to - from + 1;			\
+									\
+	ret = pcmcia_adjust_resource_info(0, &adj);			\
+									\
+	return ret ? ret : count;					\
+}
+store_iomem(add);
+store_iomem(remove);
+
+#define store_ioport(action)						\
+static ssize_t store_ioport_##action (const char *buf, size_t count)	\
+{									\
+	ssize_t ret = -EINVAL;						\
+	unsigned int from, to, addr_lines;				\
+	adjust_t adj;							\
+									\
+	ret = sscanf (buf, "0x%x-0x%x:0x%x", &from, &to, &addr_lines);	\
+	if ((ret != 2) && (ret != 3))					\
+		return -EINVAL;						\
+									\
+	if ((to <= from) || ( to > 0xffff))				\
+		return -EINVAL;						\
+									\
+	adj.Action = action##_MANAGED_RESOURCE;				\
+	adj.Resource = RES_IO_RANGE;					\
+	adj.resource.io.BasePort = from;				\
+	adj.resource.io.NumPorts = to - from + 1;			\
+	if (ret == 3)							\
+		adj.resource.io.IOAddrLines = addr_lines;		\
+	else								\
+		adj.resource.io.IOAddrLines = 0;			\
+									\
+	ret = pcmcia_adjust_resource_info(0, &adj);			\
+									\
+	return ret ? ret : count;					\
+}
+store_ioport(add);
+store_ioport(remove);
+
+#define store_irq(action)						\
+static ssize_t store_irq_##action (const char *buf, size_t count)	\
+{									\
+	ssize_t ret = -EINVAL;						\
+	unsigned int irq, attr;						\
+	adjust_t adj;							\
+									\
+	ret = sscanf (buf, "0x%u:0x%x", &irq, &attr);			\
+	if ((ret != 1) && (ret != 2))					\
+		return -EINVAL;						\
+									\
+	adj.Action = action##_MANAGED_RESOURCE;				\
+	adj.Resource = RES_IRQ;						\
+	adj.resource.irq.IRQ = irq;					\
+	if (ret == 2)							\
+		adj.Attributes = attr;					\
+	else								\
+		adj.Attributes = 0;					\
+									\
+	ret = pcmcia_adjust_resource_info(0, &adj);			\
+									\
+	return ret ? ret : count;					\
+}
+store_irq(add);
+store_irq(remove);
+
+static ssize_t store_resources_done (const char * buf, size_t count)
+{
+	ssize_t ret = -EINVAL;
+	unsigned int value;
+
+	ret = sscanf (buf, "%u", &value);
+	if ((ret != 1) || (value > 1))
+		return -EINVAL;
+	if (value == resources_available)
+		return count;
+	resources_available = value;
+	pcmcia_rescan_cards();
+	return count;
+}
+
+struct res_attr {
+	struct attribute attr;
+	ssize_t (*store)(const char *, size_t count);
+};
+
+#define define_one_w(_name) \
+struct res_attr _name = { \
+	.attr = { .name = __stringify(_name), .mode = 0200 }, \
+	.store = store_##_name, \
+}
+define_one_w(iomem_add);
+define_one_w(iomem_remove);
+define_one_w(ioport_add);
+define_one_w(ioport_remove);
+define_one_w(irq_add);
+define_one_w(irq_remove);
+define_one_w(resources_done);
+
+static struct attribute * default_attrs[] = {
+	&iomem_add.attr,
+	&iomem_remove.attr,
+	&ioport_add.attr,
+	&ioport_remove.attr,
+	&irq_add.attr,
+	&irq_remove.attr,
+	&resources_done.attr,
+	NULL
+};
+
+static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
+{
+	return 0;
+}
+
+static ssize_t store(struct kobject * kobj, struct attribute * attr, 
+		     const char * buf, size_t count)
+{
+	struct res_attr * rattr = container_of(attr, struct res_attr, attr);
+	rattr->store ? rattr->store(buf,count) : 0;
+	return count;
+}
+
+static struct sysfs_ops sysfs_ops = {
+	.show	= show,
+	.store	= store,
+};
+
+static struct kobj_type ktype_pcmcia_resources = {
+	.sysfs_ops	= &sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
+static struct kobject pcmcia_resource_kobj = {
+	.name = "resources",
+	.parent = &pcmcia_bus_type.subsys.kset.kobj,
+	.ktype = &ktype_pcmcia_resources,
+};
+
 static int __init init_pcmcia_bus(void)
 {
 	int i;
 
 	bus_register(&pcmcia_bus_type);
 	interface_register(&pcmcia_bus_interface);
+	kobject_register(&pcmcia_resource_kobj);
 
 	/* Set up character device for user mode clients */
 	i = register_chrdev(0, "pcmcia", &ds_fops);
@@ -1241,6 +1400,7 @@
 
 static void __exit exit_pcmcia_bus(void)
 {
+	kobject_unregister(&pcmcia_resource_kobj);
 	interface_unregister(&pcmcia_bus_interface);
 
 #ifdef CONFIG_PROC_FS
diff -ruN linux-original/drivers/pcmcia/rsrc_mgr.c linux/drivers/pcmcia/rsrc_mgr.c
--- linux-original/drivers/pcmcia/rsrc_mgr.c	2003-03-29 15:16:03.000000000 +0100
+++ linux/drivers/pcmcia/rsrc_mgr.c	2003-03-29 16:38:23.000000000 +0100
@@ -848,9 +848,6 @@
 
 int pcmcia_adjust_resource_info(client_handle_t handle, adjust_t *adj)
 {
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    
     switch (adj->Resource) {
     case RES_MEMORY_RANGE:
 	return adjust_memory(adj);

[-- Attachment #2: rc.d.pcmcia --]
[-- Type: text/plain, Size: 2448 bytes --]

#! /bin/sh
# place this rc.d script _after_ the hotplug script, please.
. /etc/rc.status
rc_reset

echo -n "Setting up resources for PCMCIA (16-bit): "

if [ $UID != 0 ]; then
    echo " only allowed for root"
    rc_failed 4
    rc_status -v
    rc_exit
fi

case "$1" in
    start)
	if [ ! -d /sys/bus/pcmcia/resources ]; then
	    echo "No 2.5. pcmcia subsystem found"
	    rc_failed 4
	    rc_status -v
	    rc_exit
	fi
	echo -n "0x100-0x4ff" > /sys/bus/pcmcia/resources/ioport_add
	echo -n "0x800-0x8ff" > /sys/bus/pcmcia/resources/ioport_add
	echo -n "0xc00-0xcff" > /sys/bus/pcmcia/resources/ioport_add
	echo -n "0xc0000-0xfffff"  > /sys/bus/pcmcia/resources/iomem_add
	echo -n "0xa0000000-0xa0ffffff" > /sys/bus/pcmcia/resources/iomem_add
	echo -n "0x60000000-0x60ffffff" > /sys/bus/pcmcia/resources/iomem_add
	# High port numbers do not always work...
	# echo -n "0x1000-0x17ff" > /sys/bus/pcmcia/resources/ioport_add
	# Extra port range for IBM Token Ring
	# echo -n "0xa00-0xaff" > /sys/bus/pcmcia/resources/ioport_add
	# Resources we should not use, even if they appear to be available
	# First built-in serial port
	echo -n "4" > /sys/bus/pcmcia/resources/irq_remove
	# Second built-in serial port
	# echo -n "3" > /sys/bus/pcmcia/resources/irq_remove
	# First built-in parallel port
	# echo -n "7" > /sys/bus/pcmcia/resources/irq_remove
	# start in-kernel matching
	echo -n "1" > /sys/bus/pcmcia/resources/resources_done
	rc_failed 0
	;;
    stop)
	echo -n "0" > /sys/bus/pcmcia/resources/resources_done
	sleep 1
	echo -n "0x100-0x4ff" > /sys/bus/pcmcia/resources/ioport_remove
	echo -n "0x800-0x8ff" > /sys/bus/pcmcia/resources/ioport_remove
	echo -n "0xc00-0xcff" > /sys/bus/pcmcia/resources/ioport_remove
	echo -n "0xc0000-0xfffff"  > /sys/bus/pcmcia/resources/iomem_remove
	echo -n "0xa0000000-0xa0ffffff" >  /sys/bus/pcmcia/resources/iomem_remove
	echo -n "0x60000000-0x60ffffff" > /sys/bus/pcmcia/resources/iomem_remove
	# Extra port range for IBM Token Ring
	echo -n "0xa00-0xaff" > /sys/bus/pcmcia/resources/ioport_remove
	# Resources we should not use, even if they appear to be available
	# First built-in serial port
	echo -n "4" > /sys/bus/pcmcia/resources/irq_add
	# Second built-in serial port
	# echo -n "3" > /sys/bus/pcmcia/resources/irq_add
	# First built-in parallel port
	echo -n "7" > /sys/bus/pcmcia/resources/irq_add
	;;
    *)
	echo "Usage: $0 {start|stop|status|restart|reload}"
	;;
esac

rc_status -v
rc_exit

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-03-29 16:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-29 16:19 [PATCH 2.5] pcmcia: alternative setting of resources Dominik Brodowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox