Esempio n. 1
0
static void acm_port_down(struct acm *acm, int drain)
{
	int i, nr = acm->rx_buflimit;
	mutex_lock(&open_mutex);
	if (acm->dev) {
		usb_autopm_get_interface(acm->control);
		acm_set_control(acm, acm->ctrlout = 0);
		/* try letting the last writes drain naturally */
		if (drain) {
			wait_event_interruptible_timeout(acm->drain_wait,
				(ACM_NW == acm_wb_is_avail(acm)) || !acm->dev,
					ACM_CLOSE_TIMEOUT * HZ);
		}
		usb_kill_urb(acm->ctrlurb);
		for (i = 0; i < ACM_NW; i++)
			usb_kill_urb(acm->wb[i].urb);
		tasklet_disable(&acm->urb_task);
		for (i = 0; i < nr; i++)
			usb_kill_urb(acm->ru[i].urb);
		tasklet_enable(&acm->urb_task);
		acm->control->needs_remote_wakeup = 0;
		usb_autopm_put_interface(acm->control);
	}
	mutex_unlock(&open_mutex);
}
Esempio n. 2
0
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
{
	struct acm *acm = tty->driver_data;
	int i,nr;

	if (!acm || !acm->used)
		return;

	nr = acm->rx_buflimit;
	mutex_lock(&open_mutex);
	if (!--acm->used) {
		if (acm->dev) {
			usb_autopm_get_interface(acm->control);
			acm_set_control(acm, acm->ctrlout = 0);

			/* try letting the last writes drain naturally */
			wait_event_interruptible_timeout(acm->drain_wait,
					(ACM_NW == acm_wb_is_avail(acm))
						|| !acm->dev,
					ACM_CLOSE_TIMEOUT * HZ);

			usb_kill_urb(acm->ctrlurb);
			for (i = 0; i < ACM_NW; i++)
				usb_kill_urb(acm->wb[i].urb);
			for (i = 0; i < nr; i++)
				usb_kill_urb(acm->ru[i].urb);
			acm->control->needs_remote_wakeup = 0;
			usb_autopm_put_interface(acm->control);
		} else
			acm_tty_unregister(acm);
	}
	mutex_unlock(&open_mutex);
}
Esempio n. 3
0
static int acm_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	if (acm->disconnected)
		return 0;
	return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize;
}
Esempio n. 4
0
static int acm_tty_write_room(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	/*
	 * Do not let the line discipline to know that we have a reserve,
	 * or it might get too enthusiastic.
	 */
	return acm_wb_is_avail(acm) ? acm->writesize : 0;
}
Esempio n. 5
0
static int acm_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	if (!ACM_READY(acm))
		return -EINVAL;
	/*
	 * This is inaccurate (overcounts), but it works.
	 */
	return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize;
}
Esempio n. 6
0
static int acm_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	/*
	 * if the device was unplugged then any remaining characters fell out
	 * of the connector ;)
	 */
	if (acm->disconnected)
		return 0;
	/*
	 * This is inaccurate (overcounts), but it works.
	 */
	return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize;
}
Esempio n. 7
0
static int acm_write_start(struct acm *acm, int wbn)
{
	unsigned long flags;
	struct acm_wb *wb;
	int rc;

	spin_lock_irqsave(&acm->write_lock, flags);
	if (!acm->dev) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return -ENODEV;
	}

	if (!acm->write_ready) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;	/* A white lie */
	}

	wb = &acm->wb[wbn];
	if(acm_wb_is_avail(acm) <= 1)
		acm->write_ready = 0;

	dbg("%s susp_count: %d", __FUNCTION__, acm->susp_count);
	if (acm->susp_count) {
		acm->old_ready = acm->write_ready;
		acm->delayed_wb = wb;
		acm->write_ready = 0;
		schedule_work(&acm->waker);
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;	/* A white lie */
	}
	usb_mark_last_busy(acm->dev);

	if (!acm_wb_is_used(acm, wbn)) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;
	}

	rc = acm_start_wb(acm, wb);
	spin_unlock_irqrestore(&acm->write_lock, flags);

	return rc;

}
Esempio n. 8
0
/*
 * Poke write.
 */
static int acm_write_start(struct acm *acm, int wbn)
{
	unsigned long flags;
	struct acm_wb *wb;
	int rc;

	spin_lock_irqsave(&acm->write_lock, flags);
	if (!acm->dev) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return -ENODEV;
	}

	if (!acm->write_ready) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;	/* A white lie */
	}

	if (!acm_wb_is_used(acm, wbn)) {
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;
	}
	wb = &acm->wb[wbn];

	if(acm_wb_is_avail(acm) <= 1)
		acm->write_ready = 0;
	spin_unlock_irqrestore(&acm->write_lock, flags);

	wb->urb->transfer_buffer = wb->buf;
	wb->urb->transfer_dma = wb->dmah;
	wb->urb->transfer_buffer_length = wb->len;
	wb->urb->dev = acm->dev;

	if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
		dbg("usb_submit_urb(write bulk) failed: %d", rc);
		acm_write_done(acm, wb);
	}
	return rc;
}
Esempio n. 9
0
static int acm_tty_write_room(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	return acm_wb_is_avail(acm) ? acm->writesize : 0;
}