diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | i386/i386at/i386at_ds_routines.c | 6 | ||||
-rw-r--r-- | linux/dev/glue/net.c | 94 | ||||
-rw-r--r-- | linux/dev/init/main.c | 10 |
4 files changed, 118 insertions, 2 deletions
@@ -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; } |