From 0f5e02cac96eaeb7645c4ff4470809e97cd86bfa Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Wed, 26 Jul 2006 23:15:13 +0000 Subject: 2006-07-27 Stefan Siegl * 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 . (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. --- ChangeLog | 10 +++++ i386/i386at/i386at_ds_routines.c | 6 +++ linux/dev/glue/net.c | 94 +++++++++++++++++++++++++++++++++++++++- linux/dev/init/main.c | 10 +++++ 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 + * 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 . + (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 #include #include +#include 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; } -- cgit v1.2.3