aboutsummaryrefslogtreecommitdiff
path: root/net/irda/irnet/irnet_irda.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/irda/irnet/irnet_irda.c')
-rw-r--r--net/irda/irnet/irnet_irda.c173
1 files changed, 96 insertions, 77 deletions
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index 07ec326c71f..7f17a8020e8 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -9,6 +9,31 @@
*/
#include "irnet_irda.h" /* Private header */
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+
+/*
+ * 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 *************************/
/*
@@ -118,7 +143,7 @@ irnet_open_tsap(irnet_socket * self)
/* Open an IrTTP instance */
self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
- &notify);
+ &notify);
DABORT(self->tsap == NULL, -ENOMEM,
IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
@@ -188,7 +213,7 @@ irnet_ias_to_tsap(irnet_socket * self,
if(value->t.integer != -1)
/* Get the remote TSAP selector */
dtsap_sel = value->t.integer;
- else
+ else
self->errno = -EADDRNOTAVAIL;
break;
default:
@@ -213,7 +238,7 @@ irnet_ias_to_tsap(irnet_socket * self,
DEXIT(IRDA_SR_TRACE, "\n");
/* Return the TSAP */
- return(dtsap_sel);
+ return dtsap_sel;
}
/*------------------------------------------------------------------*/
@@ -276,18 +301,18 @@ irnet_connect_tsap(irnet_socket * self)
{
clear_bit(0, &self->ttp_connect);
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
- return(err);
+ return err;
}
/* Connect to remote device */
- err = irttp_connect_request(self->tsap, self->dtsap_sel,
- self->rsaddr, self->daddr, NULL,
+ err = irttp_connect_request(self->tsap, self->dtsap_sel,
+ self->rsaddr, self->daddr, NULL,
self->max_sdu_size_rx, NULL);
if(err != 0)
{
clear_bit(0, &self->ttp_connect);
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
- return(err);
+ return err;
}
/* The above call is non-blocking.
@@ -296,7 +321,7 @@ irnet_connect_tsap(irnet_socket * self)
* See you there ;-) */
DEXIT(IRDA_SR_TRACE, "\n");
- return(err);
+ return err;
}
/*------------------------------------------------------------------*/
@@ -337,10 +362,10 @@ irnet_discover_next_daddr(irnet_socket * self)
/* The above request is non-blocking.
* After a while, IrDA will call us back in irnet_discovervalue_confirm()
* We will then call irnet_ias_to_tsap() and come back here again... */
- return(0);
+ return 0;
}
else
- return(1);
+ return 1;
}
/*------------------------------------------------------------------*/
@@ -411,7 +436,7 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
/* Follow me in irnet_discovervalue_confirm() */
DEXIT(IRDA_SR_TRACE, "\n");
- return(0);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -438,7 +463,7 @@ irnet_dname_to_daddr(irnet_socket * self)
if(discoveries == NULL)
DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
- /*
+ /*
* Now, check all discovered devices (if any), and connect
* client only about the services that the client is
* interested in...
@@ -460,7 +485,7 @@ irnet_dname_to_daddr(irnet_socket * self)
/* No luck ! */
DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
kfree(discoveries);
- return(-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
}
@@ -499,8 +524,10 @@ 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);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -574,7 +601,7 @@ irda_irnet_connect(irnet_socket * self)
* We will finish the connection procedure in irnet_connect_tsap().
*/
DEXIT(IRDA_SOCK_TRACE, "\n");
- return(0);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -627,7 +654,7 @@ irda_irnet_destroy(irnet_socket * self)
/* Unregister with LM-IAS */
if(self->iriap)
- {
+ {
iriap_close(self->iriap);
self->iriap = NULL;
}
@@ -651,7 +678,6 @@ irda_irnet_destroy(irnet_socket * self)
self->stsap_sel = 0;
DEXIT(IRDA_SOCK_TRACE, "\n");
- return;
}
@@ -696,7 +722,7 @@ irnet_daddr_to_dname(irnet_socket * self)
{
/* Yes !!! Get it.. */
strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
- self->rname[NICKNAME_MAX_LEN + 1] = '\0';
+ self->rname[sizeof(self->rname) - 1] = '\0';
DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
self->daddr, self->rname);
kfree(discoveries);
@@ -707,7 +733,7 @@ irnet_daddr_to_dname(irnet_socket * self)
/* No luck ! */
DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
kfree(discoveries);
- return(-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
}
/*------------------------------------------------------------------*/
@@ -901,7 +927,6 @@ irnet_disconnect_server(irnet_socket * self,
irttp_listen(self->tsap);
DEXIT(IRDA_SERV_TRACE, "\n");
- return;
}
/*------------------------------------------------------------------*/
@@ -945,7 +970,7 @@ irnet_setup_server(void)
/* Register with LM-IAS (so that people can connect to us) */
irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
- irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
+ irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
irias_insert_object(irnet_server.ias_obj);
@@ -986,7 +1011,6 @@ irnet_destroy_server(void)
irda_irnet_destroy(&irnet_server.s);
DEXIT(IRDA_SERV_TRACE, "\n");
- return;
}
@@ -1076,7 +1100,7 @@ irnet_data_indication(void * instance,
*/
static void
irnet_disconnect_indication(void * instance,
- void * sap,
+ void * sap,
LM_REASON reason,
struct sk_buff *skb)
{
@@ -1134,15 +1158,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
{
@@ -1166,10 +1183,10 @@ irnet_disconnect_indication(void * instance,
*/
static void
irnet_connect_confirm(void * instance,
- void * sap,
+ void * sap,
struct qos_info *qos,
__u32 max_sdu_size,
- __u8 max_header_size,
+ __u8 max_header_size,
struct sk_buff *skb)
{
irnet_socket * self = (irnet_socket *) instance;
@@ -1235,7 +1252,7 @@ irnet_connect_confirm(void * instance,
static void
irnet_flow_indication(void * instance,
void * sap,
- LOCAL_FLOW flow)
+ LOCAL_FLOW flow)
{
irnet_socket * self = (irnet_socket *) instance;
LOCAL_FLOW oldflow = self->tx_flow;
@@ -1308,13 +1325,13 @@ irnet_status_indication(void * instance,
* Some other node is attempting to connect to the IrNET service, and has
* sent a connection request on our server socket.
* We just redirect the connection to the relevant IrNET socket.
- *
+ *
* Note : we also make sure that between 2 irnet nodes, there can
* exist only one irnet connection.
*/
static void
irnet_connect_indication(void * instance,
- void * sap,
+ void * sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
@@ -1384,8 +1401,8 @@ irnet_connect_indication(void * instance,
/* Socket already connecting ? On primary ? */
if(0
#ifdef ALLOW_SIMULT_CONNECT
- || ((irttp_is_primary(server->tsap) == 1) /* primary */
- && (test_and_clear_bit(0, &new->ttp_connect)))
+ || ((irttp_is_primary(server->tsap) == 1) && /* primary */
+ (test_and_clear_bit(0, &new->ttp_connect)))
#endif /* ALLOW_SIMULT_CONNECT */
)
{
@@ -1463,7 +1480,7 @@ irnet_connect_indication(void * instance,
*/
static void
irnet_getvalue_confirm(int result,
- __u16 obj_id,
+ __u16 obj_id,
struct ias_value *value,
void * priv)
{
@@ -1526,7 +1543,7 @@ irnet_getvalue_confirm(int result,
*/
static void
irnet_discovervalue_confirm(int result,
- __u16 obj_id,
+ __u16 obj_id,
struct ias_value *value,
void * priv)
{
@@ -1645,7 +1662,7 @@ irnet_discovery_indication(discinfo_t * discovery,
void * priv)
{
irnet_socket * self = &irnet_server.s;
-
+
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
"Invalid instance (0x%p) !!!\n", priv);
@@ -1656,7 +1673,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");
}
@@ -1676,7 +1693,7 @@ irnet_expiry_indication(discinfo_t * expiry,
void * priv)
{
irnet_socket * self = &irnet_server.s;
-
+
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
"Invalid instance (0x%p) !!!\n", priv);
@@ -1687,7 +1704,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 +1718,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 +1744,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 +1779,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 +1791,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 */
@@ -1811,7 +1830,7 @@ irda_irnet_init(void)
memset(&irnet_server, 0, sizeof(struct irnet_root));
/* Setup start of irnet instance list */
- irnet_server.list = hashbin_new(HB_NOLOCK);
+ irnet_server.list = hashbin_new(HB_NOLOCK);
DABORT(irnet_server.list == NULL, -ENOMEM,
MODULE_ERROR, "Can't allocate hashbin!\n");
/* Init spinlock for instance list */
@@ -1825,7 +1844,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 */