void usb_serial_disconnect() { lock_disc(); assert(dev_usb_serial_initialized >= 0); dev_disconnected = 1; unlock_disc(); assert(port_initialized); if (port_tty_installed == 0) { } else { atomicBegin(); assume(fw_tty_lock == 0); fw_tty_lock = 2; atomicEnd(); assert(drv_module_ref_cnt > 0); assert(dev_usb_serial_initialized); assert(port_initialized); unlock_tty(); port_work_initialized = 0; assume(port_write_in_progress == 0); cancel_work_sync(); port_tty_installed = 0; drv_module_ref_cnt = drv_module_ref_cnt - 1; usb_serial_put(); usb_serial_port_poison_urbs(); } belkin_disconnect(); usb_serial_put(); }
void usb_serial_disconnect () { int x; lock_disc(); /* must set a flag, to signal subdrivers */ notify(dev_disconnected); unlock_disc(); //assert (dev_usb_serial_initialized>=0); x = dev_usb_serial_initialized; x = port_initialized; if (nondet) { assume(port_tty_installed); assume_not (port_write_in_progress); //serial_hangup (); //serial_close (); lock_tty (); //assert (drv_module_ref_cnt > 0); //x = drv_module_ref_cnt; x = dev_usb_serial_initialized; x = port_initialized; port_tty_state = 0; reset(port_tty_installed); //drv_module_ref_cnt--; reset(drv_module_ref_cnt); usb_serial_put(); // end: serial_close unlock_tty (); assume_not(port_work); //usb_serial_port_poison_urbs(); //wake_up_interruptible(&port->port.delta_msr_wait); port_work_stop = 1; port_work_initialized = 0; //if (port_dev_registered) // port_dev_registered = 0; } else { assume_not(port_tty_installed); }; //belkin_disconnect (); /* let the last holder of this object cause it to be cleaned up */ usb_serial_put(); }
void usb_serial_console_disconnect(struct usb_serial *serial) { if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) { usb_serial_console_exit(); usb_serial_put(serial); } }
static void serial_close(struct tty_struct *tty, struct file * filp) { struct usb_serial_port *port = tty->driver_data; if (!port) return; dbg("%s - port %d", __FUNCTION__, port->number); mutex_lock(&port_mutex); if (port->open_count == 0) { mutex_unlock(&port_mutex); return; } --port->open_count; if (port->open_count == 0) { /* only call the device specific close if this * port is being closed by the last owner */ port->serial->type->close(port, filp); if (port->tty) { if (port->tty->driver_data) port->tty->driver_data = NULL; port->tty = NULL; } module_put(port->serial->type->owner); } mutex_unlock(&port_mutex); usb_serial_put(port->serial); }
void serial_install() { lock_table(); if (port_idr_registered == 0) { unlock_table(); } else { lock_disc(); if (dev_disconnected == 0) { assert(port_initialized); assert(dev_usb_serial_initialized > 0); dev_usb_serial_initialized = dev_usb_serial_initialized + 1; unlock_table(); try_module_get(); if (drv_module_ref_cnt <= 0) { usb_serial_put(); unlock_disc(); } else { dev_autopm = dev_autopm + 1; port_tty_installed = 1; unlock_disc(); } } else { unlock_disc(); unlock_table(); } } }
static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct usb_serial *serial; int length = 0; int i; off_t begin = 0; char tmp[40]; dbg("%s", __FUNCTION__); length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION); for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { serial = usb_serial_get_by_index(i); if (serial == NULL) continue; length += sprintf (page+length, "%d:", i); if (serial->type->owner) length += sprintf (page+length, " module:%s", module_name(serial->type->owner)); length += sprintf (page+length, " name:\"%s\"", serial->type->name); length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product); length += sprintf (page+length, " num_ports:%d", serial->num_ports); length += sprintf (page+length, " port:%d", i - serial->minor + 1); usb_make_path(serial->dev, tmp, sizeof(tmp)); length += sprintf (page+length, " path:%s", tmp); length += sprintf (page+length, "\n"); if ((length + begin) > (off + count)) { usb_serial_put(serial); goto done; } if ((length + begin) < off) { begin += length; length = 0; } usb_serial_put(serial); } *eof = 1; done: if (off >= (length + begin)) return 0; *start = page + (off-begin); return ((count < begin+length-off) ? count : begin+length-off); }
int main(void) { struct usb_serial serial ; { { #line 50 usb_serial_put(& serial); } #line 51 return (0); } }
void serial_install () { int x; // port = usb_serial_port_get_by_minor(idx); lock_table(); if (nondet) { assume_not(port_idr_registered); unlock_table (); return; } else { assume(port_idr_registered); lock_disc (); if (nondet) { assume (dev_disconnected); unlock_disc (); unlock_table (); return; } else { assume_not(dev_disconnected); x = port_initialized; //assert (dev_usb_serial_initialized > 0); x = dev_usb_serial_initialized; dev_usb_serial_initialized++; unlock_table (); try_module_get (); if (/*drv_module_ref_cnt <= 0*/nondet) { assume_not(drv_module_ref_cnt); usb_serial_put (); unlock_disc (); return; } else { assume(drv_module_ref_cnt); dev_autopm++; port_tty_state=1; notify(port_tty_installed); unlock_disc (); } } } }
/* * 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; }
/***************************************************************************** * Driver tty interface functions *****************************************************************************/ static int serial_open (struct tty_struct *tty, struct file * filp) { struct usb_serial *serial; struct usb_serial_port *port; unsigned int portNumber; int retval; dbg("%s", __FUNCTION__); /* get the serial object associated with this tty pointer */ serial = usb_serial_get_by_index(tty->index); if (!serial) { tty->driver_data = NULL; return -ENODEV; } portNumber = tty->index - serial->minor; port = serial->port[portNumber]; if (!port) { retval = -ENODEV; goto bailout_kref_put; } if (mutex_lock_interruptible(&port_mutex)) { retval = -ERESTARTSYS; goto bailout_kref_put; } ++port->open_count; /* set up our port structure making the tty driver * remember our port object, and us it */ tty->driver_data = port; port->tty = tty; if (port->open_count == 1) { /* lock this module before we call it * this may fail, which means we must bail out, * safe because we are called with BKL held */ if (!try_module_get(serial->type->owner)) { retval = -ENODEV; goto bailout_mutex_unlock; } /* only call the device specific open if this * is the first time the port is opened */ retval = serial->type->open(port, filp); if (retval) goto bailout_module_put; } mutex_unlock(&port_mutex); return 0; bailout_module_put: module_put(serial->type->owner); bailout_mutex_unlock: port->open_count = 0; tty->driver_data = NULL; port->tty = NULL; mutex_unlock(&port_mutex); bailout_kref_put: usb_serial_put(serial); return retval; }