Exemple #1
0
static inline int
tx_link_write_error(txdrv_t *tx, const char *func)
{
	struct attr *attr = tx->opaque;

	if (is_temporary_error(errno) || ENOBUFS == errno)
		return 0;

	switch (errno) {
	/*
	 * The following are probably due to bugs in the libc, but this is in
	 * the same vein as write() failing with -1 whereas errno == 0!  Be more
	 * robust against bugs in the components we rely on. --RAM, 09/10/2003
	 */
	case EINPROGRESS:		/* Weird, but seen it -- RAM, 07/10/2003 */
		g_warning("%s(fd=%d) failed with weird errno = %d: %m -- "
			"assuming EAGAIN", func, attr->wio->fd(attr->wio), errno);
		return 0;

	case EPIPE:
	case ECONNRESET:
	case ECONNABORTED:
		tx_error(tx);
		attr->cb->eof_remove(tx->owner,
			_("Write failed: %s"), g_strerror(errno));
		return -1;

	default:
		{
			wrap_io_t *wio = ((struct attr *) tx->opaque)->wio;
			int fd = wio->fd(wio);
			g_warning("%s: write failed on fd #%d with unexpected error: %m",
				func, fd);
		}
		/* FALL THROUGH */

	case ENOSPC:
#ifdef EDQUOT
	case EDQUOT:
#endif /* EDQUOT */
#ifdef ESHUTDOWN
	case ESHUTDOWN:
#endif	/* ESHUTDOWN */
	case EACCES:
	case EFBIG:
	case EHOSTDOWN:
	case EHOSTUNREACH:
	case EIO:
	case ENETDOWN:
	case ENETUNREACH:
	case ETIMEDOUT:
		tx_error(tx);
		attr->cb->eof_shutdown(tx->owner,
			_("Write failed: %s"), g_strerror(errno));
		return -1;
	}

	return 0;		/* Just in case */
}
Exemple #2
0
static irqreturn_t
rio_interrupt (int irq, void *dev_instance)
{
	struct net_device *dev = dev_instance;
	struct netdev_private *np;
	unsigned int_status;
	long ioaddr;
	int cnt = max_intrloop;
	int handled = 0;

	ioaddr = dev->base_addr;
	np = netdev_priv(dev);
	while (1) {
		int_status = readw (ioaddr + IntStatus);
		writew (int_status, ioaddr + IntStatus);
		int_status &= DEFAULT_INTR;
		if (int_status == 0 || --cnt < 0)
			break;
		handled = 1;
		/* Processing received packets */
		if (int_status & RxDMAComplete)
			receive_packet (dev);
		/* TxDMAComplete interrupt */
		if ((int_status & (TxDMAComplete|IntRequested))) {
			int tx_status;
			tx_status = readl (ioaddr + TxStatus);
			if (tx_status & 0x01)
				tx_error (dev, tx_status);
			/* Free used tx skbuffs */
			rio_free_tx (dev, 1);
		}

		/* Handle uncommon events */
		if (int_status &
		    (HostError | LinkEvent | UpdateStats))
			rio_error (dev, int_status);
	}
	if (np->cur_tx != np->old_tx)
		writel (100, ioaddr + CountDown);
	return IRQ_RETVAL(handled);
}
Exemple #3
0
/**
 * Invoked when the output file descriptor can accept more data.
 */
static void
is_writable(void *data, int unused_source, inputevt_cond_t cond)
{
	txdrv_t *tx = data;
	struct attr *attr = tx->opaque;

	(void) unused_source;
	g_assert(tx->flags & TX_SERVICE);		/* Servicing enabled */

	if (cond & INPUT_EVENT_EXCEPTION) {
		tx_error(tx);
		attr->cb->eof_remove(tx->owner, _("Write failed (Input Exception)"));
		return;
	}

	/*
	 * We can write again on the node's socket.  Service the queue.
	 */

	g_assert(tx->srv_routine);
	tx->srv_routine(tx->srv_arg);
}
/**
 * Flush compression within filling buffer.
 *
 * @return success status, failure meaning we shutdown.
 */
static bool
deflate_flush(txdrv_t *tx)
{
	struct attr *attr = tx->opaque;
	z_streamp outz = attr->outz;
	struct buffer *b;
	int ret;
	int old_avail;

retry:
	b = &attr->buf[attr->fill_idx];	/* Buffer we fill */

	if (tx_deflate_debugging(9)) {
		g_debug("TX %s: (%s) flushing %zu bytes "
			"(buffer #%d, flushed %zu, unflushed %zu) [%c%c]",
			G_STRFUNC, gnet_host_to_string(&tx->host),
			b->wptr - b->rptr, attr->fill_idx,
			attr->flushed, attr->unflushed,
			(attr->flags & DF_FLOWC) ? 'C' : '-',
			(attr->flags & DF_FLUSH) ? 'f' : '-');
	}

	/*
	 * Prepare call to deflate().
	 *
	 * We force avail_in to 0, and don't touch next_in: no input should
	 * be consumed.
	 */

	outz->next_out = cast_to_pointer(b->wptr);
	outz->avail_out = old_avail = b->end - b->wptr;

	outz->avail_in = 0;

	g_assert(outz->avail_out > 0);

	ret = deflate(outz, (tx->flags & TX_CLOSING) ? Z_FINISH : Z_SYNC_FLUSH);

	switch (ret) {
	case Z_BUF_ERROR:				/* Nothing to flush */
		goto done;
	case Z_OK:
	case Z_STREAM_END:
		break;
	default:
		attr->flags |= DF_SHUTDOWN;
		tx_error(tx);

		/* XXX: The callback must not destroy the tx! */
		(*attr->cb->shutdown)(tx->owner, "Compression flush failed: %s",
				zlib_strerror(ret));
		return FALSE;
	}

	{
		size_t written;

		written = old_avail - outz->avail_out;
		b->wptr += written;
		attr->flushed += written;

		if (NULL != attr->cb->add_tx_deflated)
			attr->cb->add_tx_deflated(tx->owner, written);
	}

	/*
	 * Check whether avail_out is 0.
	 *
	 * If it is, then we lacked room to complete the flush.  Try to send the
	 * buffer and continue.
	 */

	if (0 == outz->avail_out) {
		if (attr->send_idx >= 0) {			/* Send buffer not sent yet */
			attr->flags |= DF_FLUSH;		/* In flush mode */
			deflate_set_flowc(tx, TRUE);	/* Starting flow-control */
			return TRUE;
		}

		deflate_rotate_and_send(tx);		/* Can set TX_ERROR */

		if (tx->flags & TX_ERROR)
			return FALSE;

		goto retry;
	}

done:
	deflate_flushed(tx);

	return TRUE;		/* Fully flushed */
}
/**
 * Write ready-to-be-sent buffer to the lower layer.
 */
static void
deflate_send(txdrv_t *tx)
{
	struct attr *attr = tx->opaque;
	struct buffer *b;
	size_t len;					/**< Amount of bytes to send */
	ssize_t r;

	g_assert(attr->send_idx >= 0);	/* We have something to send */
	g_assert(attr->send_idx < BUFFER_COUNT);

	/*
	 * Compute data to be sent.
	 */

	b = &attr->buf[attr->send_idx];		/* Buffer to send */
	len = b->wptr - b->rptr;

	g_assert(len > 0 && len <= INT_MAX);

	/*
	 * Write as much as possible.
	 */

	r = tx_write(tx->lower, b->rptr, len);

	if (tx_deflate_debugging(9)) {
		g_debug("TX %s: (%s) wrote %zu/%zu bytes (buffer #%d) [%c%c]",
			G_STRFUNC, gnet_host_to_string(&tx->host), r, len, attr->send_idx,
			(attr->flags & DF_FLOWC) ? 'C' : '-',
			(attr->flags & DF_FLUSH) ? 'f' : '-');
	}
	if ((ssize_t) -1 == r) {
		tx_error(tx);
		return;
	}

	/*
	 * If we wrote everything, we're done.
	 */

	if ((size_t) r == len) {
		if (tx_deflate_debugging(9)) {
			g_debug("TX %s: (%s) buffer #%d is empty",
				G_STRFUNC, gnet_host_to_string(&tx->host), attr->send_idx);
		}
		attr->send_idx = -1;			/* Signals: is now free */
		b->wptr = b->rptr = b->arena;	/* Buffer is now empty */
		return;
	}

	/*
	 * We were unable to send the whole buffer.  Enable servicing when
	 * the lower layer will be ready for more input.
	 */

	b->rptr += r;

	g_assert(b->rptr < b->wptr);		/* We haven't written everything */

	tx_srv_enable(tx->lower);
}