summaryrefslogtreecommitdiffstats
path: root/net/irda/ircomm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
commit59223edaa18759982db0a8aced0e77457d10c68e (patch)
tree89354903b01fa0a447bffeefe00df3044495db2e /net/irda/ircomm
parentdb7d4daea91e105e3859cf461d7e53b9b77454b2 (diff)
Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't
have a MIPS box at hand.
Diffstat (limited to 'net/irda/ircomm')
-rw-r--r--net/irda/ircomm/ircomm_common.c240
-rw-r--r--net/irda/ircomm/irvtd_driver.c191
2 files changed, 258 insertions, 173 deletions
diff --git a/net/irda/ircomm/ircomm_common.c b/net/irda/ircomm/ircomm_common.c
index bc8758e1e..5300f5f3c 100644
--- a/net/irda/ircomm/ircomm_common.c
+++ b/net/irda/ircomm/ircomm_common.c
@@ -8,7 +8,7 @@
* Author: Takahide Higuchi <thiguchi@pluto.dti.ne.jp>
* Source: irlpt_event.c
*
- * Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
+ * Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -41,21 +41,20 @@
#include <net/irda/ircomm_common.h>
-static char *revision_date = "Sun Apr 18 00:40:19 1999";
+static char *revision_date = "Tue May 18 03:11:39 1999";
-static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event,
- struct sk_buff *skb );
-
-static void ircomm_state_discoverywait( struct ircomm_cb *self, IRCOMM_EVENT event,
+static void ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
+ struct sk_buff *skb );
+static void ircomm_state_discoverywait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
+ struct sk_buff *skb );
+static void ircomm_state_queryparamwait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
struct sk_buff *skb );
-
-static void ircomm_state_queryparamwait( struct ircomm_cb *self, IRCOMM_EVENT event,
- struct sk_buff *skb );
-
-static void ircomm_state_querylsapwait( struct ircomm_cb *self, IRCOMM_EVENT event,
- struct sk_buff *skb );
-
+static void ircomm_state_querylsapwait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
+ struct sk_buff *skb );
static void ircomm_state_waiti( struct ircomm_cb *self, IRCOMM_EVENT event,
struct sk_buff *skb );
static void ircomm_state_waitr( struct ircomm_cb *self, IRCOMM_EVENT event,
@@ -206,15 +205,17 @@ __initfunc(int ircomm_init(void))
ircomm[i]->enq_char = 0x05;
ircomm[i]->ack_char = 0x06;
- ircomm[i]->max_txbuff_size = COMM_DEFAULT_DATA_SIZE; /* 64 */
- ircomm[i]->maxsdusize = SAR_DISABLE;
- ircomm[i]->ctrl_skb = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
+ ircomm[i]->max_header_size = COMM_MAX_HEADER_SIZE;
+ ircomm[i]->tx_max_sdu_size = COMM_DEFAULT_SDU_SIZE;
+ ircomm[i]->rx_max_sdu_size = SAR_DISABLE;
+ ircomm[i]->ctrl_skb = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE
+ + COMM_MAX_HEADER_SIZE);
if (ircomm[i]->ctrl_skb == NULL){
DEBUG(0,"ircomm:init_module:alloc_skb failed!\n");
return -ENOMEM;
}
- skb_reserve(ircomm[i]->ctrl_skb,COMM_HEADER_SIZE);
+ skb_reserve(ircomm[i]->ctrl_skb,COMM_MAX_HEADER_SIZE);
}
@@ -226,7 +227,6 @@ __initfunc(int ircomm_init(void))
create_proc_entry("ircomm", 0, proc_irda)->get_info = ircomm_proc_read;
#endif /* CONFIG_PROC_FS */
-
discovering_instance = NULL;
return 0;
}
@@ -275,51 +275,55 @@ void ircomm_cleanup(void)
static int ircomm_accept_data_indication(void *instance, void *sap,
struct sk_buff *skb)
{
-
- struct ircomm_cb *self = (struct ircomm_cb *)instance;
+ struct ircomm_cb *self = (struct ircomm_cb *) instance;
- ASSERT( self != NULL, return -1;);
- ASSERT( self->magic == IRCOMM_MAGIC, return -1;);
- ASSERT( skb != NULL, return -1;);
+ ASSERT(self != NULL, return -1;);
+ ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
+ ASSERT(skb != NULL, return -1;);
DEBUG(4,__FUNCTION__"():\n");
- ircomm_do_event( self, TTP_DATA_INDICATION, skb);
+ ircomm_do_event(self, TTP_DATA_INDICATION, skb);
self->rx_packets++;
return 0;
}
static void ircomm_accept_connect_confirm(void *instance, void *sap,
- struct qos_info *qos,
- __u32 maxsdusize, struct sk_buff *skb)
+ struct qos_info *qos,
+ __u32 max_sdu_size,
+ __u8 max_header_size,
+ struct sk_buff *skb)
{
+ struct ircomm_cb *self = (struct ircomm_cb *) instance;
- struct ircomm_cb *self = (struct ircomm_cb *)instance;
-
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRCOMM_MAGIC, return;);
- ASSERT( skb != NULL, return;);
- ASSERT( qos != NULL, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRCOMM_MAGIC, return;);
+ ASSERT(skb != NULL, return;);
+ ASSERT(qos != NULL, return;);
DEBUG(0,__FUNCTION__"(): got connected!\n");
- if(maxsdusize == SAR_DISABLE)
- self->max_txbuff_size = qos->data_size.value;
+ if (max_sdu_size == SAR_DISABLE)
+ self->tx_max_sdu_size =(qos->data_size.value - max_header_size
+ - COMM_HEADER_SIZE);
else {
- ASSERT(maxsdusize >= COMM_DEFAULT_DATA_SIZE, return;);
- self->max_txbuff_size = maxsdusize; /* use fragmentation */
+ ASSERT(max_sdu_size >= COMM_DEFAULT_SDU_SIZE, return;);
+ /* use fragmentation */
+ self->tx_max_sdu_size = max_sdu_size - COMM_HEADER_SIZE;
}
self->qos = qos;
- self->null_modem_mode = 0; /* disable null modem emulation */
+ self->max_header_size = max_header_size + COMM_HEADER_SIZE;
+ self->null_modem_mode = 0; /* disable null modem emulation */
- ircomm_do_event( self, TTP_CONNECT_CONFIRM, skb);
+ ircomm_do_event(self, TTP_CONNECT_CONFIRM, skb);
}
static void ircomm_accept_connect_indication(void *instance, void *sap,
- struct qos_info *qos,
- __u32 maxsdusize,
- struct sk_buff *skb )
+ struct qos_info *qos,
+ __u32 max_sdu_size,
+ __u8 max_header_size,
+ struct sk_buff *skb)
{
struct ircomm_cb *self = (struct ircomm_cb *)instance;
@@ -330,12 +334,15 @@ static void ircomm_accept_connect_indication(void *instance, void *sap,
DEBUG(0,__FUNCTION__"()\n");
- if(maxsdusize == SAR_DISABLE)
- self->max_txbuff_size = qos->data_size.value;
+ if (max_sdu_size == SAR_DISABLE)
+ self->tx_max_sdu_size =(qos->data_size.value - max_header_size
+ - COMM_HEADER_SIZE);
else
- self->max_txbuff_size = maxsdusize;
+ self->tx_max_sdu_size = max_sdu_size - COMM_HEADER_SIZE;
self->qos = qos;
+ self->max_header_size = max_header_size + COMM_HEADER_SIZE;
+
ircomm_do_event( self, TTP_CONNECT_INDICATION, skb);
/* stop connecting */
@@ -556,7 +563,7 @@ static void issue_connect_request(struct ircomm_cb *self,
irttp_connect_request(self->tsap, self->dlsap,
self->saddr, self->daddr,
- NULL, self->maxsdusize, userdata);
+ NULL, self->rx_max_sdu_size, userdata);
break;
default:
@@ -588,9 +595,10 @@ static void connect_indication(struct ircomm_cb *self, struct qos_info *qos,
/* if( !ircomm_parse_controlchannel( self, data)) */
/* self->servicetype = DEFAULT; TODOD:fix this! TH */
- if(self->notify.connect_indication)
+ if (self->notify.connect_indication)
self->notify.connect_indication(self->notify.instance, self,
- qos, 0, skb);
+ qos, self->tx_max_sdu_size,
+ self->max_header_size, skb);
}
#if 0
@@ -602,28 +610,27 @@ static void connect_indication_three_wire_raw(void)
#endif
-static void connect_confirmation(struct ircomm_cb *self, struct sk_buff *skb)
+static void connect_confirm(struct ircomm_cb *self, struct sk_buff *skb)
{
DEBUG(4 ,__FUNCTION__"()\n");
/* give a connect_confirm to the client */
if( self->notify.connect_confirm )
self->notify.connect_confirm(self->notify.instance,
- self, NULL, SAR_DISABLE, skb);
+ self, NULL, self->tx_max_sdu_size,
+ self->max_header_size, skb);
}
static void issue_connect_response(struct ircomm_cb *self,
struct sk_buff *skb)
{
-
DEBUG(0,__FUNCTION__"()\n");
if( self->servicetype == THREE_WIRE_RAW){
DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented yet\n");
/* irlmp_connect_rsp(); */
- } else {
- irttp_connect_response(self->tsap, self->maxsdusize, skb);
- }
+ } else
+ irttp_connect_response(self->tsap, self->rx_max_sdu_size, skb);
}
static void issue_disconnect_request(struct ircomm_cb *self,
@@ -642,30 +649,29 @@ static void issue_data_request(struct ircomm_cb *self,
{
int err;
- if(self->servicetype == THREE_WIRE_RAW){
+ if (self->servicetype == THREE_WIRE_RAW){
/* irlmp_data_request(self->lmhandle,userdata); */
DEBUG(0,__FUNCTION__"():not implemented!");
return;
}
DEBUG(4,__FUNCTION__"():sending frame\n");
- err = irttp_data_request(self->tsap , userdata );
- if(err){
+ err = irttp_data_request(self->tsap, userdata);
+ if (err){
printk(KERN_ERR __FUNCTION__":ttp_data_request failed\n");
- if(userdata)
+ if (userdata)
dev_kfree_skb( userdata);
}
self->tx_packets++;
}
static void issue_control_request(struct ircomm_cb *self,
- struct sk_buff *userdata )
+ struct sk_buff *userdata)
{
int err;
DEBUG(4,__FUNCTION__"()\n");
- if(self->servicetype == THREE_WIRE_RAW)
- {
+ if (self->servicetype == THREE_WIRE_RAW) {
DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented\n");
}
@@ -676,7 +682,7 @@ static void issue_control_request(struct ircomm_cb *self,
{
printk( __FUNCTION__"():ttp_data_request failed\n");
if(userdata)
- dev_kfree_skb( userdata);
+ dev_kfree_skb(userdata);
}
else
self->tx_controls++;
@@ -701,7 +707,7 @@ static void process_data(struct ircomm_cb *self, struct sk_buff *skb )
/* ircomm_parse_control(self, skb, CONTROL_CHANNEL); */
- if(self->notify.data_indication && skb->len)
+ if (self->notify.data_indication && skb->len)
self->notify.data_indication(self->notify.instance, self,
skb);
}
@@ -728,7 +734,7 @@ static void ircomm_do_event( struct ircomm_cb *self, IRCOMM_EVENT event,
DEBUG( 4, __FUNCTION__": STATE = %s, EVENT = %s\n",
ircommstate[self->state], ircommevent[event]);
- (*state[ self->state ]) ( self, event, skb);
+ (*state[self->state])(self, event, skb);
}
static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state)
@@ -747,7 +753,7 @@ static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state)
static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event,
struct sk_buff *skb )
{
- switch(event){
+ switch (event){
case IRCOMM_CONNECT_REQUEST:
/* ircomm_next_state(self, COMM_WAITI); */
@@ -779,7 +785,8 @@ static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event,
/*
* ircomm_state_discoverywait
*/
-static void ircomm_state_discoverywait(struct ircomm_cb *self, IRCOMM_EVENT event,
+static void ircomm_state_discoverywait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
struct sk_buff *skb )
{
switch(event){
@@ -817,11 +824,11 @@ static void ircomm_state_discoverywait(struct ircomm_cb *self, IRCOMM_EVENT even
* ircomm_state_queryparamwait
*/
-static void ircomm_state_queryparamwait(struct ircomm_cb *self, IRCOMM_EVENT event,
- struct sk_buff *skb )
+static void ircomm_state_queryparamwait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
+ struct sk_buff *skb)
{
- switch(event){
-
+ switch (event) {
case TTP_CONNECT_INDICATION:
ircomm_next_state(self, COMM_WAITR);
@@ -855,10 +862,11 @@ static void ircomm_state_queryparamwait(struct ircomm_cb *self, IRCOMM_EVENT eve
* ircomm_state_querylsapwait
*/
-static void ircomm_state_querylsapwait(struct ircomm_cb *self, IRCOMM_EVENT event,
+static void ircomm_state_querylsapwait(struct ircomm_cb *self,
+ IRCOMM_EVENT event,
struct sk_buff *skb )
{
- switch(event){
+ switch (event) {
case TTP_CONNECT_INDICATION:
@@ -898,10 +906,10 @@ static void ircomm_state_querylsapwait(struct ircomm_cb *self, IRCOMM_EVENT even
static void ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
struct sk_buff *skb )
{
- switch(event){
+ switch (event) {
case TTP_CONNECT_CONFIRM:
ircomm_next_state(self, COMM_CONN);
- connect_confirmation( self, skb );
+ connect_confirm(self, skb );
break;
case TTP_DISCONNECT_INDICATION:
ircomm_next_state(self, COMM_IDLE);
@@ -921,21 +929,18 @@ static void ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
}
}
-
-
/*
* ircomm_state_waitr
*/
static void ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
- struct sk_buff *skb )
+ struct sk_buff *skb )
{
-
- switch(event){
+ switch (event) {
case IRCOMM_CONNECT_RESPONSE:
/* issue_connect_response */
- if(self->servicetype==THREE_WIRE_RAW){
+ if (self->servicetype==THREE_WIRE_RAW) {
DEBUG(0,__FUNCTION__"():3WIRE_RAW is not implemented\n");
/* irlmp_connect_response(Vpeersap,
* ACCEPT,null);
@@ -987,7 +992,7 @@ static void ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
struct sk_buff *skb )
{
- switch(event){
+ switch (event) {
case TTP_DATA_INDICATION:
process_data(self, skb);
break;
@@ -1033,8 +1038,6 @@ static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
}
}
-
-
/*
* ----------------------------------------------------------------------
* IrCOMM service interfaces and supporting functions
@@ -1042,12 +1045,12 @@ static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
* ----------------------------------------------------------------------
*/
-/*
- * start_discovering()
+/*
+ * Function start_discovering (self)
+ *
+ * Start discovering and enter DISCOVERY_WAIT state
*
- * start discovering and enter DISCOVERY_WAIT state
*/
-
static void start_discovering(struct ircomm_cb *self)
{
__u16 hints;
@@ -1058,7 +1061,7 @@ static void start_discovering(struct ircomm_cb *self)
hints = irlmp_service_to_hint(S_COMM);
- DEBUG(0,__FUNCTION__"():start discovering..\n");
+ DEBUG(1,__FUNCTION__"():start discovering..\n");
switch (ircomm_cs) {
case 0:
MOD_INC_USE_COUNT;
@@ -1092,19 +1095,26 @@ static void start_discovering(struct ircomm_cb *self)
/*
* queryias_done(self)
*
- * called when discovery process got wrong results, completed, or terminated.
+ *
*/
+/*
+ * Function queryias_done (self)
+ *
+ * Called when discovery process got wrong results, completed, or
+ * terminated.
+ *
+ */
static void queryias_done(struct ircomm_cb *self)
{
DEBUG(0, __FUNCTION__"():\n");
- if(self->queryias_lock){
+ if (self->queryias_lock){
self->queryias_lock = 0;
discovering_instance = NULL;
MOD_DEC_USE_COUNT;
irlmp_unregister_client(self->ckey);
}
- if(ircomm_cs != 1)
+ if (ircomm_cs != 1)
irlmp_unregister_service(self->skey);
return;
}
@@ -1120,7 +1130,6 @@ static void query_parameters(struct ircomm_cb *self)
ircomm_getvalue_confirm, self );
}
-
static void query_lsapsel(struct ircomm_cb * self)
{
DEBUG(0, __FUNCTION__"():querying IAS: Lsapsel...\n");
@@ -1135,13 +1144,13 @@ static void query_lsapsel(struct ircomm_cb * self)
}
}
-/*
- * ircomm_connect_request()
- * Impl. of this function is differ from one of the reference.
- * This functin does discovery as well as sending connect request
+/*
+ * Function ircomm_connect_request (self, servicetype)
+ *
+ * Impl. of this function is differ from one of the reference. This
+ * function does discovery as well as sending connect request
+ *
*/
-
-
void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
{
/*
@@ -1153,17 +1162,17 @@ void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
ASSERT( self->magic == IRCOMM_MAGIC, return;);
- DEBUG(0, __FUNCTION__"():sending connect_request...\n");
+ DEBUG(1, __FUNCTION__"():sending connect_request...\n");
self->servicetype= servicetype;
/* ircomm_control_request(self, SERVICETYPE); */ /*servictype*/
- self->maxsdusize = SAR_DISABLE;
- ircomm_do_event( self, IRCOMM_CONNECT_REQUEST, NULL);
+ self->rx_max_sdu_size = SAR_DISABLE;
+ ircomm_do_event(self, IRCOMM_CONNECT_REQUEST, NULL);
}
void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
- __u32 maxsdusize)
+ __u32 max_sdu_size)
{
ASSERT( self != NULL, return;);
@@ -1177,20 +1186,20 @@ void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
* and send it with connect_response
*/
- if(!userdata){
+ if (!userdata){
/* FIXME: check for errors and initialize? DB */
- userdata = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
- ASSERT(userdata != NULL, return;);
+ userdata = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE + COMM_MAX_HEADER_SIZE);
+ if (userdata == NULL)
+ return;
- skb_reserve(userdata,COMM_HEADER_SIZE);
+ skb_reserve(userdata,COMM_MAX_HEADER_SIZE);
}
/* enable null-modem emulation (i.e. server mode )*/
self->null_modem_mode = 1;
- self->maxsdusize = maxsdusize;
- if(maxsdusize != SAR_DISABLE)
- self->max_txbuff_size = maxsdusize;
+ self->rx_max_sdu_size = max_sdu_size;
+
ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata);
}
@@ -1303,10 +1312,10 @@ static void ircomm_tx_controlchannel(struct ircomm_cb *self )
ircomm_do_event(self, IRCOMM_CONTROL_REQUEST, skb);
self->control_ch_pending = 0;
- skb = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
+ skb = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE + COMM_MAX_HEADER_SIZE);
ASSERT(skb != NULL, return ;);
- skb_reserve(skb,COMM_HEADER_SIZE);
+ skb_reserve(skb,COMM_MAX_HEADER_SIZE);
self->ctrl_skb = skb;
}
@@ -1341,14 +1350,13 @@ static void append_tuple(struct ircomm_cb *self, __u8 instruction, __u8 pl ,
self->control_ch_pending = 1;
}
-
-
/*
- * ircomm_control_request();
- * this function is exported as a request to send some control-channel tuples
- * to peer device
+ * Function ircomm_control_request (self, instruction)
+ *
+ * This function is exported as a request to send some control-channel
+ * tuples * to peer device
+ *
*/
-
void ircomm_control_request(struct ircomm_cb *self, __u8 instruction)
{
diff --git a/net/irda/ircomm/irvtd_driver.c b/net/irda/ircomm/irvtd_driver.c
index 2df2fdd60..7b1ddf3cb 100644
--- a/net/irda/ircomm/irvtd_driver.c
+++ b/net/irda/ircomm/irvtd_driver.c
@@ -8,7 +8,7 @@
* Source: serial.c by Linus Torvalds
* isdn_tty.c by Fritz Elfert
*
- * Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
+ * Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -51,7 +51,7 @@ struct termios *irvtd_termios_locked[COMM_MAX_TTY];
static int irvtd_refcount;
struct irvtd_cb **irvtd = NULL;
-static char *revision_date = "Sun Apr 18 17:31:53 1999";
+static char *revision_date = "Wed May 26 00:49:11 1999";
/*
@@ -83,8 +83,10 @@ static void irvtd_break(struct tty_struct *tty, int break_state);
static void irvtd_send_xchar(struct tty_struct *tty, char ch);
static void irvtd_wait_until_sent(struct tty_struct *tty, int timeout);
-static void irvtd_start_timer( struct irvtd_cb *driver);
-static void irvtd_timer_expired(unsigned long data);
+static void irvtd_start_tx_timer( struct irvtd_cb *driver, int timeout);
+static void irvtd_tx_timer_expired(unsigned long data);
+static void irvtd_start_rx_timer( struct irvtd_cb *driver, int timeout);
+static void irvtd_rx_timer_expired(unsigned long data);
static int line_info(char *buf, struct irvtd_cb *driver);
static int irvtd_read_proc(char *buf, char **start, off_t offset, int len,
@@ -118,7 +120,7 @@ static void irvtd_write_to_tty( struct irvtd_cb *driver)
if(driver->rx_disable)
return;
- skb = skb_dequeue(&driver->rxbuff);
+ skb = skb_dequeue(&driver->rxbuff);
if(skb == NULL)
return; /* there's nothing */
@@ -211,8 +213,13 @@ static void irvtd_write_to_tty( struct irvtd_cb *driver)
if(skb_queue_len(&driver->rxbuff)< IRVTD_RX_QUEUE_LOW &&
driver->ttp_stoprx){
- irttp_flow_request(driver->comm->tsap, FLOW_START);
+ DEBUG(1, __FUNCTION__"():FLOW_START\n");
+ /*
+ * next 2 lines must follow this order since irttp_flow_request()
+ * will run its rx queue
+ */
driver->ttp_stoprx = 0;
+ irttp_flow_request(driver->comm->tsap, FLOW_START);
}
if(skb_queue_empty(&driver->rxbuff) && driver->disconnect_pend){
@@ -236,10 +243,14 @@ static int irvtd_receive_data(void *instance, void *sap, struct sk_buff *skb)
skb_queue_tail( &driver->rxbuff, skb );
if(skb_queue_len(&driver->rxbuff) > IRVTD_RX_QUEUE_HIGH){
+ DEBUG(1, __FUNCTION__"():FLOW_STOP\n");
irttp_flow_request(driver->comm->tsap, FLOW_STOP);
driver->ttp_stoprx = 1;
}
irvtd_write_to_tty(driver);
+
+ if(!skb_queue_empty(&driver->rxbuff))
+ irvtd_start_rx_timer(driver,0);
return 0;
}
@@ -255,22 +266,36 @@ static int irvtd_receive_data(void *instance, void *sap, struct sk_buff *skb)
*/
-static void irvtd_start_timer( struct irvtd_cb *driver)
+static void irvtd_start_tx_timer( struct irvtd_cb *driver, int timeout)
+{
+ ASSERT( driver != NULL, return;);
+ ASSERT( driver->magic == IRVTD_MAGIC, return;);
+
+ del_timer( &driver->tx_timer);
+
+ driver->tx_timer.data = (unsigned long) driver;
+ driver->tx_timer.function = &irvtd_tx_timer_expired;
+ driver->tx_timer.expires = jiffies + timeout;
+
+ add_timer( &driver->tx_timer);
+}
+
+static void irvtd_start_rx_timer( struct irvtd_cb *driver, int timeout)
{
ASSERT( driver != NULL, return;);
ASSERT( driver->magic == IRVTD_MAGIC, return;);
- del_timer( &driver->timer);
+ del_timer( &driver->rx_timer);
- driver->timer.data = (unsigned long) driver;
- driver->timer.function = &irvtd_timer_expired;
- driver->timer.expires = jiffies + (HZ / 5); /* 200msec */
+ driver->rx_timer.data = (unsigned long) driver;
+ driver->rx_timer.function = &irvtd_rx_timer_expired;
+ driver->rx_timer.expires = jiffies + timeout;
- add_timer( &driver->timer);
+ add_timer( &driver->rx_timer);
}
-static void irvtd_timer_expired(unsigned long data)
+static void irvtd_tx_timer_expired(unsigned long data)
{
struct irvtd_cb *driver = (struct irvtd_cb *)data;
@@ -279,11 +304,26 @@ static void irvtd_timer_expired(unsigned long data)
DEBUG(4, __FUNCTION__"()\n");
irvtd_send_data_request(driver);
+}
- irvtd_write_to_tty(driver);
+static void irvtd_rx_timer_expired(unsigned long data)
+{
+ struct irvtd_cb *driver = (struct irvtd_cb *)data;
+
+ ASSERT(driver != NULL,return;);
+ ASSERT(driver->magic == IRVTD_MAGIC,return;);
+ DEBUG(4, __FUNCTION__"()\n");
- /* start our timer again and again */
- irvtd_start_timer(driver);
+ while(TTY_FLIPBUF_SIZE - driver->tty->flip.count
+ && !skb_queue_empty(&driver->rxbuff))
+ irvtd_write_to_tty(driver);
+
+ DEBUG(1, __FUNCTION__"(): room in flip_buffer = %d\n",
+ TTY_FLIPBUF_SIZE - driver->tty->flip.count);
+
+ if(!skb_queue_empty(&driver->rxbuff))
+ /* handle it later */
+ irvtd_start_rx_timer(driver, 1);
}
@@ -310,21 +350,23 @@ static void irvtd_send_data_request(struct irvtd_cb *driver)
}
#endif
- DEBUG(1, __FUNCTION__"():sending %d octets\n",(int)skb->len );
+ DEBUG(1, __FUNCTION__"():len = %d, room = %d\n",(int)skb->len,
+ skb_tailroom(skb));
driver->icount.tx += skb->len;
err = ircomm_data_request(driver->comm, driver->txbuff);
if (err){
ASSERT(err == 0,;);
- DEBUG(0,"%d chars are lost\n",(int)skb->len);
+ DEBUG(1,"%d chars are lost\n",(int)skb->len);
skb_trim(skb, 0);
}
/* allocate a new frame */
- skb = driver->txbuff = dev_alloc_skb(driver->comm->max_txbuff_size);
+ skb = driver->txbuff
+ = dev_alloc_skb(driver->tx_max_sdu_size + driver->max_header_size);
if (skb == NULL){
printk(__FUNCTION__"():alloc_skb failed!\n");
} else {
- skb_reserve(skb, COMM_HEADER_SIZE);
+ skb_reserve(skb, driver->max_header_size);
}
wake_up_interruptible(&driver->tty->write_wait);
@@ -341,20 +383,23 @@ static void irvtd_send_data_request(struct irvtd_cb *driver)
***********************************************************************
*/
-
/*
* Function irvtd_connect_confirm (instance, sap, qos, max_sdu_size, skb)
*
- * ircomm_connect_request which we have send have succeed!
+ * ircomm_connect_request which we have send, has succeeded!
*
*/
void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
- __u32 max_sdu_size, struct sk_buff *skb)
+ __u32 max_sdu_size, __u8 max_header_size,
+ struct sk_buff *skb)
{
struct irvtd_cb *driver = (struct irvtd_cb *)instance;
ASSERT(driver != NULL, return;);
ASSERT(driver->magic == IRVTD_MAGIC, return;);
+
+ driver->tx_max_sdu_size = max_sdu_size;
+ driver->max_header_size = max_header_size;
/*
* set default value
*/
@@ -364,7 +409,7 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
/*
* sending initial control parameters here
*/
- if(driver->comm->servicetype == THREE_WIRE_RAW)
+ if (driver->comm->servicetype == THREE_WIRE_RAW)
return; /* do nothing */
driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
@@ -376,7 +421,7 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
ircomm_control_request(driver->comm, XON_XOFF_CHAR);
/* ircomm_control_request(driver->comm, ENQ_ACK_CHAR); */
- switch(driver->comm->servicetype){
+ switch (driver->comm->servicetype) {
case CENTRONICS:
break;
@@ -397,17 +442,20 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
*
*/
void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
- __u32 max_sdu_size, struct sk_buff *skb)
+ __u32 max_sdu_size, __u8 max_header_size,
+ struct sk_buff *skb)
{
-
struct irvtd_cb *driver = (struct irvtd_cb *)instance;
struct ircomm_cb *comm = (struct ircomm_cb *)sap;
+
ASSERT(driver != NULL, return;);
ASSERT(driver->magic == IRVTD_MAGIC, return;);
ASSERT(comm != NULL, return;);
ASSERT(comm->magic == IRCOMM_MAGIC, return;);
- DEBUG(4,"irvtd_connect_indication:sending connect_response...\n");
+ driver->tx_max_sdu_size = max_sdu_size;
+ driver->max_header_size = max_header_size;
+ DEBUG(4, __FUNCTION__ "():sending connect_response...\n");
ircomm_connect_response(comm, NULL, SAR_DISABLE );
@@ -416,7 +464,7 @@ void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
/*
* send initial control parameters
*/
- if(driver->comm->servicetype == THREE_WIRE_RAW)
+ if (driver->comm->servicetype == THREE_WIRE_RAW)
return; /* do nothing */
driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
@@ -426,6 +474,7 @@ void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
ircomm_control_request(driver->comm, DTELINE_STATE);
break;
default:
+ DEBUG(0, __FUNCTION__ "(), not implemented!\n");
}
@@ -479,11 +528,12 @@ void irvtd_control_indication(void *instance, void *sap, IRCOMM_CMD cmd)
if(cmd == TX_READY){
driver->ttp_stoptx = 0;
driver->tty->hw_stopped = driver->cts_stoptx;
- irvtd_start_timer( driver);
if(driver->cts_stoptx)
return;
+ /* push tx queue so that client can send at least 1 octet */
+ irvtd_send_data_request(driver);
/*
* driver->tty->write_wait will keep asleep if
* our txbuff is full.
@@ -498,7 +548,7 @@ void irvtd_control_indication(void *instance, void *sap, IRCOMM_CMD cmd)
if(cmd == TX_BUSY){
driver->ttp_stoptx = driver->tty->hw_stopped = 1;
- del_timer( &driver->timer);
+ del_timer( &driver->tx_timer);
return;
}
@@ -576,6 +626,7 @@ void irvtd_control_indication(void *instance, void *sap, IRCOMM_CMD cmd)
case DATA_RATE:
case XON_XOFF_CHAR:
case DTELINE_STATE:
+ case ENQ_ACK_CHAR: /* got this from win95 */
/* (maybe) nothing to do */
break;
default:
@@ -607,7 +658,7 @@ static int irvtd_block_til_ready(struct tty_struct *tty, struct file * filp,
struct irvtd_cb *driver)
{
- struct wait_queue wait = { current, NULL };
+ DECLARE_WAITQUEUE(wait,current);
int retval = 0;
int do_clocal = 0;
@@ -678,7 +729,7 @@ static int irvtd_block_til_ready(struct tty_struct *tty, struct file * filp,
driver->blocked_open--;
- DEBUG(0, __FUNCTION__"():after blocking\n");
+ DEBUG(1, __FUNCTION__"():after blocking\n");
if (retval)
return retval;
@@ -765,7 +816,7 @@ static int irvtd_startup(struct irvtd_cb *driver)
struct notify_t irvtd_notify;
/* FIXME: it should not be hard coded */
- __u8 oct_seq[6] = { 0,1,4,1,1,1 };
+ __u8 oct_seq[6] = { 0,1,6,1,1,1 };
DEBUG(4,__FUNCTION__"()\n" );
if(driver->flags & ASYNC_INITIALIZED)
@@ -776,12 +827,12 @@ static int irvtd_startup(struct irvtd_cb *driver)
*/
skb_queue_head_init(&driver->rxbuff);
- driver->txbuff = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
+ driver->txbuff = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE + COMM_MAX_HEADER_SIZE);
if (!driver->txbuff){
- DEBUG(0,__FUNCTION__"():alloc_skb failed!\n");
+ DEBUG(0,__FUNCTION__"(), alloc_skb failed!\n");
return -ENOMEM;
}
- skb_reserve(driver->txbuff, COMM_HEADER_SIZE);
+ skb_reserve(driver->txbuff, COMM_MAX_HEADER_SIZE);
irda_notify_init(&irvtd_notify);
irvtd_notify.data_indication = irvtd_receive_data;
@@ -793,9 +844,8 @@ static int irvtd_startup(struct irvtd_cb *driver)
irvtd_notify.instance = driver;
driver->comm = ircomm_open_instance(irvtd_notify);
- if(!driver->comm){
+ if (!driver->comm)
return -ENODEV;
- }
/*
@@ -811,22 +861,20 @@ static int irvtd_startup(struct irvtd_cb *driver)
driver->flags |= ASYNC_INITIALIZED;
- /*
- * discover a peer device
- * TODO: other servicetype(i.e. 3wire,3wireraw) support
- */
- ircomm_connect_request(driver->comm, NINE_WIRE);
-
- /*
- * TODO:we have to initialize control-channel here!
- * i.e.set something into RTS,CTS and so on....
- */
-
if (driver->tty)
clear_bit(TTY_IO_ERROR, &driver->tty->flags);
change_speed(driver);
- irvtd_start_timer( driver);
+
+ /*
+ * discover a peer device
+ */
+ if(driver->tty->termios->c_cflag & CRTSCTS)
+ ircomm_connect_request(driver->comm, NINE_WIRE);
+ else
+ ircomm_connect_request(driver->comm, THREE_WIRE);
+
+ /* irvtd_start_timer( driver); */
driver->rx_disable = 0;
driver->tx_disable = 1;
@@ -989,7 +1037,8 @@ static void irvtd_shutdown(struct irvtd_cb * driver)
if (driver->tty)
set_bit(TTY_IO_ERROR, &driver->tty->flags);
- del_timer( &driver->timer);
+ del_timer( &driver->tx_timer);
+ del_timer( &driver->rx_timer);
irias_delete_object("IrDA:IrCOMM");
@@ -1144,13 +1193,21 @@ int irvtd_write(struct tty_struct * tty, int from_user,
DEBUG(4, __FUNCTION__"()\n");
save_flags(flags);
- while(1){
+ while(count > 0){
cli();
skb = driver->txbuff;
ASSERT(skb != NULL, break;);
c = MIN(count, (skb_tailroom(skb)));
if (c <= 0)
- break;
+ {
+ if(!driver->ttp_stoptx)
+ {
+ irvtd_send_data_request(driver);
+ continue;
+ }
+ else
+ break;
+ }
/* write to the frame */
@@ -1164,9 +1221,9 @@ int irvtd_write(struct tty_struct * tty, int from_user,
wrote += c;
count -= c;
buf += c;
- irvtd_send_data_request(driver);
}
restore_flags(flags);
+ irvtd_send_data_request(driver);
return (wrote);
}
@@ -1199,19 +1256,27 @@ void irvtd_put_char(struct tty_struct *tty, unsigned char ch)
DEBUG(4, __FUNCTION__"()\n");
+ again:
save_flags(flags);cli();
skb = driver->txbuff;
ASSERT(skb != NULL,return;);
+ if(!skb_tailroom(skb))
+ {
+ restore_flags(flags);
+ irvtd_send_data_request(driver);
+ goto again;
+ }
ASSERT(skb_tailroom(skb) > 0, return;);
- DEBUG(4, "irvtd_put_char(0x%02x) skb_len(%d) MAX(%d):\n",
+ DEBUG(4, "irvtd_put_char(0x%02x) skb_len(%d) room(%d):\n",
(int)ch ,(int)skb->len,
- driver->comm->max_txbuff_size - COMM_HEADER_SIZE);
+ skb_tailroom(skb));
/* append a character */
frame = skb_put(skb,1);
frame[0] = ch;
restore_flags(flags);
+ irvtd_start_tx_timer(driver,20);
return;
}
@@ -1635,6 +1700,7 @@ void irvtd_throttle(struct tty_struct *tty){
driver->comm->dte = driver->mcr;
ircomm_control_request(driver->comm, DTELINE_STATE );
+ DEBUG(1, __FUNCTION__"():FLOW_STOP\n");
irttp_flow_request(driver->comm->tsap, FLOW_STOP);
}
@@ -1649,6 +1715,7 @@ void irvtd_unthrottle(struct tty_struct *tty){
driver->comm->dte = driver->mcr;
ircomm_control_request(driver->comm, DTELINE_STATE );
+ DEBUG(1, __FUNCTION__"():FLOW_START\n");
irttp_flow_request(driver->comm->tsap, FLOW_START);
}
@@ -1859,6 +1926,12 @@ static int line_info(char *buf, struct irvtd_cb *driver)
if (driver->msr & MSR_RI)
ret += sprintf(buf+ret, "|RI");
+ ret += sprintf(buf+ret, "\n");
+ ret += sprintf(buf+ret, "rx queue:%d",
+ skb_queue_len( &driver->rxbuff));
+ ret += sprintf(buf+ret, "ttp_stoprx:%s",
+ driver->ttp_stoprx?"TRUE":"FALSE");
+
exit:
ret += sprintf(buf+ret, "\n");
return ret;
@@ -1930,6 +2003,10 @@ __initfunc(int irvtd_init(void))
irvtd[i]->line = i;
irvtd[i]->closing_wait = 10*HZ ;
irvtd[i]->close_delay = 5*HZ/10 ;
+ init_waitqueue_head(&irvtd[i]->open_wait);
+ init_waitqueue_head(&irvtd[i]->close_wait);
+ init_waitqueue_head(&irvtd[i]->tx_wait);
+ init_waitqueue_head(&irvtd[i]->delta_msr_wait);
}
/*