+
+ priv->write_urb_in_use = 0;
+
+ /* send any buffered data */
+ cypress_send(port);
+}
+
+
+/*****************************************************************************
+ * Write buffer functions - buffering code from pl2303 used
+ *****************************************************************************/
+
+/*
+ * cypress_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+
+static struct cypress_buf *cypress_buf_alloc(unsigned int size)
+{
+
+ struct cypress_buf *cb;
+
+
+ if (size == 0)
+ return NULL;
+
+ cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
+ if (cb == NULL)
+ return NULL;
+
+ cb->buf_buf = kmalloc(size, GFP_KERNEL);
+ if (cb->buf_buf == NULL) {
+ kfree(cb);
+ return NULL;
+ }
+
+ cb->buf_size = size;
+ cb->buf_get = cb->buf_put = cb->buf_buf;
+
+ return cb;
+
+}
+
+
+/*
+ * cypress_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+
+static void cypress_buf_free(struct cypress_buf *cb)
+{
+ if (cb) {
+ kfree(cb->buf_buf);
+ kfree(cb);
+ }
+}
+
+
+/*
+ * cypress_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+
+static void cypress_buf_clear(struct cypress_buf *cb)
+{
+ if (cb != NULL)
+ cb->buf_get = cb->buf_put;
+ /* equivalent to a get of all data available */
+}
+
+
+/*
+ * cypress_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
+{
+ if (cb != NULL)
+ return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
+ else
+ return 0;
+}
+
+
+/*
+ * cypress_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
+{
+ if (cb != NULL)
+ return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
+ else
+ return 0;
+}
+
+
+/*
+ * cypress_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
+ unsigned int count)
+{
+
+ unsigned int len;
+
+
+ if (cb == NULL)
+ return 0;
+
+ len = cypress_buf_space_avail(cb);
+ if (count > len)
+ count = len;
+
+ if (count == 0)
+ return 0;
+
+ len = cb->buf_buf + cb->buf_size - cb->buf_put;
+ if (count > len) {
+ memcpy(cb->buf_put, buf, len);
+ memcpy(cb->buf_buf, buf+len, count - len);
+ cb->buf_put = cb->buf_buf + count - len;
+ } else {
+ memcpy(cb->buf_put, buf, count);
+ if (count < len)
+ cb->buf_put += count;
+ else /* count == len */
+ cb->buf_put = cb->buf_buf;
+ }
+
+ return count;