X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=net%2Firda%2Firnet%2Firnet_irda.c;h=cccc2e93234f3033765f5c71e0e13c8861765e8f;hp=c378e668af0c2e1cea690245c114d296c12b3da9;hb=d43c36dc6b357fa1806800f18aa30123c747a6d1;hpb=6819bc2e1e46c71711a8dddf4040e706b02973c0 diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index c378e66..cccc2e9 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c @@ -9,6 +9,30 @@ */ #include "irnet_irda.h" /* Private header */ +#include +#include +#include + +/* + * PPP disconnect work: we need to make sure we're in + * process context when calling ppp_unregister_channel(). + */ +static void irnet_ppp_disconnect(struct work_struct *work) +{ + irnet_socket * self = + container_of(work, irnet_socket, disconnect_work); + + if (self == NULL) + return; + /* + * If we were connected, cleanup & close the PPP + * channel, which will kill pppd (hangup) and the rest. + */ + if (self->ppp_open && !self->ttp_open && !self->ttp_connect) { + ppp_unregister_channel(&self->chan); + self->ppp_open = 0; + } +} /************************* CONTROL CHANNEL *************************/ /* @@ -499,6 +523,8 @@ irda_irnet_create(irnet_socket * self) #endif /* DISCOVERY_NOMASK */ self->tx_flow = FLOW_START; /* Flow control from IrTTP */ + INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect); + DEXIT(IRDA_SOCK_TRACE, "\n"); return(0); } @@ -1134,15 +1160,8 @@ irnet_disconnect_indication(void * instance, { if(test_open) { -#ifdef MISSING_PPP_API - /* ppp_unregister_channel() wants a user context, which we - * are guaranteed to NOT have here. What are we supposed - * to do here ? Jean II */ - /* If we were connected, cleanup & close the PPP channel, - * which will kill pppd (hangup) and the rest */ - ppp_unregister_channel(&self->chan); - self->ppp_open = 0; -#endif + /* ppp_unregister_channel() wants a user context. */ + schedule_work(&self->disconnect_work); } else { @@ -1656,7 +1675,7 @@ irnet_discovery_indication(discinfo_t * discovery, /* Notify the control channel */ irnet_post_event(NULL, IRNET_DISCOVER, discovery->saddr, discovery->daddr, discovery->info, - u16ho(discovery->hints)); + get_unaligned((__u16 *)discovery->hints)); DEXIT(IRDA_OCB_TRACE, "\n"); } @@ -1687,7 +1706,7 @@ irnet_expiry_indication(discinfo_t * expiry, /* Notify the control channel */ irnet_post_event(NULL, IRNET_EXPIRE, expiry->saddr, expiry->daddr, expiry->info, - u16ho(expiry->hints)); + get_unaligned((__u16 *)expiry->hints)); DEXIT(IRDA_OCB_TRACE, "\n"); } @@ -1701,34 +1720,23 @@ irnet_expiry_indication(discinfo_t * expiry, */ #ifdef CONFIG_PROC_FS -/*------------------------------------------------------------------*/ -/* - * Function irnet_proc_read (buf, start, offset, len, unused) - * - * Give some info to the /proc file system - */ static int -irnet_proc_read(char * buf, - char ** start, - off_t offset, - int len) +irnet_proc_show(struct seq_file *m, void *v) { irnet_socket * self; char * state; int i = 0; - len = 0; - /* Get the IrNET server information... */ - len += sprintf(buf+len, "IrNET server - "); - len += sprintf(buf+len, "IrDA state: %s, ", + seq_printf(m, "IrNET server - "); + seq_printf(m, "IrDA state: %s, ", (irnet_server.running ? "running" : "dead")); - len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel); - len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel); + seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel); + seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel); /* Do we need to continue ? */ if(!irnet_server.running) - return len; + return 0; /* Protect access to the instance list */ spin_lock_bh(&irnet_server.spinlock); @@ -1738,23 +1746,23 @@ irnet_proc_read(char * buf, while(self != NULL) { /* Start printing info about the socket. */ - len += sprintf(buf+len, "\nIrNET socket %d - ", i++); + seq_printf(m, "\nIrNET socket %d - ", i++); /* First, get the requested configuration */ - len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname); - len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr); - len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr); + seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname); + seq_printf(m, "daddr: %08x, ", self->rdaddr); + seq_printf(m, "saddr: %08x\n", self->rsaddr); /* Second, get all the PPP info */ - len += sprintf(buf+len, " PPP state: %s", + seq_printf(m, " PPP state: %s", (self->ppp_open ? "registered" : "unregistered")); if(self->ppp_open) { - len += sprintf(buf+len, ", unit: ppp%d", + seq_printf(m, ", unit: ppp%d", ppp_unit_number(&self->chan)); - len += sprintf(buf+len, ", channel: %d", + seq_printf(m, ", channel: %d", ppp_channel_index(&self->chan)); - len += sprintf(buf+len, ", mru: %d", + seq_printf(m, ", mru: %d", self->mru); /* Maybe add self->flags ? Later... */ } @@ -1773,10 +1781,10 @@ irnet_proc_read(char * buf, state = "weird"; else state = "idle"; - len += sprintf(buf+len, "\n IrDA state: %s, ", state); - len += sprintf(buf+len, "daddr: %08x, ", self->daddr); - len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel); - len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel); + seq_printf(m, "\n IrDA state: %s, ", state); + seq_printf(m, "daddr: %08x, ", self->daddr); + seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel); + seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel); /* Next socket, please... */ self = (irnet_socket *) hashbin_get_next(irnet_server.list); @@ -1785,8 +1793,21 @@ irnet_proc_read(char * buf, /* Spin lock end */ spin_unlock_bh(&irnet_server.spinlock); - return len; + return 0; } + +static int irnet_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, irnet_proc_show, NULL); +} + +static const struct file_operations irnet_proc_fops = { + .owner = THIS_MODULE, + .open = irnet_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* PROC_FS */ @@ -1825,7 +1846,7 @@ irda_irnet_init(void) #ifdef CONFIG_PROC_FS /* Add a /proc file for irnet infos */ - create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read); + proc_create("irnet", 0, proc_irda, &irnet_proc_fops); #endif /* CONFIG_PROC_FS */ /* Setup the IrNET server */