diff options
Diffstat (limited to 'linux/dev')
-rw-r--r-- | linux/dev/glue/net.c | 94 | ||||
-rw-r--r-- | linux/dev/init/main.c | 10 |
2 files changed, 102 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, 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; } |