static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) { if (!tty->count) { del_timer_sync(&pdc_console_timer); tty_port_tty_set(&tty_port, NULL); } }
static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) { tty_port_tty_set(&tty_port, tty); mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); return 0; }
static int mytty_open(struct tty_struct *tty,struct file *pfile) { struct mytty_info *pinfo = NULL; struct tty_driver *pmytty; int line; if(!tty) { printk("%s: failed to alloc for mytty info\n",TAGS); return -EINVAL; } if(!tty->driver_data) { pinfo = kzalloc(sizeof(struct mytty_info), GFP_KERNEL); if(!pinfo) { printk("%s: tty is NULL\n",TAGS); return -ENOMEM; } pmytty = tty->driver; line = tty->index; tty_port_tty_set(pmytty->ports[line],tty); INIT_DELAYED_WORK(&pinfo->work, print_work); schedule_delayed_work(&pinfo->work, 5 * HZ); tty->driver_data = pinfo; pinfo->tty = tty; } pinfo = tty->driver_data; pinfo->open_count += 1; printk("%s: mytty open successfull!open count is %d\n", TAGS, pinfo->open_count); return 0; }
static void option_close(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp) { int i; struct usb_serial *serial = port->serial; struct option_port_private *portdata; dbg("%s", __func__); portdata = usb_get_serial_port_data(port); portdata->rts_state = 0; portdata->dtr_state = 0; if (serial->dev) { mutex_lock(&serial->disc_mutex); if (!serial->disconnected) option_send_setup(tty, port); mutex_unlock(&serial->disc_mutex); /* Stop reading/writing urbs */ for (i = 0; i < N_IN_URB; i++) usb_kill_urb(portdata->in_urbs[i]); for (i = 0; i < N_OUT_URB; i++) usb_kill_urb(portdata->out_urbs[i]); } tty_port_tty_set(&port->port, NULL); }
static int lge_bypass_open(struct tty_struct *tty, struct file *file) { struct bypass_driver *bypass_drv = NULL; bypass_drv = lge_bypass_drv; if(!bypass_drv) { pr_err("%s: bypass_drv is null\n", __func__); return -ENODEV; } #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_connect_bridge(0); #endif tty_port_tty_set(bypass_drv->port, tty); #if defined(CONFIG_ARCH_MSM8916) || defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_ODIN) bypass_drv->port->low_latency = 0; #endif tty->driver_data = bypass_drv; bypass_drv->tty_str = tty; set_bit(TTY_NO_WRITE_SPLIT, &bypass_drv->tty_str->flags); is_opened = 1; pr_info("%s success\n", __func__); return 0; }
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; int result = 0; dbg("%s - port %d", __func__, port->number); wport = serial->port[1]; tty_port_tty_set(&wport->port, tty); /* Start reading from the device */ usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, omninet_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); return result; }
static int lge_dm_tty_open(struct tty_struct *tty, struct file *file) { struct dm_tty *lge_dm_tty_drv = NULL; if (!tty) { pr_err(DM_TTY_MODULE_NAME ": %s: NULL tty", __func__); return -ENODEV; } lge_dm_tty_drv = lge_dm_tty; if (!lge_dm_tty_drv) { pr_err(DM_TTY_MODULE_NAME ": %s:" "NULL lge_dm_tty_drv", __func__); return -ENODEV; } #ifdef CONFIG_TTY_PORT tty_port_tty_set(&dm_tty_port, tty); dm_tty_port.low_latency = 1; #endif /* CONFIG_TTY_PORT */ tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; if (lge_dm_tty_drv->tty_state == DM_TTY_OPEN) { pr_err(DM_TTY_MODULE_NAME ": %s:" "tty is already open", __func__); return -EBUSY; } /* support max = 64KB */ set_bit(TTY_NO_WRITE_SPLIT, &lge_dm_tty_drv->tty_str->flags); lge_dm_tty_drv->tty_ts = kthread_run(lge_dm_tty_read_thread, NULL, "lge_dm_tty_thread"); lge_dm_tty_drv->tty_state = DM_TTY_OPEN; pr_info(DM_TTY_MODULE_NAME ": %s: TTY device open\n", __func__); lge_dm_tty_drv->logging_mode = DM_APP_ODM; lge_dm_tty_drv->set_logging= 0; dm_modem_response_length = 0; dm_modem_request_length = 0; dm_rx_start_flag = 0x2B1A; dm_rx_end_flag = 0x7E6D; dm_modem_response_header->dm_router_cmd = DM_APP_MODEM_RESPONSE; dm_modem_response_header->dm_router_type = DM_APP_NOTICE; lge_dm_tty_drv->dm_wq = create_singlethread_workqueue("dm_wq"); INIT_WORK(&(lge_dm_tty_drv->dm_usb_work), lge_dm_usb_fn); INIT_WORK(&(lge_dm_tty_drv->dm_dload_work), lge_dm_dload_fn); return 0; }
static void uart_close(struct tty_struct *tty, struct file *filp) { struct uart_state *state = tty->driver_data; struct tty_port *port; struct uart_port *uport; unsigned long flags; if (!state) return; uport = state->uart_port; port = &state->port; pr_debug("uart_close(%d) called\n", uport->line); if (tty_port_close_start(port, tty, filp) == 0) return; if (port->flags & ASYNC_INITIALIZED) { unsigned long flags; spin_lock_irqsave(&uport->lock, flags); uport->ops->stop_rx(uport); spin_unlock_irqrestore(&uport->lock, flags); uart_wait_until_sent(tty, uport->timeout); } mutex_lock(&port->mutex); uart_shutdown(tty, state); uart_flush_buffer(tty); tty_ldisc_flush(tty); tty_port_tty_set(port, NULL); spin_lock_irqsave(&port->lock, flags); tty->closing = 0; if (port->blocked_open) { spin_unlock_irqrestore(&port->lock, flags); if (port->close_delay) msleep_interruptible( jiffies_to_msecs(port->close_delay)); spin_lock_irqsave(&port->lock, flags); } else if (!uart_console(uport)) { spin_unlock_irqrestore(&port->lock, flags); uart_change_pm(state, 3); spin_lock_irqsave(&port->lock, flags); } clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); clear_bit(ASYNCB_CLOSING, &port->flags); spin_unlock_irqrestore(&port->lock, flags); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->close_wait); mutex_unlock(&port->mutex); }
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; wport = serial->port[1]; tty_port_tty_set(&wport->port, tty); return usb_serial_generic_open(tty, port); }
static void lcd_close(struct tty_struct *tty, struct file *filp) { struct lcd *lcd_data = tty->driver_data; unsigned long flags; bool last; spin_lock_irqsave(&lcd_data->port.lock, flags); --lcd_data->port.count; last = (lcd_data->port.count == 0); spin_unlock_irqrestore(&lcd_data->port.lock, flags); if (last) tty_port_tty_set(&lcd_data->port, NULL); }
static int lcd_open(struct tty_struct *tty, struct file *filp) { struct lcd *lcd_data = tty->driver_data; unsigned long flags; tty->driver_data = lcd_data; spin_lock_irqsave(&lcd_data->port.lock, flags); lcd_data->port.count++; spin_unlock_irqrestore(&lcd_data->port.lock, flags); tty_port_tty_set(&lcd_data->port, tty); return 0; }
static void acm_tty_close(struct tty_struct *tty, struct file *filp) { struct acm *acm = tty->driver_data; /* Perform the closing process and see if we need to do the hardware shutdown */ if (!acm) return; if (tty_port_close_start(&acm->port, tty, filp) == 0) { mutex_lock(&open_mutex); if (!acm->dev) { tty_port_tty_set(&acm->port, NULL); acm_tty_unregister(acm); tty->driver_data = NULL; } mutex_unlock(&open_mutex); return; } acm_port_down(acm); tty_port_close_end(&acm->port, tty); tty_port_tty_set(&acm->port, NULL); }
/* * tty3215_close() * * This routine is called when the 3215 tty is closed. We wait * for the remaining request to be completed. Then we clean up. */ static void tty3215_close(struct tty_struct *tty, struct file * filp) { struct raw3215_info *raw; raw = (struct raw3215_info *) tty->driver_data; if (raw == NULL || tty->count > 1) return; tty->closing = 1; /* Shutdown the terminal */ raw3215_shutdown(raw); tasklet_kill(&raw->tlet); tty->closing = 0; tty_port_tty_set(&raw->port, NULL); }
/* * rs_hangup() --- called by tty_hangup() when a hangup is signaled. */ void rs_hangup(struct tty_struct *tty) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_hangup")) return; rs_flush_buffer(tty); shutdown(info, tty); info->tport.count = 0; info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; tty_port_tty_set(&info->tport, NULL); wake_up_interruptible(&info->tport.open_wait); }
static void mts_tty_close(struct tty_struct *tty, struct file *file) { struct mts_tty *mts_tty_drv = NULL; if (!tty) { printk( "mts_tty_close FAIL." "tty is Null %d,%d\n", 0, 0); return; } mts_tty_drv = tty->driver_data; tty_port_tty_set(mts_tty_drv->mts_tty_port, NULL); printk( "mts_tty_close TTY device close %d,%d\n", 0, 0); return; }
static void lge_dm_tty_close(struct tty_struct *tty, struct file *file) { struct dm_tty *lge_dm_tty_drv = NULL; lge_dm_tty_drv = lge_dm_tty; tty->driver_data = lge_dm_tty_drv; lge_dm_tty_drv->tty_str = tty; clear_bit(TTY_NO_WRITE_SPLIT, &lge_dm_tty_drv->tty_str->flags); if (!tty) { pr_err(DM_TTY_MODULE_NAME ": %s: NULL tty", __func__); return; } lge_dm_tty_drv = tty->driver_data; if (!lge_dm_tty_drv) { pr_err(DM_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv", __func__); return; } if (lge_dm_tty_drv->tty_state != DM_TTY_OPEN) { pr_err(DM_TTY_MODULE_NAME ": %s: TTY device was not opened\n", __func__); return; } lge_dm_tty_drv->logging_mode = DM_APP_ODM; lge_dm_tty_drv->set_logging = 1; wake_up_interruptible(&lge_dm_tty_drv->waitq); kthread_stop(lge_dm_tty_drv->tty_ts); lge_dm_tty_drv->tty_state = DM_TTY_CLOSED; pr_info(DM_TTY_MODULE_NAME ": %s: TTY device closed\n", __func__); cancel_work_sync(&(lge_dm_tty_drv->dm_usb_work)); cancel_work_sync(&(lge_dm_tty_drv->dm_dload_work)); destroy_workqueue(lge_dm_tty_drv->dm_wq); #ifdef CONFIG_TTY_PORT tty_port_tty_set(&dm_tty_port, NULL); #endif /* CONFIG_TTY_PORT */ return; }
static int uart_open(struct tty_struct *tty, struct file *filp) { struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; int retval, line = tty->index; struct uart_state *state = drv->state + line; struct tty_port *port = &state->port; pr_debug("uart_open(%d) called\n", line); if (mutex_lock_interruptible(&port->mutex)) { retval = -ERESTARTSYS; goto end; } port->count++; if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { retval = -ENXIO; goto err_dec_count; } tty->driver_data = state; state->uart_port->state = state; tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; tty_port_tty_set(port, tty); if (tty_hung_up_p(filp)) { retval = -EAGAIN; goto err_dec_count; } if (port->count == 1) uart_change_pm(state, 0); retval = uart_startup(tty, state, 0); mutex_unlock(&port->mutex); if (retval == 0) retval = tty_port_block_til_ready(port, tty, filp); end: return retval; err_dec_count: port->count--; mutex_unlock(&port->mutex); goto end; }
/* * tty3215_open * * This routine is called whenever a 3215 tty is opened. */ static int tty3215_open(struct tty_struct *tty, struct file * filp) { struct raw3215_info *raw = tty->driver_data; int retval; tty_port_tty_set(&raw->port, tty); raw->port.low_latency = 0; /* don't use bottom half for pushing chars */ /* * Start up 3215 device */ retval = raw3215_startup(raw); if (retval) return retval; return 0; }
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; int result = 0; dbg("%s - port %d", __func__, port->number); wport = serial->port[1]; tty_port_tty_set(&wport->port, tty); /* Start reading from the device */ result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); return result; }
static void lge_bypass_close(struct tty_struct *tty, struct file *file) { struct bypass_driver *bypass_drv = NULL; #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diagfwd_cancel_hsic(REOPEN_HSIC); // QCT 161032 migration - NEED TO CHECK diagfwd_disconnect_bridge(0); #endif is_opened = 0; if(!tty) { pr_err( "%s tty is null\n", __func__); } else { bypass_drv = tty->driver_data; bypass_drv->enable = 0; tty_port_tty_set(bypass_drv->port, NULL); pr_info( "%s success\n", __func__); } }
static void uart_hangup(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct tty_port *port = &state->port; unsigned long flags; pr_debug("uart_hangup(%d)\n", state->uart_port->line); mutex_lock(&port->mutex); if (port->flags & ASYNC_NORMAL_ACTIVE) { uart_flush_buffer(tty); uart_shutdown(tty, state); spin_lock_irqsave(&port->lock, flags); port->count = 0; clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); spin_unlock_irqrestore(&port->lock, flags); tty_port_tty_set(port, NULL); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); } mutex_unlock(&port->mutex); }
static int mts_tty_open(struct tty_struct *tty, struct file *file) { struct mts_tty *mts_tty_drv = NULL; if (!tty) return -ENODEV; mts_tty_drv = mts_tty; if (!mts_tty_drv) return -ENODEV; tty_port_tty_set(mts_tty_drv->mts_tty_port, tty); mts_tty_drv->mts_tty_port->low_latency = 0; tty->driver_data = mts_tty_drv; mts_tty_drv->tty_struct = tty; set_bit(TTY_NO_WRITE_SPLIT, &mts_tty_drv->tty_struct->flags); pr_debug(KERN_INFO "mts_tty_open TTY device open %d,%d\n", 0, 0); return 0; }
/* * This routine is called whenever a serial port is opened. It * enables interrupts for a serial port, linking in its S structure into * the IRQ chain. It also performs the serial-specific * initialization for the tty structure. */ int rs_open(struct tty_struct *tty, struct file * filp) { struct m68k_serial *info; int retval; info = &m68k_soft[tty->index]; if (serial_paranoia_check(info, tty->name, "rs_open")) return -ENODEV; info->tport.count++; tty->driver_data = info; tty_port_tty_set(&info->tport, tty); /* * Start up serial port */ retval = startup(info, tty); if (retval) return retval; return tty_port_block_til_ready(&info->tport, tty, filp); }
static void if_close(struct tty_struct *tty, struct file *filp) { struct cardstate *cs = tty->driver_data; if (!cs) { /* happens if we didn't find cs in open */ printk(KERN_DEBUG "%s: no cardstate\n", __func__); return; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); if (!cs->connected) gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ else if (!cs->port.count) dev_warn(cs->dev, "%s: device not opened\n", __func__); else if (!--cs->port.count) tty_port_tty_set(&cs->port, NULL); mutex_unlock(&cs->mutex); module_put(cs->driver->owner); }
/* * The parsing of the command line works exactly like the * serial.c code, except that the specifier is "ttyUSB" instead * of "ttyS". */ static int usb_console_setup(struct console *co, char *options) { struct usbcons_info *info = &usbcons_info; int baud = 9600; int bits = 8; int parity = 'n'; int doflow = 0; int cflag = CREAD | HUPCL | CLOCAL; char *s; struct usb_serial *serial; struct usb_serial_port *port; int retval; struct tty_struct *tty = NULL; struct ktermios dummy; dbg("%s", __func__); if (options) { baud = simple_strtoul(options, NULL, 10); s = options; while (*s >= '0' && *s <= '9') s++; if (*s) parity = *s++; if (*s) bits = *s++ - '0'; if (*s) doflow = (*s++ == 'r'); } /* Sane default */ if (baud == 0) baud = 9600; switch (bits) { case 7: cflag |= CS7; break; default: case 8: cflag |= CS8; break; } switch (parity) { case 'o': case 'O': cflag |= PARODD; break; case 'e': case 'E': cflag |= PARENB; break; } co->cflag = cflag; /* * no need to check the index here: if the index is wrong, console * code won't call us */ serial = usb_serial_get_by_index(co->index); if (serial == NULL) { /* no device is connected yet, sorry :( */ err("No USB device connected to ttyUSB%i", co->index); return -ENODEV; } retval = usb_autopm_get_interface(serial->interface); if (retval) goto error_get_interface; port = serial->port[co->index - serial->minor]; tty_port_tty_set(&port->port, NULL); info->port = port; ++port->port.count; if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) { if (serial->type->set_termios) { /* * allocate a fake tty so the driver can initialize * the termios structure, then later call set_termios to * configure according to command line arguments */ tty = kzalloc(sizeof(*tty), GFP_KERNEL); if (!tty) { retval = -ENOMEM; err("no more memory"); goto reset_open_count; } kref_init(&tty->kref); tty_port_tty_set(&port->port, tty); tty->driver = usb_serial_tty_driver; tty->index = co->index; if (tty_init_termios(tty)) { retval = -ENOMEM; err("no more memory"); goto free_tty; } } /* only call the device specific open if this * is the first time the port is opened */ if (serial->type->open) retval = serial->type->open(NULL, port); else retval = usb_serial_generic_open(NULL, port); if (retval) { err("could not open USB console port"); goto fail; } if (serial->type->set_termios) { tty->termios->c_cflag = cflag; tty_termios_encode_baud_rate(tty->termios, baud, baud); memset(&dummy, 0, sizeof(struct ktermios)); serial->type->set_termios(tty, port, &dummy); tty_port_tty_set(&port->port, NULL); kfree(tty); } set_bit(ASYNCB_INITIALIZED, &port->port.flags); } /* Now that any required fake tty operations are completed restore * the tty port count */ --port->port.count; /* The console is special in terms of closing the device so * indicate this port is now acting as a system console. */ port->port.console = 1; mutex_unlock(&serial->disc_mutex); return retval; fail: tty_port_tty_set(&port->port, NULL); free_tty: kfree(tty); reset_open_count: port->port.count = 0; usb_autopm_put_interface(serial->interface); error_get_interface: usb_serial_put(serial); mutex_unlock(&serial->disc_mutex); return retval; }
static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; int rv = -ENODEV; int i; dbg("Entering acm_tty_open."); mutex_lock(&open_mutex); acm = acm_table[tty->index]; if (!acm || !acm->dev) goto out; else rv = 0; set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty->driver_data = acm; tty_port_tty_set(&acm->port, tty); if (usb_autopm_get_interface(acm->control) < 0) goto early_bail; else acm->control->needs_remote_wakeup = 1; mutex_lock(&acm->mutex); if (acm->port.count++) { mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); goto out; } acm->ctrlurb->dev = acm->dev; if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dbg("usb_submit_urb(ctrl irq) failed"); goto bail_out; } if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && (acm->ctrl_caps & USB_CDC_CAP_LINE)) goto full_bailout; /* enorcar*/ acm->state &= ~ACM_ABS_IDLE; if (0 > acm_set_comm_feature(acm, ACM_ABSTRACT_STATE, &acm->state) && (acm->ctrl_caps & USB_CDC_COMM_FEATURE)) goto full_bailout; usb_autopm_put_interface(acm->control); INIT_LIST_HEAD(&acm->spare_read_urbs); INIT_LIST_HEAD(&acm->spare_read_bufs); INIT_LIST_HEAD(&acm->filled_read_bufs); for (i = 0; i < acm->rx_buflimit; i++) list_add(&(acm->ru[i].list), &acm->spare_read_urbs); for (i = 0; i < acm->rx_buflimit; i++) list_add(&(acm->rb[i].list), &acm->spare_read_bufs); acm->throttle = 0; set_bit(ASYNCB_INITIALIZED, &acm->port.flags); rv = tty_port_block_til_ready(&acm->port, tty, filp); tasklet_schedule(&acm->urb_task); mutex_unlock(&acm->mutex); out: mutex_unlock(&open_mutex); return rv; full_bailout: usb_kill_urb(acm->ctrlurb); bail_out: acm->port.count--; mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); early_bail: mutex_unlock(&open_mutex); tty_port_tty_set(&acm->port, NULL); return -EIO; }
static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; int rv = -ENODEV; mutex_lock(&open_mutex); acm = acm_table[tty->index]; if (!acm || !acm->dev) goto out; else rv = 0; dev_dbg(&acm->control->dev, "%s\n", __func__); set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty->driver_data = acm; tty_port_tty_set(&acm->port, tty); if (usb_autopm_get_interface(acm->control) < 0) goto early_bail; else acm->control->needs_remote_wakeup = 1; mutex_lock(&acm->mutex); if (acm->port.count++) { mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); goto out; } acm->ctrlurb->dev = acm->dev; if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dev_err(&acm->control->dev, "%s - usb_submit_urb(ctrl irq) failed\n", __func__); goto bail_out; } if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && (acm->ctrl_caps & USB_CDC_CAP_LINE)) goto bail_out; usb_autopm_put_interface(acm->control); /* * Unthrottle device in case the TTY was closed while throttled. */ spin_lock_irq(&acm->read_lock); acm->throttled = 0; acm->throttle_req = 0; spin_unlock_irq(&acm->read_lock); if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto bail_out; set_bit(ASYNCB_INITIALIZED, &acm->port.flags); rv = tty_port_block_til_ready(&acm->port, tty, filp); mutex_unlock(&acm->mutex); out: mutex_unlock(&open_mutex); return rv; bail_out: acm->port.count--; mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); early_bail: mutex_unlock(&open_mutex); tty_port_tty_set(&acm->port, NULL); return -EIO; }
static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; int rv = -ENODEV; mutex_lock(&open_mutex); acm = acm_table[tty->index]; if (!acm || !acm->dev) goto out; else rv = 0; dev_dbg(&acm->control->dev, "%s\n", __func__); set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty->driver_data = acm; tty_port_tty_set(&acm->port, tty); if (usb_autopm_get_interface(acm->control) < 0) goto early_bail; else acm->control->needs_remote_wakeup = 0; mutex_lock(&acm->mutex); if (acm->port.count++) { mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); goto out; } if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto bail_out; acm->ctrlurb->dev = acm->dev; if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dev_err(&acm->control->dev, "%s - usb_submit_urb(ctrl irq) failed\n", __func__); goto bail_out; } if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && (acm->ctrl_caps & USB_CDC_CAP_LINE)) goto bail_out; // enorcar acm->state &= ~ACM_ABS_IDLE; if (0 > acm_set_comm_feature(acm, ACM_ABSTRACT_STATE, &acm->state) && (acm->ctrl_caps & USB_CDC_COMM_FEATURE)) goto bail_out; usb_autopm_put_interface(acm->control); set_bit(ASYNCB_INITIALIZED, &acm->port.flags); rv = tty_port_block_til_ready(&acm->port, tty, filp); mutex_unlock(&acm->mutex); out: mutex_unlock(&open_mutex); return rv; bail_out: acm->port.count--; mutex_unlock(&acm->mutex); usb_autopm_put_interface(acm->control); early_bail: mutex_unlock(&open_mutex); tty_port_tty_set(&acm->port, NULL); return -EIO; }
void hsictty_close(struct usb_serial_port *port) { int i; struct tty_struct *tty = NULL; struct usb_serial *serial = port->serial; struct hsictty_port_private *portdata; struct hsictty_intf_private *intfdata = usb_get_serial_data(serial); int channel = -1; portdata = usb_get_serial_port_data(port); wakeup_device(port, 1); down(&portdata->ch_sem_w); down(&portdata->ch_sem_r); tty = tty_port_tty_get(&port->port); channel = portdata->channel; if (!tty) goto out; if (!channel_verify(port, channel)) hsictty_dbg("%s: invalid channel (%d)!\n", __func__, channel); //goto out; if (intfdata->multi_channel_mode && portdata->lch_opened) { if (hsictty_handshake_setup(port, channel, 0) < 0) hsictty_info("%s: Can't connect server channel %d!\n", __func__, channel); portdata->lch_opened = 0; } if (test_and_clear_bit(channel, &intfdata->channel_open_flag)) clear_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty_port_tty_set(&port->port, NULL); out: hsictty_dbg("hsic tty[%d] is closed by process id:%d (\"%s\")\n", channel, current->tgid, current->comm); spin_lock_irq(&intfdata->susp_lock); portdata->opened = 0; spin_unlock_irq(&intfdata->susp_lock); if (serial->dev) { /* Stop reading/writing urbs */ for (i = 0; i < N_IN_URB; i++) usb_kill_urb(portdata->in_urbs[i]); for (i = 0; i < N_OUT_URB; i++) usb_kill_urb(portdata->out_urbs[i]); serial->interface->needs_remote_wakeup = 0; } complete_all(&portdata->tx_notifier); complete_all(&portdata->rx_notifier); if (tty) tty_kref_put(tty); //delete to balance usb-serial up(&portdata->ch_sem_w); up(&portdata->ch_sem_r); /*safe close*/ if (!check_read_msg_all_free(port)) { int timeout = 0, timeout_max = 200; hsictty_info("hsic tty[%d] waiting safe close\n", channel); complete_all(&portdata->rx_push_notifier); while (!check_read_msg_all_free(port) && ++timeout < timeout_max) { msleep(10); } if (timeout >= timeout_max) hsictty_error("hsic tty[%d] wait safe close error\n", channel); else hsictty_info("hsic tty[%d] wait safe close success\n", channel); } return; }
/* * ------------------------------------------------------------ * rs_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * S structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ static void rs_close(struct tty_struct *tty, struct file * filp) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; struct tty_port *port = &info->tport; m68328_uart *uart = &uart_addr[info->line]; unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_close")) return; local_irq_save(flags); if (tty_hung_up_p(filp)) { local_irq_restore(flags); return; } if ((tty->count == 1) && (port->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->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. */ printk("rs_close: bad serial port count; tty->count is 1, " "port->count is %d\n", port->count); port->count = 1; } if (--port->count < 0) { printk("rs_close: bad serial port count for ttyS%d: %d\n", info->line, port->count); port->count = 0; } if (port->count) { local_irq_restore(flags); return; } port->flags |= ASYNC_CLOSING; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, port->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ uart->ustcnt &= ~USTCNT_RXEN; uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); shutdown(info, tty); rs_flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; tty_port_tty_set(&info->tport, NULL); #warning "This is not and has never been valid so fix it" #if 0 if (tty->ldisc.num != ldiscs[N_TTY].num) { if (tty->ldisc.close) (tty->ldisc.close)(tty); tty->ldisc = ldiscs[N_TTY]; tty->termios.c_line = N_TTY; if (tty->ldisc.open) (tty->ldisc.open)(tty); } #endif if (port->blocked_open) { if (port->close_delay) msleep_interruptible(jiffies_to_msecs(port->close_delay)); wake_up_interruptible(&port->open_wait); } port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&port->close_wait); local_irq_restore(flags); }