コード例 #1
0
ファイル: fhci-tds.c プロジェクト: ANFS/ANFS-kernel
/* destroy an USB endpoint */
void fhci_ep0_free(struct fhci_usb *usb)
{
	struct endpoint *ep;
	int size;

	ep = usb->ep0;
	if (ep) {
		if (ep->td_base)
			cpm_muram_free(cpm_muram_offset(ep->td_base));

		if (kfifo_initialized(&ep->conf_frame_Q)) {
			size = cq_howmany(&ep->conf_frame_Q);
			for (; size; size--) {
				struct packet *pkt = cq_get(&ep->conf_frame_Q);

				kfree(pkt);
			}
			cq_delete(&ep->conf_frame_Q);
		}

		if (kfifo_initialized(&ep->empty_frame_Q)) {
			size = cq_howmany(&ep->empty_frame_Q);
			for (; size; size--) {
				struct packet *pkt = cq_get(&ep->empty_frame_Q);

				kfree(pkt);
			}
			cq_delete(&ep->empty_frame_Q);
		}

		if (kfifo_initialized(&ep->dummy_packets_Q)) {
			size = cq_howmany(&ep->dummy_packets_Q);
			for (; size; size--) {
				u8 *buff = cq_get(&ep->dummy_packets_Q);

				kfree(buff);
			}
			cq_delete(&ep->dummy_packets_Q);
		}

		kfree(ep);
		usb->ep0 = NULL;
	}
}
コード例 #2
0
ファイル: kfifo_buf.c プロジェクト: Sangil-Lee/ZynqFPGA
static int iio_kfifo_write(struct iio_buffer *r, size_t n,
	const char __user *buf)
{
	struct iio_kfifo *kf = iio_to_kfifo(r);
	int ret, copied;

	mutex_lock(&kf->user_lock);
	if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
		ret = -EINVAL;
	else
		ret = kfifo_from_user(&kf->kf, buf, n, &copied);
	mutex_unlock(&kf->user_lock);
	if (ret)
		return ret;

	return copied;
}
コード例 #3
0
ファイル: kfifo_buf.c プロジェクト: Sangil-Lee/ZynqFPGA
static int iio_read_kfifo(struct iio_buffer *r, size_t n, char __user *buf)
{
	int ret, copied;
	struct iio_kfifo *kf = iio_to_kfifo(r);

	if (mutex_lock_interruptible(&kf->user_lock))
		return -ERESTARTSYS;

	if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
		ret = -EINVAL;
	else
		ret = kfifo_to_user(&kf->kf, buf, n, &copied);
	mutex_unlock(&kf->user_lock);
	if (ret < 0)
		return ret;

	return copied;
}
コード例 #4
0
ファイル: u_serial.c プロジェクト: AlexShiLucky/linux
/*
 * gs_open sets up the link between a gs_port and its associated TTY.
 * That link is broken *only* by TTY close(), and all driver methods
 * know that.
 */
static int gs_open(struct tty_struct *tty, struct file *file)
{
	int		port_num = tty->index;
	struct gs_port	*port;
	int		status;

	do {
		mutex_lock(&ports[port_num].lock);
		port = ports[port_num].port;
		if (!port)
			status = -ENODEV;
		else {
			spin_lock_irq(&port->port_lock);

			/* already open?  Great. */
			if (port->port.count) {
				status = 0;
				port->port.count++;

			/* currently opening/closing? wait ... */
			} else if (port->openclose) {
				status = -EBUSY;

			/* ... else we do the work */
			} else {
				status = -EAGAIN;
				port->openclose = true;
			}
			spin_unlock_irq(&port->port_lock);
		}
		mutex_unlock(&ports[port_num].lock);

		switch (status) {
		default:
			/* fully handled */
			return status;
		case -EAGAIN:
			/* must do the work */
			break;
		case -EBUSY:
			/* wait for EAGAIN task to finish */
			msleep(1);
			/* REVISIT could have a waitchannel here, if
			 * concurrent open performance is important
			 */
			break;
		}
	} while (status != -EAGAIN);

	/* Do the "real open" */
	spin_lock_irq(&port->port_lock);

	/* allocate circular buffer on first open */
	if (!kfifo_initialized(&port->port_write_buf)) {

		spin_unlock_irq(&port->port_lock);
		status = kfifo_alloc(&port->port_write_buf,
				     WRITE_BUF_SIZE, GFP_KERNEL);
		spin_lock_irq(&port->port_lock);

		if (status) {
			pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n",
				port->port_num, tty, file);
			port->openclose = false;
			goto exit_unlock_port;
		}
	}

	/* REVISIT if REMOVED (ports[].port NULL), abort the open
	 * to let rmmod work faster (but this way isn't wrong).
	 */

	/* REVISIT maybe wait for "carrier detect" */

	tty->driver_data = port;
	port->port.tty = tty;

	port->port.count = 1;
	port->openclose = false;

	/* if connected, start the I/O stream */
	if (port->port_usb) {
		struct gserial	*gser = port->port_usb;

		pr_debug("gs_open: start ttyGS%d\n", port->port_num);
		gs_start_io(port);

		if (gser->connect)
			gser->connect(gser);
	}

	pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);

	status = 0;

exit_unlock_port:
	spin_unlock_irq(&port->port_lock);
	return status;
}