summaryrefslogtreecommitdiffstats
path: root/net/irda/irlpt/irlpt_common.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
commitdb7d4daea91e105e3859cf461d7e53b9b77454b2 (patch)
tree9bb65b95440af09e8aca63abe56970dd3360cc57 /net/irda/irlpt/irlpt_common.c
parent9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff)
Merge with Linux 2.2.8.
Diffstat (limited to 'net/irda/irlpt/irlpt_common.c')
-rw-r--r--net/irda/irlpt/irlpt_common.c190
1 files changed, 94 insertions, 96 deletions
diff --git a/net/irda/irlpt/irlpt_common.c b/net/irda/irlpt/irlpt_common.c
index 886eb30a0..b4512736a 100644
--- a/net/irda/irlpt/irlpt_common.c
+++ b/net/irda/irlpt/irlpt_common.c
@@ -68,7 +68,7 @@ char *irlpt_connected[] = {
char *irlpt_reasons[] = {
"SERVICE_CLOSE", /* Service has closed the connection */
- "DISC_INDICATION", /* Received a disconnect request from peer entity*/
+ "DISC_INDICATION", /* Received disconnect request from peer entity*/
"NO_RESPONSE", /* To many retransmits without response */
"DEADLOCK_DETECTED", /* To many retransmits _with_ response */
"FOUND_NONE", /* No devices were discovered */
@@ -81,7 +81,6 @@ char *irlpt_client_fsm_state[] = {
"IRLPT_CLIENT_QUERY",
"IRLPT_CLIENT_READY",
"IRLPT_CLIENT_WAITI",
- "IRLPT_CLIENT_WAITR",
"IRLPT_CLIENT_CONN"
};
@@ -108,9 +107,8 @@ char *irlpt_fsm_event[] = {
hashbin_t *irlpt_clients = NULL;
struct irlpt_cb *irlpt_server = NULL;
int irlpt_common_debug = 4; /* want to change this? please don't!
- use irlpt_common_debug=3 on the command line! */
-
-static struct wait_queue *irlpt_wait;
+ use irlpt_common_debug=3 on the
+ command line! */
#if 0
static char *rcsid = "$Id: irlpt_common.c,v 1.6 1998/11/10 22:50:58 dagb Exp $";
@@ -152,7 +150,6 @@ ssize_t irlpt_read( struct file *file, char *buffer, size_t count, loff_t
char *ptr = buffer;
struct irlpt_cb *self;
struct sk_buff *skb = NULL;
- struct wait_queue wait = { current, NULL };
DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
@@ -170,11 +167,12 @@ ssize_t irlpt_read( struct file *file, char *buffer, size_t count, loff_t
switch (self->eof) {
case LM_USER_REQUEST:
self->eof = FALSE;
- DEBUG(3, "irlpt_read: returning 0\n");
+ DEBUG(irlpt_common_debug,
+ __FUNCTION__ ": returning 0\n");
return 0;
case LM_LAP_DISCONNECT:
self->eof = FALSE;
- return -EIO;
+ return 0;
case LM_LAP_RESET:
self->eof = FALSE;
return -ECONNRESET;
@@ -208,11 +206,7 @@ ssize_t irlpt_read( struct file *file, char *buffer, size_t count, loff_t
len, count, self->eof);
if (!signal_pending(current) && !self->eof) {
- add_wait_queue(&irlpt_wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&irlpt_wait, &wait);
+ interruptible_sleep_on(&self->read_wait);
} else
break;
}
@@ -228,7 +222,6 @@ ssize_t irlpt_write(struct file *file, const char *buffer,
{
struct irlpt_cb *self;
struct sk_buff *skb;
- struct wait_queue wait = { current, NULL };
DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
@@ -240,26 +233,25 @@ ssize_t irlpt_write(struct file *file, const char *buffer,
DEBUG( irlpt_common_debug, __FUNCTION__
": count = %d\n", count);
- if (self->state != IRLPT_CLIENT_CONN) {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": pkt_count = %d\n", self->pkt_count);
+ if (self->pkt_count > 8) {
DEBUG( irlpt_common_debug, __FUNCTION__
- ": state != IRLPT_CONN (possible link problems?)\n");
- return -ENOLINK;
+ ": too many outstanding buffers, going to sleep\n");
+ interruptible_sleep_on(&self->write_wait);
}
DEBUG( irlpt_common_debug, __FUNCTION__
": pkt_count = %d\n", self->pkt_count);
- if (self->pkt_count > 8) {
+
+ if (self->state != IRLPT_CLIENT_CONN) {
DEBUG( irlpt_common_debug, __FUNCTION__
- ": too many outstanding buffers, going to sleep\n");
- add_wait_queue(&self->write_wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&self->write_wait, &wait);
+ ": state != IRLPT_CONN (possible link problems?)\n");
+ return -ENOLINK;
}
DEBUG( irlpt_common_debug, __FUNCTION__
- ":count = %d, irlap_data_size = %d, IRLPT_MAX_HEADER = %d\n",
+ ": count = %d, irlap_data_size = %d, IRLPT_MAX_HEADER = %d\n",
count, self->irlap_data_size, IRLPT_MAX_HEADER);
if (count > (self->irlap_data_size - IRLPT_MAX_HEADER)) {
@@ -272,7 +264,8 @@ ssize_t irlpt_write(struct file *file, const char *buffer,
skb = dev_alloc_skb(count + IRLPT_MAX_HEADER);
if ( skb == NULL) {
- printk( KERN_INFO __FUNCTION__ ": couldn't allocate skbuff!\n");
+ printk( KERN_INFO
+ __FUNCTION__ ": couldn't allocate skbuff!\n");
return 0;
}
@@ -292,6 +285,9 @@ ssize_t irlpt_write(struct file *file, const char *buffer,
irlmp_data_request(self->lsap, skb);
+ irda_start_timer( &self->lpt_timer, 5000, (unsigned long) self,
+ self->timeout);
+
DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
return(count);
@@ -305,60 +301,13 @@ loff_t irlpt_seek( struct file *file, loff_t offset, int count)
return -ESPIPE;
}
-#if 0
-
/*
- * Function irlpt_select (inode, filp, mode, table)
- *
- * Implementation for the select() call
- *
- */
-int irlpt_select( struct inode *inode, struct file *filp, int mode,
- select_table *table)
-{
- struct irlpt_cb *self;
-
- DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
-
- self = irlpt_find_handle(MINOR( inode->i_rdev));
-
- ASSERT( self != NULL, return -1;);
- ASSERT( self->magic == IRLPT_MAGIC, return -1;);
-
- switch (mode) {
- case SEL_IN:
- if ( skb_queue_len( &self->rx_queue))
- return 1; /* Readable */
- select_wait( &self->read_wait, table);
- break;
- case SEL_OUT:
- if ( self->connected)
- return 1;
- select_wait( &self->write_wait, table);
- break;
- case SEL_EX:
- if ( self->connected)
- return 1;
- select_wait( &self->ex_wait, table);
- break;
- default:
- break;
- }
-
- DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
-
- return 0;
-}
-
-#else
-
-/*
- * Function irobex_poll (file, wait)
+ * Function irlpt_poll (file, wait)
*
*
*
*/
-static u_int irlpt_poll(struct file *file, poll_table *wait)
+u_int irlpt_poll(struct file *file, poll_table *wait)
{
DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
@@ -367,8 +316,6 @@ static u_int irlpt_poll(struct file *file, poll_table *wait)
return 0;
}
-#endif
-
/*
* Function open_irlpt (inode, file)
*
@@ -378,6 +325,7 @@ static u_int irlpt_poll(struct file *file, poll_table *wait)
int irlpt_open(struct inode *inode, struct file *file)
{
struct irlpt_cb *self;
+ struct irlpt_info info;
DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
@@ -386,22 +334,6 @@ int irlpt_open(struct inode *inode, struct file *file)
ASSERT( self != NULL, return -1;);
ASSERT( self->magic == IRLPT_MAGIC, return -1;);
-#if 0
- if (self->state == IRLPT_IDLE) {
- DEBUG( irlpt_common_debug, __FUNCTION__
- ": state == IRLPT_IDLE! (no device found yet)\n");
- return -ENODEV;
- }
-
- if (self->state == IRLPT_QUERY ||
- self->state == IRLPT_READY ||
- self->state == IRLPT_WAITI) {
- DEBUG( irlpt_common_debug, __FUNCTION__ ": state == IRLPT_QUERY, "
- "IRLPT_READY or IRLPT_WAITI (link problems)!\n");
- return -EBUSY;
- }
-#endif
-
if (self->count++) {
DEBUG( irlpt_common_debug, __FUNCTION__
": count not zero; actual = %d\n", self->count);
@@ -409,6 +341,35 @@ int irlpt_open(struct inode *inode, struct file *file)
return -EBUSY;
}
+ self->eof = FALSE;
+
+ /* ok, now, if it's idle, try to get some information
+ about the remote end, and sleep till we get totally connected.. */
+
+ if ((self->servicetype != IRLPT_SERVER_MODE) &&
+ self->state != IRLPT_CLIENT_CONN) {
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": self->state != IRLPT_CLIENT_CONN\n");
+
+ info.daddr = self->daddr;
+ info.saddr = self->saddr;
+
+ if (self->do_event != NULL) {
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": doing a discovery..\n");
+ self->do_event( self,
+ IRLPT_DISCOVERY_INDICATION,
+ NULL, &info);
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": sleeping until connected.\n");
+ interruptible_sleep_on(&self->read_wait);
+ }
+ }
+
+ /* at this point, if it's a client, we have a connection.
+ * if it's the server, it's waiting for a connection.
+ */
+
DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
return 0;
@@ -420,9 +381,12 @@ int irlpt_open(struct inode *inode, struct file *file)
*
*
*/
-int irlpt_close(struct inode *inode, struct file *file)
+int irlpt_close(struct inode *inode,
+ struct file *file)
{
struct irlpt_cb *self;
+ struct sk_buff *skb;
+ struct irlpt_info info;
DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
@@ -433,12 +397,42 @@ int irlpt_close(struct inode *inode, struct file *file)
ASSERT( self != NULL, return -1;);
ASSERT( self->magic == IRLPT_MAGIC, return -1;);
- DEBUG(irlpt_common_debug, __FUNCTION__ ": self->count=%d\n", self->count);
+ DEBUG(irlpt_common_debug,
+ __FUNCTION__ ": self->count=%d\n", self->count);
+
if (self->count > 0)
self->count--;
- DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+ while (self->pkt_count > 0) {
+ interruptible_sleep_on(&self->write_wait);
+ }
+
+ /* all done, tear down the connection and wait for the next open */
+ if ((self->servicetype != IRLPT_SERVER_MODE) &&
+ self->state == IRLPT_CLIENT_CONN) {
+ skb = dev_alloc_skb(64);
+ if (skb == NULL) {
+ DEBUG( 0, __FUNCTION__ "(: Could not allocate an "
+ "sk_buff of length %d\n", 64);
+ return 0;
+ }
+
+ skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+ irlmp_disconnect_request(self->lsap, skb);
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": irlmp_close_slap(self->lsap)\n");
+ irlmp_close_lsap(self->lsap);
+ }
+
+ info.daddr = self->daddr;
+ if (self->do_event != NULL) {
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": closing connection..\n");
+ self->do_event( self, LMP_DISCONNECT, NULL, &info);
+ }
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
return 0;
}
@@ -486,6 +480,10 @@ void irlpt_flow_control(struct sk_buff *skb)
#ifdef MODULE
+MODULE_AUTHOR("Thomas Davis <ratbert@radiks.net>");
+MODULE_DESCRIPTION("The Linux IrDA/IrLPT common");
+MODULE_PARM(irlpt_common_debug,"1i");
+
/*
* Function init_module (void)
*