Exemplo n.º 1
0
static int serial_write_room (struct tty_struct *tty)
{
	/* Return the amount of room for writing. */
	unsigned long flags;
	struct serproto_dev *device;
	int n = 0;

	dbg_tx (7, "entered");

	if ((device = tty->driver_data) == NULL) {
		dbg_tx (1, "not presently connected -> FAIL");
		return (-EINVAL);
	}
	read_lock_irqsave (&device->rwlock, flags);
	if (device->connected &&
	    (device->queued_bytes < device->max_queue_bytes) &&
	    (device->max_queue_entries == 0
	     || device->queued_entries < device->max_queue_entries)) {
#if 0
		if (device->tx_size < (n = device->max_queue_bytes - device->queued_bytes)) {
			n = device->tx_size;
		}
#else
		n = device->max_queue_bytes - device->queued_bytes;
#endif
	}
	read_unlock_irqrestore (&device->rwlock, flags);
	// Shouldn't really access these outside the lock, but only the dbg msg can go wrong.
	dbg_tx (6, "c:%c b=%u/%u e=%u/%u -> %d", (device->connected ? 'T' : 'F'),
		device->queued_bytes, device->max_queue_bytes,
		device->queued_entries, device->max_queue_entries, n);
	return (n);
}
Exemplo n.º 2
0
static inline int sio_xmit(int ch)
{
	unsigned long flags;

	dbg_tx("%s: ch %02x (STA %02x)\n", __FUNCTION__, ch, rd_reg(OKI_SIOSTA));

	local_irq_save(flags);

	/* decided wether we can write this directly to the uart
	 * or wether we are going to have to buffer it */

	printk(KERN_DEBUG "%s: ready %d, locked %d, xchar %02x\n",
	       __FUNCTION__, sio_xmit_ready(), sio_xmit_locked(), x_char);

	if (sio_xmit_ready() && !sio_xmit_locked() && x_char == 0) {
		sio_xmit_do(ch);
		goto exit;
	}

	if (putp + 1 == getp ||
	    (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf)) {
		local_irq_restore(flags);
		return 0;
	}

	*putp = ch;

	if (++putp >= wbuf + sizeof(wbuf))
		putp = wbuf;

 exit:
	local_irq_restore(flags);
	return 1;
}
Exemplo n.º 3
0
/**
 * bi_send_urb - start transmit
 * @urb:
 */
int bi_send_urb(struct usbd_urb *urb)
{
    unsigned long flags;
    dbg_tx(4, "urb: %p", urb);
    local_irq_save(flags);
    if (urb && urb->endpoint && !urb->endpoint->tx_urb) {
        dbg_tx(2, "urb: %p endpoint: %x", urb, urb->endpoint->endpoint_address);
        usbd_tx_complete_irq(urb->endpoint, 0);
        udc_start_in_irq(urb->endpoint, urb->device);
    }
    local_irq_restore(flags);

    // Shouldn't need to make this atomic, all we need is a change indicator
    urb->device->usbd_rxtx_timestamp = jiffies;

    return 0;
}
Exemplo n.º 4
0
/**
 * usbd_cancel_urb - cancel an urb being sent
 * @urb: pointer to an urb structure
 *
 * Used by a USB Function driver to cancel an urb that is being
 * sent.
 */
int usbd_cancel_urb (struct usb_device_instance *device, struct urb *urb)
{
	dbg_tx (3, "%p", urb);
	if (!device->bus->driver->ops->cancel_urb) {
		// XXX should we do usbd_dealloc_urb(urb);
		return 0;
	}
	//urb->device->urbs_queued++;
	return device->bus->driver->ops->cancel_urb (urb);
}
Exemplo n.º 5
0
static void sio_xmit_check(void)
{
	unsigned int status;

	/* must be called with irqs disabled */

	status = rd_reg(OKI_SIOSTA);

	dbg_tx("%s: status=%02x\n", __FUNCTION__, status);

	if (status & OKI_SIOSTA_TRIRQ) {
		sio_tx_inprogress = 0;
		wr_reg(OKI_SIOSTA, OKI_SIOSTA_TRIRQ);
	} else if (time_after(jiffies, sio_tx_last + HZ/10)) {
		printk(KERN_ERR "sio: tx timeout\n");
		sio_tx_inprogress = 0;
	}
}
Exemplo n.º 6
0
static int serial_write (struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
{
	// Return the number of bytes (out of count) that get written,
	// or negative for error.
	unsigned long flags;
	struct serproto_dev *device;
	int cnt = count;
	int size;
	const unsigned char *currpos = buf;

	unsigned char *buffer;

	dbg_tx (3, "count=%d", count);

	if ((device = tty->driver_data) == NULL) {
		dbg_tx (1, "not presently connected -> FAIL");
		return -EINVAL;
	}
	dbgPRINTmem (dbgflg_tx, 4, buf, count);

	// loop on data
	while (cnt > 0) {

		int length;

		// send at most tx_size bytes
		size = MIN (device->tx_size, cnt);

		write_lock_irqsave (&device->rwlock, flags);
		// Make sure we can send.
		if (!device->connected ||
		    (device->max_queue_entries > 0
		     && (device->queued_entries >= device->max_queue_entries))
		    || (device->queued_bytes >= device->max_queue_bytes)) {
			// Can't write any more,
			// return the number that we did manage to send.
			write_unlock_irqrestore (&device->rwlock, flags);
			dbg_tx (2, "->%d/%d", (count - cnt), count);
			return (count - cnt);
		}
		size = MIN ((device->max_queue_bytes - device->queued_bytes), size);

		// allocate a buffer

		length = (device->blocked ? device->tx_size : size) + 1 + device->trailer;
		dbg_tx (1, "------> blocked: %d tx_size: %d size: %d trailer: %d, length: %d",
			device->blocked, device->tx_size, size, device->trailer, length);

		if ((buffer = kmalloc (length, GFP_KERNEL)) == NULL) {
			write_unlock_irqrestore (&device->rwlock, flags);
			dbg_tx (2, "->ENOMEM");
			return -ENOMEM;
		}
		memset (buffer, '\0', length);


		// copy data
		if (from_user) {
			copy_from_user ((void *) buffer, currpos, size);
		} else {
			memcpy ((void *) buffer, currpos, size);
		}

		currpos += size;
		cnt -= size;

		device->xmit_data (device->number, buffer, size);

		device->queued_entries++;
		device->queued_bytes += size;
		write_unlock_irqrestore (&device->rwlock, flags);
	}

	// Everything went out.
	dbg_tx (5, "->%d (all)", count);

	return count;
}