diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
commit | 99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch) | |
tree | 3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /net/irda/ircomm | |
parent | e73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff) |
Merge with Linux 2.3.38.
Diffstat (limited to 'net/irda/ircomm')
-rw-r--r-- | net/irda/ircomm/ircomm_core.c | 43 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_event.c | 12 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_lmp.c | 17 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_param.c | 141 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_ttp.c | 28 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty.c | 292 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_attach.c | 143 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_ioctl.c | 106 |
8 files changed, 471 insertions, 311 deletions
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index ed45a509f..805186128 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 20:37:34 1999 - * Modified at: Sat Oct 30 12:48:14 1999 + * Modified at: Tue Dec 21 13:26:41 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -144,16 +144,14 @@ static int __ircomm_close(struct ircomm_cb *self) { IRDA_DEBUG(2, __FUNCTION__"()\n"); - ASSERT(self != NULL, return -EIO;); - ASSERT(self->magic == IRCOMM_MAGIC, return -EIO;); - /* Disconnect link if any */ ircomm_do_event(self, IRCOMM_DISCONNECT_REQUEST, NULL, NULL); /* Remove TSAP */ - if (self->tsap) + if (self->tsap) { irttp_close_tsap(self->tsap); - self->tsap = NULL; + self->tsap = NULL; + } /* Remove LSAP */ if (self->lsap) { @@ -177,6 +175,11 @@ int ircomm_close(struct ircomm_cb *self) { struct ircomm_cb *entry; + ASSERT(self != NULL, return -EIO;); + ASSERT(self->magic == IRCOMM_MAGIC, return -EIO;); + + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + entry = hashbin_remove(ircomm, self->line, NULL); ASSERT(entry == self, return -1;); @@ -236,14 +239,14 @@ void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb, * deliver it first. The side effect is that the control channel * will be removed from the skb */ -#if 0 - if (clen > 0) - ircomm_control_indication(self, skb, clen); -#endif if (self->notify.connect_indication) self->notify.connect_indication(self->notify.instance, self, info->qos, info->max_data_size, info->max_header_size, skb); + else { + IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n"); + dev_kfree_skb(skb); + } } /* @@ -282,6 +285,10 @@ void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb, self, info->qos, info->max_data_size, info->max_header_size, skb); + else { + IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n"); + dev_kfree_skb(skb); + } } /* @@ -319,6 +326,10 @@ void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb) if (self->notify.data_indication) self->notify.data_indication(self->notify.instance, self, skb); + else { + IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n"); + dev_kfree_skb(skb); + } } /* @@ -349,7 +360,8 @@ void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb) if (skb->len) ircomm_data_indication(self, skb); else { - IRDA_DEBUG(4, __FUNCTION__ "(), data was control info only!\n"); + IRDA_DEBUG(4, __FUNCTION__ + "(), data was control info only!\n"); dev_kfree_skb(skb); } } @@ -399,6 +411,10 @@ static void ircomm_control_indication(struct ircomm_cb *self, if (self->notify.udata_indication) self->notify.udata_indication(self->notify.instance, self, ctrl_skb); + else { + IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n"); + dev_kfree_skb(skb); + } } /* @@ -438,6 +454,9 @@ void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb, if (self->notify.disconnect_indication) { self->notify.disconnect_indication(self->notify.instance, self, info->reason, skb); + } else { + IRDA_DEBUG(0, __FUNCTION__ "(), missing handler\n"); + dev_kfree_skb(skb); } } @@ -462,7 +481,7 @@ void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow) #ifdef CONFIG_PROC_FS /* - * Function ircomm_proc_read (buf, start, offset, len) + * Function ircomm_proc_read (buf, start, offset, len, unused) * * * diff --git a/net/irda/ircomm/ircomm_event.c b/net/irda/ircomm/ircomm_event.c index 7e2bdd50a..5b43be858 100644 --- a/net/irda/ircomm/ircomm_event.c +++ b/net/irda/ircomm/ircomm_event.c @@ -3,10 +3,10 @@ * Filename: ircomm_event.c * Version: 1.0 * Description: IrCOMM layer state machine - * Status: Experimental. + * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 20:33:11 1999 - * Modified at: Sat Oct 30 13:05:23 1999 + * Modified at: Sun Dec 12 13:44:32 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -109,6 +109,8 @@ static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, default: IRDA_DEBUG(4, __FUNCTION__"(), unknown event: %s\n", ircomm_event[event]); + if (skb) + dev_kfree_skb(skb); return -EINVAL; } return ret; @@ -139,6 +141,8 @@ static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, default: IRDA_DEBUG(0, __FUNCTION__"(), unknown event: %s\n", ircomm_event[event]); + if (skb) + dev_kfree_skb(skb); ret = -EINVAL; } return ret; @@ -172,6 +176,8 @@ static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, default: IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n", ircomm_event[event]); + if (skb) + dev_kfree_skb(skb); ret = -EINVAL; } return ret; @@ -214,6 +220,8 @@ static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, default: IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n", ircomm_event[event]); + if (skb) + dev_kfree_skb(skb); ret = -EINVAL; } return ret; diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c index bf35c75e0..ca4526260 100644 --- a/net/irda/ircomm/ircomm_lmp.c +++ b/net/irda/ircomm/ircomm_lmp.c @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: ircomm_lmp.c - * Version: + * Version: 1.0 * Description: Interface between IrCOMM and IrLMP - * Status: Experimental. + * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 20:48:27 1999 - * Modified at: Sat Oct 30 12:55:24 1999 + * Modified at: Sun Dec 12 13:44:17 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: Previous IrLPT work by Thomas Davis * @@ -60,7 +60,7 @@ int ircomm_open_lsap(struct ircomm_cb *self) notify.instance = self; strncpy(notify.name, "IrCOMM", NOTIFY_MAX_NAME); - self->lsap = irlmp_open_lsap(LSAP_ANY, ¬ify); + self->lsap = irlmp_open_lsap(LSAP_ANY, ¬ify, 0); if (!self->lsap) { IRDA_DEBUG(0,__FUNCTION__"failed to allocate tsap\n"); return -1; @@ -128,11 +128,8 @@ int ircomm_lmp_disconnect_request(struct ircomm_cb *self, if (!skb) return -ENOMEM; - /* - * Reserve space for MUX and LAP header - */ - skb_reserve(skb, LMP_MAX_HEADER); - + /* Reserve space for MUX and LAP header */ + skb_reserve(skb, LMP_MAX_HEADER); userdata = skb; } ret = irlmp_disconnect_request(self->lsap, userdata); @@ -323,5 +320,3 @@ void ircomm_lmp_disconnect_indication(void *instance, void *sap, ircomm_do_event(self, IRCOMM_LMP_DISCONNECT_INDICATION, skb, &info); } - - diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index 382027892..3c9ff35da 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Jun 7 10:25:11 1999 - * Modified at: Sat Oct 30 13:05:42 1999 + * Modified at: Tue Dec 14 15:26:30 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -28,6 +28,9 @@ * ********************************************************************/ +#include <linux/sched.h> +#include <linux/interrupt.h> + #include <net/irda/irda.h> #include <net/irda/parameters.h> @@ -67,7 +70,7 @@ static pi_minor_info_t pi_minor_call_table_non_raw[] = { static pi_minor_info_t pi_minor_call_table_9_wire[] = { { ircomm_param_dte, PV_INT_8_BITS }, { ircomm_param_dce, PV_INT_8_BITS }, - { ircomm_param_poll, PV_INT_8_BITS }, + { ircomm_param_poll, PV_NO_VALUE }, }; static pi_major_info_t pi_major_call_table[] = { @@ -102,6 +105,7 @@ int ircomm_param_flush(struct ircomm_tty_cb *self) */ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) { + struct tty_struct *tty; unsigned long flags; struct sk_buff *skb; int count; @@ -111,10 +115,9 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - if (self->state != IRCOMM_TTY_READY) { - IRDA_DEBUG(2, __FUNCTION__ "(), not ready yet!\n"); + tty = self->tty; + if (!tty) return 0; - } /* Make sure we don't send parameters for raw mode */ if (self->service_type == IRCOMM_3_WIRE_RAW) @@ -132,8 +135,7 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) } skb_reserve(skb, self->max_header_size); - - self->ctrl_skb = skb; + self->ctrl_skb = skb; } /* * Inserting is a little bit tricky since we don't know how much @@ -142,17 +144,22 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) count = irda_param_insert(self, pi, skb->tail, skb_tailroom(skb), &ircomm_param_info); if (count < 0) { - IRDA_DEBUG(0, __FUNCTION__ "(), no room for parameter!\n"); + WARNING(__FUNCTION__ "(), no room for parameter!\n"); restore_flags(flags); return -1; } skb_put(skb, count); + restore_flags(flags); + IRDA_DEBUG(2, __FUNCTION__ "(), skb->len=%d\n", skb->len); + if (flush) { - ircomm_control_request(self->ircomm, skb); - self->ctrl_skb = NULL; + /* ircomm_tty_do_softint will take care of the rest */ + queue_task(&self->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); } + return count; } @@ -172,38 +179,45 @@ static int ircomm_param_service_type(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) { - param->pv.b = self->session.service_type; + param->pv.b = self->settings.service_type; return 0; } + /* Find all common service types */ + service_type &= self->service_type; + if (!service_type) { + IRDA_DEBUG(2, __FUNCTION__ + "(), No common service type to use!\n"); + return -1; + } + IRDA_DEBUG(0, __FUNCTION__ "(), services in common=%02x\n", + service_type); + /* * Now choose a preferred service type of those available */ - if (service_type & IRCOMM_3_WIRE_RAW) { - IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 3 wire raw\n"); - self->session.service_type |= IRCOMM_3_WIRE_RAW; - } - if (service_type & IRCOMM_3_WIRE) { - IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 3 wire\n"); - self->session.service_type |= IRCOMM_3_WIRE; - } - if (service_type & IRCOMM_9_WIRE) { - IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 9 wire\n"); - self->session.service_type |= IRCOMM_9_WIRE; - } - if (service_type & IRCOMM_CENTRONICS) { - IRDA_DEBUG(2, __FUNCTION__ "(), peer supports Centronics\n"); - self->session.service_type |= IRCOMM_CENTRONICS; - } - - self->session.service_type &= self->service_type; - if (!self->session.service_type) { - IRDA_DEBUG(2, __FUNCTION__"(), No common service type to use!\n"); - return -1; + if (service_type & IRCOMM_CENTRONICS) + self->settings.service_type = IRCOMM_CENTRONICS; + else if (service_type & IRCOMM_9_WIRE) + self->settings.service_type = IRCOMM_9_WIRE; + else if (service_type & IRCOMM_3_WIRE) + self->settings.service_type = IRCOMM_3_WIRE; + else if (service_type & IRCOMM_3_WIRE_RAW) + self->settings.service_type = IRCOMM_3_WIRE_RAW; + + IRDA_DEBUG(0, __FUNCTION__ "(), resulting service type=0x%02x\n", + self->settings.service_type); + + /* + * Now the line is ready for some communication. Check if we are a + * server, and send over some initial parameters + */ + if (!self->client && (self->settings.service_type != IRCOMM_3_WIRE_RAW)) + { + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); } - - IRDA_DEBUG(2, __FUNCTION__ "(), resulting service type=0x%02x\n", - self->session.service_type); return 0; } @@ -225,10 +239,10 @@ static int ircomm_param_port_type(void *instance, param_t *param, int get) if (get) param->pv.b = IRCOMM_SERIAL; else { - self->session.port_type = param->pv.b; + self->settings.port_type = param->pv.b; IRDA_DEBUG(0, __FUNCTION__ "(), port type=%d\n", - self->session.port_type); + self->settings.port_type); } return 0; } @@ -250,7 +264,7 @@ static int ircomm_param_port_name(void *instance, param_t *param, int get) IRDA_DEBUG(0, __FUNCTION__ "(), not imp!\n"); } else { IRDA_DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c); - strncpy(self->session.port_name, param->pv.c, 32); + strncpy(self->settings.port_name, param->pv.c, 32); } return 0; @@ -259,7 +273,7 @@ static int ircomm_param_port_name(void *instance, param_t *param, int get) /* * Function ircomm_param_data_rate (self, param) * - * Exchange data rate to be used in this session + * Exchange data rate to be used in this settings * */ static int ircomm_param_data_rate(void *instance, param_t *param, int get) @@ -270,9 +284,9 @@ static int ircomm_param_data_rate(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) - param->pv.i = self->session.data_rate; + param->pv.i = self->settings.data_rate; else - self->session.data_rate = param->pv.i; + self->settings.data_rate = param->pv.i; IRDA_DEBUG(2, __FUNCTION__ "(), data rate = %d\n", param->pv.i); @@ -282,7 +296,7 @@ static int ircomm_param_data_rate(void *instance, param_t *param, int get) /* * Function ircomm_param_data_format (self, param) * - * Exchange data format to be used in this session + * Exchange data format to be used in this settings * */ static int ircomm_param_data_format(void *instance, param_t *param, int get) @@ -293,9 +307,9 @@ static int ircomm_param_data_format(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) - param->pv.b = self->session.data_format; + param->pv.b = self->settings.data_format; else - self->session.data_format = param->pv.b; + self->settings.data_format = param->pv.b; return 0; } @@ -303,7 +317,7 @@ static int ircomm_param_data_format(void *instance, param_t *param, int get) /* * Function ircomm_param_flow_control (self, param) * - * Exchange flow control settings to be used in this session + * Exchange flow control settings to be used in this settings * */ static int ircomm_param_flow_control(void *instance, param_t *param, int get) @@ -314,9 +328,9 @@ static int ircomm_param_flow_control(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) - param->pv.b = self->session.flow_control; + param->pv.b = self->settings.flow_control; else - self->session.flow_control = param->pv.b; + self->settings.flow_control = param->pv.b; IRDA_DEBUG(1, __FUNCTION__ "(), flow control = 0x%02x\n", param->pv.b); @@ -337,14 +351,14 @@ static int ircomm_param_xon_xoff(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) { - param->pv.s = self->session.xonxoff[0]; - param->pv.s |= self->session.xonxoff[1] << 8; + param->pv.s = self->settings.xonxoff[0]; + param->pv.s |= self->settings.xonxoff[1] << 8; } else { - self->session.xonxoff[0] = param->pv.s & 0xff; - self->session.xonxoff[1] = param->pv.s >> 8; + self->settings.xonxoff[0] = param->pv.s & 0xff; + self->settings.xonxoff[1] = param->pv.s >> 8; } - IRDA_DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x\n,0x%02x", + IRDA_DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x,0x%02x\n", param->pv.s & 0xff, param->pv.s >> 8); return 0; @@ -364,11 +378,11 @@ static int ircomm_param_enq_ack(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) { - param->pv.s = self->session.enqack[0]; - param->pv.s |= self->session.enqack[1] << 8; + param->pv.s = self->settings.enqack[0]; + param->pv.s |= self->settings.enqack[1] << 8; } else { - self->session.enqack[0] = param->pv.s & 0xff; - self->session.enqack[1] = param->pv.s >> 8; + self->settings.enqack[0] = param->pv.s & 0xff; + self->settings.enqack[1] = param->pv.s >> 8; } IRDA_DEBUG(0, __FUNCTION__ "(), ENQ/ACK = 0x%02x,0x%02x\n", @@ -405,29 +419,29 @@ static int ircomm_param_dte(void *instance, param_t *param, int get) ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); if (get) - param->pv.b = self->session.dte; + param->pv.b = self->settings.dte; else { dte = param->pv.b; if (dte & IRCOMM_DELTA_DTR) - self->session.dce |= (IRCOMM_DELTA_DSR| + self->settings.dce |= (IRCOMM_DELTA_DSR| IRCOMM_DELTA_RI | IRCOMM_DELTA_CD); if (dte & IRCOMM_DTR) - self->session.dce |= (IRCOMM_DSR| + self->settings.dce |= (IRCOMM_DSR| IRCOMM_RI | IRCOMM_CD); if (dte & IRCOMM_DELTA_RTS) - self->session.dce |= IRCOMM_DELTA_CTS; + self->settings.dce |= IRCOMM_DELTA_CTS; if (dte & IRCOMM_RTS) - self->session.dce |= IRCOMM_CTS; + self->settings.dce |= IRCOMM_CTS; /* Take appropriate actions */ ircomm_tty_check_modem_status(self); /* Null modem cable emulator */ - self->session.null_modem = TRUE; + self->settings.null_modem = TRUE; } return 0; @@ -451,7 +465,7 @@ static int ircomm_param_dce(void *instance, param_t *param, int get) ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - self->session.dce = dce; + self->settings.dce = dce; /* Check if any of the settings have changed */ if (dce & 0x0f) { @@ -483,7 +497,6 @@ static int ircomm_param_poll(void *instance, param_t *param, int get) /* Respond with DTE line settings */ ircomm_param_request(self, IRCOMM_DTE, TRUE); } - return 0; } diff --git a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c index 211bc14a8..642b8416a 100644 --- a/net/irda/ircomm/ircomm_ttp.c +++ b/net/irda/ircomm/ircomm_ttp.c @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: ircomm_ttp.c - * Version: + * Version: 1.0 * Description: Interface between IrCOMM and IrTTP - * Status: Experimental. + * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 20:48:27 1999 - * Modified at: Sat Oct 30 12:55:36 1999 + * Modified at: Mon Dec 13 11:35:13 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -64,7 +64,7 @@ int ircomm_open_tsap(struct ircomm_cb *self) self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); if (!self->tsap) { - IRDA_DEBUG(0,__FUNCTION__"failed to allocate tsap\n"); + IRDA_DEBUG(0, __FUNCTION__"failed to allocate tsap\n"); return -1; } self->slsap_sel = self->tsap->stsap_sel; @@ -95,8 +95,8 @@ int ircomm_ttp_connect_request(struct ircomm_cb *self, IRDA_DEBUG(4, __FUNCTION__ "()\n"); ret = irttp_connect_request(self->tsap, info->dlsap_sel, - info->saddr, info->daddr, - NULL, SAR_DISABLE, userdata); + info->saddr, info->daddr, NULL, + TTP_SAR_DISABLE, userdata); return ret; } @@ -112,7 +112,7 @@ int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb) IRDA_DEBUG(4, __FUNCTION__"()\n"); - ret = irttp_connect_response(self->tsap, SAR_DISABLE, skb); + ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, skb); return ret; } @@ -139,7 +139,7 @@ int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, * Insert clen field, currently we either send data only, or control * only frames, to make things easier and avoid queueing */ - ASSERT(skb_headroom(skb) >= 1, return -1;); + ASSERT(skb_headroom(skb) >= IRCOMM_HEADER_SIZE, return -1;); skb_push(skb, IRCOMM_HEADER_SIZE); skb->data[0] = clen; @@ -191,12 +191,13 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap, ASSERT(skb != NULL, return;); ASSERT(qos != NULL, return;); - if (max_sdu_size != SAR_DISABLE) { + if (max_sdu_size != TTP_SAR_DISABLE) { ERROR(__FUNCTION__ "(), SAR not allowed for IrCOMM!\n"); + dev_kfree_skb(skb); return; } - info.max_data_size = irttp_get_max_seq_size(self->tsap) + info.max_data_size = irttp_get_max_seg_size(self->tsap) - IRCOMM_HEADER_SIZE; info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE; info.qos = qos; @@ -227,12 +228,13 @@ void ircomm_ttp_connect_indication(void *instance, void *sap, ASSERT(skb != NULL, return;); ASSERT(qos != NULL, return;); - if (max_sdu_size != SAR_DISABLE) { + if (max_sdu_size != TTP_SAR_DISABLE) { ERROR(__FUNCTION__ "(), SAR not allowed for IrCOMM!\n"); + dev_kfree_skb(skb); return; } - info.max_data_size = irttp_get_max_seq_size(self->tsap) + info.max_data_size = irttp_get_max_seg_size(self->tsap) - IRCOMM_HEADER_SIZE; info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE; info.qos = qos; @@ -270,7 +272,7 @@ void ircomm_ttp_disconnect_indication(void *instance, void *sap, struct ircomm_cb *self = (struct ircomm_cb *) instance; struct ircomm_info info; - IRDA_DEBUG(4, __FUNCTION__"()\n"); + IRDA_DEBUG(2, __FUNCTION__"()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_MAGIC, return;); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index e79b10bcd..b53f8a8cf 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -6,11 +6,11 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 21:00:56 1999 - * Modified at: Sat Oct 30 12:49:26 1999 + * Modified at: Tue Jan 4 14:12:06 2000 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: serial.c and previous IrCOMM work by Takahide Higuchi * - * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -61,6 +61,7 @@ static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); static void ircomm_tty_hangup(struct tty_struct *tty); static void ircomm_tty_do_softint(void *private_); +static void ircomm_tty_shutdown(struct ircomm_tty_cb *self); static int ircomm_tty_data_indication(void *instance, void *sap, struct sk_buff *skb); @@ -134,6 +135,20 @@ int __init ircomm_tty_init(void) return 0; } +#ifdef MODULE +static void __ircomm_tty_cleanup(struct ircomm_tty_cb *self) +{ + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + ircomm_tty_shutdown(self); + + self->magic = 0; + kfree(self); +} + /* * Function ircomm_tty_cleanup () * @@ -144,7 +159,7 @@ void ircomm_tty_cleanup(void) { int ret; - IRDA_DEBUG(4, __FUNCTION__"()\n"); + IRDA_DEBUG(4, __FUNCTION__"()\n"); ret = tty_unregister_driver(&driver); if (ret) { @@ -152,8 +167,9 @@ void ircomm_tty_cleanup(void) return; } - hashbin_delete(ircomm_tty, (FREE_FUNC) kfree); + hashbin_delete(ircomm_tty, (FREE_FUNC) __ircomm_tty_cleanup); } +#endif /* MODULE */ /* * Function ircomm_startup (self) @@ -166,6 +182,8 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) notify_t notify; int ret; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); @@ -189,9 +207,10 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) strncpy(notify.name, "ircomm_tty", NOTIFY_MAX_NAME); notify.instance = self; - if (!self->ircomm) + if (!self->ircomm) { self->ircomm = ircomm_open(¬ify, self->service_type, self->line); + } if (!self->ircomm) return -ENODEV; @@ -224,25 +243,23 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, unsigned long flags; struct tty_struct *tty; - tty = self->tty; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + tty = self->tty; + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { /* this is a callout device */ /* just verify that normal device is not in use */ if (self->flags & ASYNC_NORMAL_ACTIVE) return -EBUSY; -#if 0 if ((self->flags & ASYNC_CALLOUT_ACTIVE) && (self->flags & ASYNC_SESSION_LOCKOUT) && (self->session != current->session)) - return -EBUSY; -#endif + return -EBUSY; if ((self->flags & ASYNC_CALLOUT_ACTIVE) && (self->flags & ASYNC_PGRP_LOCKOUT) && (self->pgrp != current->pgrp)) - return -EBUSY; + return -EBUSY; self->flags |= ASYNC_CALLOUT_ACTIVE; return 0; } @@ -263,13 +280,15 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, } if (self->flags & ASYNC_CALLOUT_ACTIVE) { - if (self->normal_termios.c_cflag & CLOCAL) + if (self->normal_termios.c_cflag & CLOCAL) { IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n"); do_clocal = 1; + } } else { - if (tty->termios->c_cflag & CLOCAL) + if (tty->termios->c_cflag & CLOCAL) { IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n"); do_clocal = 1; + } } /* Wait for carrier detect and the line to become @@ -297,13 +316,13 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, if (!(self->flags & ASYNC_CALLOUT_ACTIVE) && (tty->termios->c_cflag & CBAUD)) { save_flags(flags); cli(); - self->session.dte |= IRCOMM_RTS + IRCOMM_DTR; + self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR; ircomm_param_request(self, IRCOMM_DTE, TRUE); restore_flags(flags); } - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; if (tty_hung_up_p(filp) || !(self->flags & ASYNC_INITIALIZED)){ retval = (self->flags & ASYNC_HUP_NOTIFY) ? @@ -318,7 +337,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, */ if (!(self->flags & ASYNC_CALLOUT_ACTIVE) && !(self->flags & ASYNC_CLOSING) && - (do_clocal || (self->session.dce & IRCOMM_CD)) && + (do_clocal || (self->settings.dce & IRCOMM_CD)) && self->state == IRCOMM_TTY_READY) { break; @@ -386,6 +405,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) memset(self, 0, sizeof(struct ircomm_tty_cb)); self->magic = IRCOMM_TTY_MAGIC; + self->flow = FLOW_STOP; + self->line = line; self->tqueue.routine = ircomm_tty_do_softint; self->tqueue.data = self; @@ -397,7 +418,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) /* Init some important stuff */ init_timer(&self->watchdog_timer); init_waitqueue_head(&self->open_wait); - init_waitqueue_head(&self->close_wait); + init_waitqueue_head(&self->close_wait); /* * Force TTY into raw mode by default which is usually what @@ -440,10 +461,12 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) /* Check if this is a "normal" ircomm device, or an irlpt device */ if (line < 0x10) { self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; + self->settings.service_type = IRCOMM_9_WIRE; /* Default */ IRDA_DEBUG(2, __FUNCTION__ "(), IrCOMM device\n"); } else { IRDA_DEBUG(2, __FUNCTION__ "(), IrLPT device\n"); self->service_type = IRCOMM_3_WIRE_RAW; + self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */ } ret = ircomm_tty_startup(self); @@ -453,15 +476,14 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) ret = ircomm_tty_block_til_ready(self, filp); if (ret) { /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ - IRDA_DEBUG(0, __FUNCTION__ + IRDA_DEBUG(2, __FUNCTION__ "(), returning after block_til_ready with %d\n", ret); return ret; } -#if 0 + self->session = current->session; -#endif self->pgrp = current->pgrp; return 0; @@ -478,14 +500,11 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; unsigned long flags; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if (!tty) return; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); - save_flags(flags); cli(); @@ -493,10 +512,27 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) MOD_DEC_USE_COUNT; restore_flags(flags); - IRDA_DEBUG(2, __FUNCTION__ "(), returning 1\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), returning 1\n"); return; } + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + if ((tty->count == 1) && (self->open_count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + IRDA_DEBUG(0, __FUNCTION__ "(), bad serial port count; " + "tty->count is 1, state->count is %d\n", + self->open_count); + self->open_count = 1; + } + if (--self->open_count < 0) { ERROR(__FUNCTION__ "(), bad serial port count for ttys%d: %d\n", @@ -507,7 +543,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) MOD_DEC_USE_COUNT; restore_flags(flags); - IRDA_DEBUG(2, __FUNCTION__ "(), open count > 0\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), open count > 0\n"); return; } self->flags |= ASYNC_CLOSING; @@ -520,7 +556,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, self->closing_wait); - self->flags &= ~ASYNC_INITIALIZED; + ircomm_tty_shutdown(self); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); @@ -543,34 +579,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&self->close_wait); MOD_DEC_USE_COUNT; - - del_timer(&self->watchdog_timer); - - /* Free parameter buffer */ - if (self->ctrl_skb) { - dev_kfree_skb(self->ctrl_skb); - self->ctrl_skb = NULL; - } - - /* Free transmit buffer */ - if (self->tx_skb) { - dev_kfree_skb(self->tx_skb); - self->tx_skb = NULL; - } - restore_flags(flags); - - ircomm_tty_detach_cable(self); - ircomm_close(self->ircomm); - self->ircomm = NULL; - -#if IRCOMM_TTY_CLOSE_WILL_DEALLOC - self->magic = 0; - - hashbin_remove(ircomm_tty, self->line, NULL); - - kfree(self); -#endif } /* @@ -606,7 +615,9 @@ static void ircomm_tty_do_softint(void *private_) struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_; struct tty_struct *tty; unsigned long flags; - struct sk_buff *skb; + struct sk_buff *skb, *ctrl_skb; + + IRDA_DEBUG(2, __FUNCTION__ "()\n"); if (!self || self->magic != IRCOMM_TTY_MAGIC) return; @@ -615,6 +626,19 @@ static void ircomm_tty_do_softint(void *private_) if (!tty) return; + /* Unlink control buffer */ + save_flags(flags); + cli(); + + ctrl_skb = self->ctrl_skb; + self->ctrl_skb = NULL; + + restore_flags(flags); + + /* Flush control buffer if any */ + if (ctrl_skb && self->flow == FLOW_START) + ircomm_control_request(self->ircomm, ctrl_skb); + if (tty->hw_stopped) return; @@ -625,7 +649,7 @@ static void ircomm_tty_do_softint(void *private_) skb = self->tx_skb; self->tx_skb = NULL; - restore_flags(flags); + restore_flags(flags); /* Flush transmit buffer if any */ if (skb) @@ -658,7 +682,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user, int len = 0; int size; - IRDA_DEBUG(3, __FUNCTION__ "(), count=%d, hw_stopped=%d\n", count, + IRDA_DEBUG(2, __FUNCTION__ "(), count=%d, hw_stopped=%d\n", count, tty->hw_stopped); ASSERT(self != NULL, return -1;); @@ -788,7 +812,7 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; unsigned long orig_jiffies, poll_time; - IRDA_DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -831,8 +855,8 @@ static void ircomm_tty_throttle(struct tty_struct *tty) /* Hardware flow control? */ if (tty->termios->c_cflag & CRTSCTS) { - self->session.dte &= ~IRCOMM_RTS; - self->session.dte |= IRCOMM_DELTA_RTS; + self->settings.dte &= ~IRCOMM_RTS; + self->settings.dte |= IRCOMM_DELTA_RTS; ircomm_param_request(self, IRCOMM_DTE, TRUE); } @@ -863,7 +887,7 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty) /* Using hardware flow control? */ if (tty->termios->c_cflag & CRTSCTS) { - self->session.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); + self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); ircomm_param_request(self, IRCOMM_DTE, TRUE); IRDA_DEBUG(1, __FUNCTION__"(), FLOW_START\n"); @@ -897,6 +921,46 @@ static int ircomm_tty_chars_in_buffer(struct tty_struct *tty) return len; } +static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) +{ + unsigned long flags; + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + + if (!(self->flags & ASYNC_INITIALIZED)) + return; + + save_flags(flags); + cli(); + + del_timer(&self->watchdog_timer); + + /* Free parameter buffer */ + if (self->ctrl_skb) { + dev_kfree_skb(self->ctrl_skb); + self->ctrl_skb = NULL; + } + + /* Free transmit buffer */ + if (self->tx_skb) { + dev_kfree_skb(self->tx_skb); + self->tx_skb = NULL; + } + + ircomm_tty_detach_cable(self); + + if (self->ircomm) { + ircomm_close(self->ircomm); + self->ircomm = NULL; + } + self->flags &= ~ASYNC_INITIALIZED; + + restore_flags(flags); +} + /* * Function ircomm_tty_hangup (tty) * @@ -908,7 +972,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - IRDA_DEBUG(2, __FUNCTION__"()\n"); + IRDA_DEBUG(0, __FUNCTION__"()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -917,17 +981,11 @@ static void ircomm_tty_hangup(struct tty_struct *tty) return; /* ircomm_tty_flush_buffer(tty); */ - ircomm_tty_detach_cable(self); - ircomm_close(self->ircomm); + ircomm_tty_shutdown(self); - self->ircomm = NULL; - - self->flags &= ~ASYNC_INITIALIZED; - - self->open_count = 0; self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); self->tty = 0; - + self->open_count = 0; wake_up_interruptible(&self->open_wait); } @@ -983,19 +1041,21 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) struct tty_struct *tty; int status; + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); tty = self->tty; - status = self->session.dce; + status = self->settings.dce; if (status & IRCOMM_DCE_DELTA_ANY) { /*wake_up_interruptible(&self->delta_msr_wait);*/ } if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { IRDA_DEBUG(2, __FUNCTION__ - "(), ttys%d CD now %s...\n", self->line, + "(), ircomm%d CD now %s...\n", self->line, (status & IRCOMM_CD) ? "on" : "off"); if (status & IRCOMM_CD) { @@ -1003,27 +1063,30 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) } else if (!((self->flags & ASYNC_CALLOUT_ACTIVE) && (self->flags & ASYNC_CALLOUT_NOHUP))) { - IRDA_DEBUG(2, __FUNCTION__ "(), Doing serial hangup..\n"); - + IRDA_DEBUG(2, __FUNCTION__ + "(), Doing serial hangup..\n"); if (tty) tty_hangup(tty); + + /* Hangup will remote the tty, so better break out */ + return; } } if (self->flags & ASYNC_CTS_FLOW) { if (tty->hw_stopped) { if (status & IRCOMM_CTS) { - IRDA_DEBUG(2, __FUNCTION__ "(), CTS tx start...\n"); - + IRDA_DEBUG(2, __FUNCTION__ + "(), CTS tx start...\n"); tty->hw_stopped = 0; - + queue_task(&self->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); return; } } else { if (!(status & IRCOMM_CTS)) { - IRDA_DEBUG(2, __FUNCTION__ "(), CTS tx stop...\n"); - + IRDA_DEBUG(2, __FUNCTION__ + "(), CTS tx stop...\n"); tty->hw_stopped = 1; } } @@ -1047,8 +1110,26 @@ static int ircomm_tty_data_indication(void *instance, void *sap, ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); ASSERT(skb != NULL, return -1;); - if (!self->tty) + if (!self->tty) { + IRDA_DEBUG(0, __FUNCTION__ "(), no tty!\n"); + dev_kfree_skb(skb); return 0; + } + + /* + * If we receive data when hardware is stopped then something is wrong. + * We try to poll the peers line settings to check if we are up todate. + * Devices like WinCE can do this, and since they don't send any + * params, we can just as well declare the hardware for running. + */ + if (self->tty->hw_stopped && (self->flow == FLOW_START)) { + IRDA_DEBUG(0, __FUNCTION__ "(), polling for line settings!\n"); + ircomm_param_request(self, IRCOMM_POLL, TRUE); + + /* We can just as well declare the hardware for running */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); + } /* * Just give it over to the line discipline. There is no need to @@ -1113,15 +1194,15 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, /* ircomm_tty_do_softint will take care of the rest */ queue_task(&self->tqueue, &tq_immediate); - mark_bh(IMMEDIATE_BH); + mark_bh(IMMEDIATE_BH); break; - default: - /* If we get here, something is very wrong, better stop */ + default: /* If we get here, something is very wrong, better stop */ case FLOW_STOP: IRDA_DEBUG(2, __FUNCTION__ "(), hw stopped!\n"); tty->hw_stopped = 1; break; } + self->flow = cmd; } static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) @@ -1141,57 +1222,57 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) ret += sprintf(buf+ret, "No common service type!\n"); ret += sprintf(buf+ret, "\n"); - ret += sprintf(buf+ret, "Port name: %s\n", self->session.port_name); + ret += sprintf(buf+ret, "Port name: %s\n", self->settings.port_name); ret += sprintf(buf+ret, "DTE status: "); - if (self->session.dte & IRCOMM_RTS) + if (self->settings.dte & IRCOMM_RTS) ret += sprintf(buf+ret, "RTS|"); - if (self->session.dte & IRCOMM_DTR) + if (self->settings.dte & IRCOMM_DTR) ret += sprintf(buf+ret, "DTR|"); - if (self->session.dte) + if (self->settings.dte) ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "DCE status: "); - if (self->session.dce & IRCOMM_CTS) + if (self->settings.dce & IRCOMM_CTS) ret += sprintf(buf+ret, "CTS|"); - if (self->session.dce & IRCOMM_DSR) + if (self->settings.dce & IRCOMM_DSR) ret += sprintf(buf+ret, "DSR|"); - if (self->session.dce & IRCOMM_CD) + if (self->settings.dce & IRCOMM_CD) ret += sprintf(buf+ret, "CD|"); - if (self->session.dce & IRCOMM_RI) + if (self->settings.dce & IRCOMM_RI) ret += sprintf(buf+ret, "RI|"); - if (self->session.dce) + if (self->settings.dce) ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "Configuration: "); - if (!self->session.null_modem) + if (!self->settings.null_modem) ret += sprintf(buf+ret, "DTE <-> DCE\n"); else ret += sprintf(buf+ret, "DTE <-> DTE (null modem emulation)\n"); - ret += sprintf(buf+ret, "Data rate: %d\n", self->session.data_rate); + ret += sprintf(buf+ret, "Data rate: %d\n", self->settings.data_rate); ret += sprintf(buf+ret, "Flow control: "); - if (self->session.flow_control & IRCOMM_XON_XOFF_IN) + if (self->settings.flow_control & IRCOMM_XON_XOFF_IN) ret += sprintf(buf+ret, "XON_XOFF_IN|"); - if (self->session.flow_control & IRCOMM_XON_XOFF_OUT) + if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT) ret += sprintf(buf+ret, "XON_XOFF_OUT|"); - if (self->session.flow_control & IRCOMM_RTS_CTS_IN) + if (self->settings.flow_control & IRCOMM_RTS_CTS_IN) ret += sprintf(buf+ret, "RTS_CTS_IN|"); - if (self->session.flow_control & IRCOMM_RTS_CTS_OUT) + if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT) ret += sprintf(buf+ret, "RTS_CTS_OUT|"); - if (self->session.flow_control & IRCOMM_DSR_DTR_IN) + if (self->settings.flow_control & IRCOMM_DSR_DTR_IN) ret += sprintf(buf+ret, "DSR_DTR_IN|"); - if (self->session.flow_control & IRCOMM_DSR_DTR_OUT) + if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT) ret += sprintf(buf+ret, "DSR_DTR_OUT|"); - if (self->session.flow_control & IRCOMM_ENQ_ACK_IN) + if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN) ret += sprintf(buf+ret, "ENQ_ACK_IN|"); - if (self->session.flow_control & IRCOMM_ENQ_ACK_OUT) + if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT) ret += sprintf(buf+ret, "ENQ_ACK_OUT|"); - if (self->session.flow_control) + if (self->settings.flow_control) ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); @@ -1214,7 +1295,12 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); + ret += sprintf(buf+ret, "Role: %s\n", self->client ? + "client" : "server"); ret += sprintf(buf+ret, "Open count: %d\n", self->open_count); + ret += sprintf(buf+ret, "Max data size: %d\n", self->max_data_size); + ret += sprintf(buf+ret, "Max header size: %d\n", self->max_header_size); + if (self->tty) ret += sprintf(buf+ret, "Hardware: %s\n", self->tty->hw_stopped ? "Stopped" : "Running"); diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index db8f382dc..94c9fee09 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Jun 5 17:42:00 1999 - * Modified at: Sun Oct 31 22:19:37 1999 + * Modified at: Tue Jan 4 14:20:49 2000 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -124,7 +124,7 @@ static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, */ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); @@ -159,17 +159,21 @@ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) */ void ircomm_tty_detach_cable(struct ircomm_tty_cb *self) { - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + del_timer(&self->watchdog_timer); + /* Remove IrCOMM hint bits */ irlmp_unregister_client(self->ckey); irlmp_unregister_service(self->skey); - if (self->iriap) + if (self->iriap) { iriap_close(self->iriap); + self->iriap = NULL; + } /* Remove LM-IAS object */ if (self->obj) { @@ -183,7 +187,7 @@ void ircomm_tty_detach_cable(struct ircomm_tty_cb *self) self->daddr = self->saddr = 0; self->dlsap_sel = self->slsap_sel = 0; - memset(&self->session, 0, sizeof(struct ircomm_params)); + memset(&self->settings, 0, sizeof(struct ircomm_params)); } /* @@ -197,6 +201,8 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) __u8 oct_seq[6]; __u16 hints; + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -237,7 +243,7 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) * Send initial parameters to the remote IrCOMM device. These parameters * must be sent before any data. */ -static int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self) +int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self) { ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); @@ -250,27 +256,29 @@ static int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self) * haven't set them already */ IRDA_DEBUG(2, __FUNCTION__ "(), data-rate = %d\n", - self->session.data_rate); - if (!self->session.data_rate) - self->session.data_rate = 9600; + self->settings.data_rate); + if (!self->settings.data_rate) + self->settings.data_rate = 9600; IRDA_DEBUG(2, __FUNCTION__ "(), data-format = %d\n", - self->session.data_format); - if (!self->session.data_format) - self->session.data_format = IRCOMM_WSIZE_8; /* 8N1 */ + self->settings.data_format); + if (!self->settings.data_format) + self->settings.data_format = IRCOMM_WSIZE_8; /* 8N1 */ IRDA_DEBUG(2, __FUNCTION__ "(), flow-control = %d\n", - self->session.flow_control); - /*self->session.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/ + self->settings.flow_control); + /*self->settings.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/ /* Do not set delta values for the initial parameters */ - self->session.dte = IRCOMM_DTR | IRCOMM_RTS; + self->settings.dte = IRCOMM_DTR | IRCOMM_RTS; - ircomm_param_request(self, IRCOMM_SERVICE_TYPE, FALSE); + /* Only send service type parameter when we are the client */ + if (self->client) + ircomm_param_request(self, IRCOMM_SERVICE_TYPE, FALSE); ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE); ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE); /* For a 3 wire service, we just flush the last parameter and return */ - if (self->session.service_type == IRCOMM_3_WIRE) { + if (self->settings.service_type == IRCOMM_3_WIRE) { ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE); return 0; } @@ -335,6 +343,12 @@ void ircomm_tty_disconnect_indication(void *instance, void *sap, if (!self->tty) return; + /* This will stop control data transfers */ + self->flow = FLOW_STOP; + + /* Stop data transfers */ + self->tty->hw_stopped = 1; + ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, NULL); } @@ -395,6 +409,7 @@ static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id, IRDA_DEBUG(0, __FUNCTION__"(), got unknown type!\n"); break; } + irias_delete_value(value); } /* @@ -416,10 +431,14 @@ void ircomm_tty_connect_confirm(void *instance, void *sap, ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + self->client = TRUE; self->max_data_size = max_data_size; self->max_header_size = max_header_size; + self->flow = FLOW_START; ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_CONFIRM, NULL, NULL); + + dev_kfree_skb(skb); } /* @@ -443,8 +462,10 @@ void ircomm_tty_connect_indication(void *instance, void *sap, ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + self->client = FALSE; self->max_data_size = max_data_size; self->max_header_size = max_header_size; + self->flow = FLOW_START; clen = skb->data[0]; if (clen) @@ -453,6 +474,8 @@ void ircomm_tty_connect_indication(void *instance, void *sap, &ircomm_param_info); ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL); + + dev_kfree_skb(skb); } /* @@ -465,26 +488,32 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self) { IRDA_DEBUG(2, __FUNCTION__ "()\n"); + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + if (!self->tty) + return; + del_timer(&self->watchdog_timer); - /* + /* * IrCOMM link is now up, and if we are not using hardware - * flow-control, then declare the hardware as running. Otherwise - * the client will have to wait for the CD to be set. + * flow-control, then declare the hardware as running. Otherwise we + * will have to wait for the peer device (DCE) to raise the CTS + * line. */ - if (!(self->flags & ASYNC_CTS_FLOW)) { + if (self->flags & ASYNC_CTS_FLOW) { + IRDA_DEBUG(0, __FUNCTION__ "(), waiting for CTS ...\n"); + return; + } else { IRDA_DEBUG(2, __FUNCTION__ "(), starting hardware!\n"); - if (!self->tty) - return; + self->tty->hw_stopped = 0; + + /* Wake up processes blocked on open */ + wake_up_interruptible(&self->open_wait); } - /* Wake up processes blocked on open */ - wake_up_interruptible(&self->open_wait); - /* - * Wake up processes blocked on write, or waiting for a write - * wakeup notification - */ queue_task(&self->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); } @@ -498,6 +527,9 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self) */ void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout) { + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + irda_start_timer(&self->watchdog_timer, timeout, (void *) self, ircomm_tty_watchdog_timer_expired); } @@ -512,7 +544,7 @@ void ircomm_tty_watchdog_timer_expired(void *data) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data; - IRDA_DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -535,13 +567,12 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); - switch (event) { case IRCOMM_TTY_ATTACH_CABLE: /* Try to discover any remote devices */ ircomm_tty_start_watchdog_timer(self, 3*HZ); ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); - + irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS); break; case IRCOMM_TTY_DISCOVERY_INDICATION: @@ -570,10 +601,6 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - - /* Init connection */ - ircomm_tty_send_initial_parameters(self); - ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: /* Just stay idle */ @@ -640,15 +667,15 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self, /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - - /* Init connection */ - ircomm_tty_send_initial_parameters(self); - ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: +#if 1 + /* Give up */ +#else /* Try to discover any remote devices */ ircomm_tty_start_watchdog_timer(self, 3*HZ); irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS); +#endif break; case IRCOMM_TTY_DETACH_CABLE: ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); @@ -706,10 +733,6 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self, /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - - /* Init connection */ - ircomm_tty_send_initial_parameters(self); - ircomm_tty_link_established(self); break; case IRCOMM_TTY_DETACH_CABLE: ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); @@ -758,10 +781,6 @@ static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self, /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - - /* Init connection */ - ircomm_tty_send_initial_parameters(self); - ircomm_tty_link_established(self); break; case IRCOMM_TTY_DETACH_CABLE: ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); @@ -808,10 +827,6 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self, /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - - /* Init connection */ - ircomm_tty_send_initial_parameters(self); - ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: /* Go back to search mode */ @@ -819,7 +834,7 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self, ircomm_tty_start_watchdog_timer(self, 3*HZ); break; case IRCOMM_TTY_DETACH_CABLE: - ircomm_disconnect_request(self->ircomm, NULL); + /* ircomm_disconnect_request(self->ircomm, NULL); */ ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: @@ -855,9 +870,15 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); ircomm_tty_start_watchdog_timer(self, 3*HZ); - /* Drop carrier */ - self->session.dce = IRCOMM_DELTA_CD; - ircomm_tty_check_modem_status(self); + if (self->flags & ASYNC_CHECK_CD) { + /* Drop carrier */ + self->settings.dce = IRCOMM_DELTA_CD; + ircomm_tty_check_modem_status(self); + } else { + IRDA_DEBUG(0, __FUNCTION__ "(), hanging up!\n"); + if (self->tty) + tty_hangup(self->tty); + } break; default: IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n", @@ -876,9 +897,12 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, struct sk_buff *skb, struct ircomm_tty_info *info) { + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); + IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); - + return (*state[self->state])(self, event, skb, info); } @@ -890,6 +914,9 @@ int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, */ void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state) { + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + self->state = state; IRDA_DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index 5262af954..107ceb612 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Jun 10 14:39:09 1999 - * Modified at: Sat Oct 30 12:50:41 1999 + * Modified at: Wed Jan 5 14:45:43 2000 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -59,6 +59,8 @@ void ircomm_tty_change_speed(struct ircomm_tty_cb *self) unsigned cflag, cval; int baud; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + if (!self->tty || !self->tty->termios || !self->ircomm) return; @@ -85,16 +87,17 @@ void ircomm_tty_change_speed(struct ircomm_tty_cb *self) if (!baud) baud = 9600; /* B0 transition handled in rs_set_termios */ - self->session.data_rate = baud; + self->settings.data_rate = baud; ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE); /* CTS flow control flag and modem status interrupts */ if (cflag & CRTSCTS) { self->flags |= ASYNC_CTS_FLOW; - self->session.flow_control |= IRCOMM_RTS_CTS_IN; - } else + self->settings.flow_control |= IRCOMM_RTS_CTS_IN; + } else { self->flags &= ~ASYNC_CTS_FLOW; - + self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; + } if (cflag & CLOCAL) self->flags &= ~ASYNC_CHECK_CD; else @@ -126,7 +129,7 @@ void ircomm_tty_change_speed(struct ircomm_tty_cb *self) self->ignore_status_mask |= LSR_OE; } #endif - self->session.data_format = cval; + self->settings.data_format = cval; ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE); ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE); @@ -146,6 +149,8 @@ void ircomm_tty_set_termios(struct tty_struct *tty, struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; unsigned int cflag = tty->termios->c_cflag; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) @@ -158,17 +163,17 @@ void ircomm_tty_set_termios(struct tty_struct *tty, /* Handle transition to B0 status */ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { - self->session.dte &= ~(IRCOMM_DTR|IRCOMM_RTS); + self->settings.dte &= ~(IRCOMM_DTR|IRCOMM_RTS); ircomm_param_request(self, IRCOMM_DTE, TRUE); } /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { - self->session.dte |= IRCOMM_DTR; + self->settings.dte |= IRCOMM_DTR; if (!(tty->termios->c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { - self->session.dte |= IRCOMM_RTS; + self->settings.dte |= IRCOMM_RTS; } ircomm_param_request(self, IRCOMM_DTE, TRUE); } @@ -193,14 +198,14 @@ static int ircomm_tty_get_modem_info(struct ircomm_tty_cb *self, { unsigned int result; - IRDA_DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - result = ((self->session.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) - | ((self->session.dte & IRCOMM_DTR) ? TIOCM_DTR : 0) - | ((self->session.dce & IRCOMM_CD) ? TIOCM_CAR : 0) - | ((self->session.dce & IRCOMM_RI) ? TIOCM_RNG : 0) - | ((self->session.dce & IRCOMM_DSR) ? TIOCM_DSR : 0) - | ((self->session.dce & IRCOMM_CTS) ? TIOCM_CTS : 0); + result = ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) + | ((self->settings.dte & IRCOMM_DTR) ? TIOCM_DTR : 0) + | ((self->settings.dce & IRCOMM_CD) ? TIOCM_CAR : 0) + | ((self->settings.dce & IRCOMM_RI) ? TIOCM_RNG : 0) + | ((self->settings.dce & IRCOMM_DSR) ? TIOCM_DSR : 0) + | ((self->settings.dce & IRCOMM_CTS) ? TIOCM_CTS : 0); return put_user(result, value); } @@ -227,27 +232,27 @@ static int ircomm_tty_set_modem_info(struct ircomm_tty_cb *self, if (error) return error; - old_rts = self->session.dte & IRCOMM_RTS; - old_dtr = self->session.dte & IRCOMM_DTR; + old_rts = self->settings.dte & IRCOMM_RTS; + old_dtr = self->settings.dte & IRCOMM_DTR; switch (cmd) { case TIOCMBIS: if (arg & TIOCM_RTS) - self->session.dte |= IRCOMM_RTS; + self->settings.dte |= IRCOMM_RTS; if (arg & TIOCM_DTR) - self->session.dte |= IRCOMM_DTR; + self->settings.dte |= IRCOMM_DTR; break; case TIOCMBIC: if (arg & TIOCM_RTS) - self->session.dte &= ~IRCOMM_RTS; + self->settings.dte &= ~IRCOMM_RTS; if (arg & TIOCM_DTR) - self->session.dte &= ~IRCOMM_DTR; + self->settings.dte &= ~IRCOMM_DTR; break; case TIOCMSET: - self->session.dte = - ((self->session.dte & ~(IRCOMM_RTS | IRCOMM_DTR)) + self->settings.dte = + ((self->settings.dte & ~(IRCOMM_RTS | IRCOMM_DTR)) | ((arg & TIOCM_RTS) ? IRCOMM_RTS : 0) | ((arg & TIOCM_DTR) ? IRCOMM_DTR : 0)); break; @@ -256,11 +261,11 @@ static int ircomm_tty_set_modem_info(struct ircomm_tty_cb *self, return -EINVAL; } - if ((self->session.dte & IRCOMM_RTS) != old_rts) - self->session.dte |= IRCOMM_DELTA_RTS; + if ((self->settings.dte & IRCOMM_RTS) != old_rts) + self->settings.dte |= IRCOMM_DELTA_RTS; - if ((self->session.dte & IRCOMM_DTR) != old_dtr) - self->session.dte |= IRCOMM_DELTA_DTR; + if ((self->settings.dte & IRCOMM_DTR) != old_dtr) + self->settings.dte |= IRCOMM_DELTA_DTR; ircomm_param_request(self, IRCOMM_DTE, TRUE); @@ -281,12 +286,12 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, if (!retinfo) return -EFAULT; - IRDA_DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); memset(&info, 0, sizeof(info)); info.line = self->line; info.flags = self->flags; - info.baud_base = self->session.data_rate; + info.baud_base = self->settings.data_rate; info.close_delay = self->close_delay; info.closing_wait = self->closing_wait; @@ -310,29 +315,33 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, * * */ -static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *tty, +static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self, struct serial_struct *new_info) { #if 0 struct serial_struct new_serial; - struct ircomm_tty_cb old_driver; + struct ircomm_tty_cb old_state, *state; - IRDA_DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) return -EFAULT; - old_driver = *driver; + + state = self + old_state = *self; if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.baud_base != driver->comm->data_rate) || - (new_serial.close_delay != driver->close_delay) || + if ((new_serial.baud_base != state->settings.data_rate) || + (new_serial.close_delay != state->close_delay) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (driver->flags & ~ASYNC_USR_MASK))) + (self->flags & ~ASYNC_USR_MASK))) return -EPERM; - driver->flags = ((driver->flags & ~ASYNC_USR_MASK) | + state->flags = ((state->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); - driver->custom_divisor = new_serial.custom_divisor; + self->flags = ((self->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + /* self->custom_divisor = new_serial.custom_divisor; */ goto check_and_exit; } @@ -341,15 +350,14 @@ static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *tty, * At this point, we start making changes..... */ - if (self->session.data_rate != new_serial.baud_base) { - self->session.data_rate.data_rate = new_serial.baud_base; - if (driver->comm->state == IRCOMM_CONN) - ircomm_control_request(driver->comm, DATA_RATE); + if (self->settings.data_rate != new_serial.baud_base) { + self->settings.data_rate = new_serial.baud_base; + ircomm_param_request(self, IRCOMM_DATA_RATE, TRUE); } - driver->close_delay = new_serial.close_delay * HZ/100; - driver->closing_wait = new_serial.closing_wait * HZ/100; - driver->custom_divisor = new_serial.custom_divisor; + self->close_delay = new_serial.close_delay * HZ/100; + self->closing_wait = new_serial.closing_wait * HZ/100; + /* self->custom_divisor = new_serial.custom_divisor; */ self->flags = ((self->flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); @@ -358,7 +366,7 @@ static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *tty, check_and_exit: if (self->flags & ASYNC_INITIALIZED) { - if (((old_driver.flags & ASYNC_SPD_MASK) != + if (((old_state.flags & ASYNC_SPD_MASK) != (self->flags & ASYNC_SPD_MASK)) || (old_driver.custom_divisor != driver->custom_divisor)) { if ((driver->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) @@ -388,6 +396,8 @@ int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; int ret = 0; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { |