summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--i386/i386at/i386at_ds_routines.c6
-rw-r--r--linux/dev/glue/net.c94
-rw-r--r--linux/dev/init/main.c10
4 files changed, 118 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index db0e195..4ea9030 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2006-07-27 Stefan Siegl <stesie@brokenpipe.de>
+ * i386/i386at/i386at_ds_routines.c (emulation_list)
+ [LINUX_DEV && CONFIG_INET && CONFIG_PCMCIA]: Add the Linux pcmcia
+ emulation structure.
+ * linux/dev/glue/net.c: Include <linux/wireless.h>.
+ (device_get_status): Rewrite function.
+ (device_set_status): New function.
+ (linux_net_emulation_ops): Add `device_set_status' at the appropriate
+ position.
+ * linux/dev/init/main.c (linux_init) [CONFIG_PCMCIA]: Call pcmcia_init.
+
* linux/pcmcia-cs/glue/ds.c: New file.
* linux/pcmcia-cs/glue/pcmcia.c: Likewise.
* linux/pcmcia-cs/glue/pcmcia_glue.h: Likewise.
diff --git a/i386/i386at/i386at_ds_routines.c b/i386/i386at/i386at_ds_routines.c
index 2a52a67..b4387d6 100644
--- a/i386/i386at/i386at_ds_routines.c
+++ b/i386/i386at/i386at_ds_routines.c
@@ -45,6 +45,9 @@ extern struct device_emulation_ops mach_device_emulation_ops;
extern struct device_emulation_ops linux_block_emulation_ops;
#ifdef CONFIG_INET
extern struct device_emulation_ops linux_net_emulation_ops;
+#ifdef CONFIG_PCMCIA
+extern struct device_emulation_ops linux_pcmcia_emulation_ops;
+#endif
#endif
#endif
@@ -55,6 +58,9 @@ static struct device_emulation_ops *emulation_list[] =
&linux_block_emulation_ops,
#ifdef CONFIG_INET
&linux_net_emulation_ops,
+#ifdef CONFIG_PCMCIA
+ &linux_pcmcia_emulation_ops,
+#endif
#endif
#endif
&mach_device_emulation_ops,
diff --git a/linux/dev/glue/net.c b/linux/dev/glue/net.c
index 4a989d3..f0bd650 100644
--- a/linux/dev/glue/net.c
+++ b/linux/dev/glue/net.c
@@ -96,6 +96,7 @@
#include <linux/malloc.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/wireless.h>
extern int linux_intr_pri;
@@ -520,13 +521,102 @@ device_write (void *d, ipc_port_t reply_port,
return MIG_NO_REPLY;
}
+
static io_return_t
device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
mach_msg_type_number_t *count)
{
- return net_getstat (&((struct net_data *) d)->ifnet, flavor, status, count);
+ if(flavor >= SIOCIWFIRST && flavor <= SIOCIWLAST)
+ {
+ /* handle wireless ioctl */
+ if(! IW_IS_GET(flavor))
+ return D_INVALID_OPERATION;
+
+ if(*count * sizeof(int) < sizeof(struct ifreq))
+ return D_INVALID_OPERATION;
+
+ struct net_data *nd = d;
+ struct linux_device *dev = nd->dev;
+
+ if(! dev->do_ioctl)
+ return D_INVALID_OPERATION;
+
+ int result;
+
+ if((flavor == SIOCGIWRANGE || flavor == SIOCGIWENCODE
+ || flavor == SIOCGIWESSID || flavor == SIOCGIWNICKN
+ || flavor == SIOCGIWSPY)
+ && ((struct iwreq *) status)->u.data.pointer)
+ {
+ struct iw_point *iwp = &((struct iwreq *) status)->u.data;
+
+ /* safety check whether the status array is long enough ... */
+ if(*count * sizeof(int) < sizeof(struct ifreq) + iwp->length)
+ return D_INVALID_OPERATION;
+
+ /* make sure, iwp->pointer points to the correct address */
+ iwp->pointer = (void *) status + sizeof(struct ifreq);
+
+ result = dev->do_ioctl(dev, (struct ifreq *) status, flavor);
+ /* *count = (sizeof(struct ifreq) + iwp->length) / sizeof(int);
+ * if(iwp->length % sizeof(int)) *count ++;
+ */
+ }
+ else
+ {
+ *count = sizeof(struct ifreq) / sizeof(int);
+ result = dev->do_ioctl(dev, (struct ifreq *) status, flavor);
+ }
+
+ return result ? D_IO_ERROR : D_SUCCESS;
+ }
+ else
+ {
+ /* common get_status request */
+ return net_getstat (&((struct net_data *) d)->ifnet, flavor,
+ status, count);
+ }
+}
+
+
+static io_return_t
+device_set_status(void *d, dev_flavor_t flavor, dev_status_t status,
+ mach_msg_type_number_t count)
+{
+ if(flavor < SIOCIWFIRST || flavor > SIOCIWLAST)
+ return D_INVALID_OPERATION;
+
+ if(! IW_IS_SET(flavor))
+ return D_INVALID_OPERATION;
+
+ if(count * sizeof(int) < sizeof(struct ifreq))
+ return D_INVALID_OPERATION;
+
+ struct net_data *nd = d;
+ struct linux_device *dev = nd->dev;
+
+ if(! dev->do_ioctl)
+ return D_INVALID_OPERATION;
+
+ if((flavor == SIOCSIWENCODE || flavor == SIOCSIWESSID
+ || flavor == SIOCSIWNICKN || flavor == SIOCSIWSPY)
+ && ((struct iwreq *) status)->u.data.pointer)
+ {
+ struct iw_point *iwp = &((struct iwreq *) status)->u.data;
+
+ /* safety check whether the status array is long enough ... */
+ if(count * sizeof(int) < sizeof(struct ifreq) + iwp->length)
+ return D_INVALID_OPERATION;
+
+ /* make sure, iwp->pointer points to the correct address */
+ if(iwp->pointer) iwp->pointer = (void *) status + sizeof(struct ifreq);
+ }
+
+ int result = dev->do_ioctl(dev, (struct ifreq *) status, flavor);
+ return result ? D_IO_ERROR : D_SUCCESS;
}
+
static io_return_t
device_set_filter (void *d, ipc_port_t port, int priority,
filter_t * filter, unsigned filter_count)
@@ -546,7 +636,7 @@ struct device_emulation_ops linux_net_emulation_ops =
NULL,
NULL,
NULL,
- NULL,
+ device_set_status,
device_get_status,
device_set_filter,
NULL,
diff --git a/linux/dev/init/main.c b/linux/dev/init/main.c
index 0c14353..fa932bd 100644
--- a/linux/dev/init/main.c
+++ b/linux/dev/init/main.c
@@ -103,6 +103,7 @@ extern int linux_bad_intr (int);
extern int prtnull ();
extern int intnull ();
extern void linux_sched_init (void);
+extern void pcmcia_init (void);
/*
@@ -179,10 +180,19 @@ linux_init (void)
#ifdef CONFIG_INET
linux_net_emulation_init ();
#endif
+
cli ();
device_setup ();
+#ifdef CONFIG_PCMCIA
+ /*
+ * Initialize pcmcia.
+ */
+ pcmcia_init ();
+#endif
+
restore_IRQ ();
+
linux_auto_config = 0;
}