diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /net/irda/irlpt/irlpt_common.c | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'net/irda/irlpt/irlpt_common.c')
-rw-r--r-- | net/irda/irlpt/irlpt_common.c | 190 |
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) * |