static int ps3_vuart_handle_interrupt_tx()

in ps3-vuart.c [718:768]


static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev)
{
	int result = 0;
	struct ps3_vuart_port_priv *priv = to_port_priv(dev);
	unsigned long flags;
	struct list_buffer *lb, *n;
	unsigned long bytes_total = 0;

	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);

	spin_lock_irqsave(&priv->tx_list.lock, flags);

	list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) {

		u64 bytes_written;

		result = ps3_vuart_raw_write(dev, lb->head, lb->tail - lb->head,
			&bytes_written);

		if (result) {
			dev_dbg(&dev->core,
				"%s:%d: ps3_vuart_raw_write failed\n",
				__func__, __LINE__);
			break;
		}

		bytes_total += bytes_written;

		if (bytes_written < lb->tail - lb->head) {
			lb->head += bytes_written;
			dev_dbg(&dev->core,
				"%s:%d cleared buf_%lu, %llxh bytes\n",
				__func__, __LINE__, lb->dbg_number,
				bytes_written);
			goto port_full;
		}

		dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__,
			lb->dbg_number);

		list_del(&lb->link);
		kfree(lb);
	}

	ps3_vuart_disable_interrupt_tx(dev);
port_full:
	spin_unlock_irqrestore(&priv->tx_list.lock, flags);
	dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
		__func__, __LINE__, bytes_total);
	return result;
}