summaryrefslogtreecommitdiff
path: root/linux/dev/glue
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@gnu.org>2006-07-26 23:15:13 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-06-18 00:26:39 +0200
commit0f5e02cac96eaeb7645c4ff4470809e97cd86bfa (patch)
treec9885a409c45c89564b5f6b99427728fd15854bb /linux/dev/glue
parentd5ca6ad6dab83572dbdafbdec34d129d5da5a1c1 (diff)
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.
Diffstat (limited to 'linux/dev/glue')
-rw-r--r--linux/dev/glue/net.c94
1 files changed, 92 insertions, 2 deletions
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,