From 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 Mon Sep 17 00:00:00 2001 From: Yunhong Jiang Date: Tue, 4 Aug 2015 12:17:53 -0700 Subject: Add the rt linux 4.1.3-rt3 as base Import the rt linux 4.1.3-rt3 as OPNFV kvm base. It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and the base is: commit 0917f823c59692d751951bf5ea699a2d1e2f26a2 Author: Sebastian Andrzej Siewior Date: Sat Jul 25 12:13:34 2015 +0200 Prepare v4.1.3-rt3 Signed-off-by: Sebastian Andrzej Siewior We lose all the git history this way and it's not good. We should apply another opnfv project repo in future. Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423 Signed-off-by: Yunhong Jiang --- kernel/drivers/staging/vt6656/usbpipe.c | 308 ++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 kernel/drivers/staging/vt6656/usbpipe.c (limited to 'kernel/drivers/staging/vt6656/usbpipe.c') diff --git a/kernel/drivers/staging/vt6656/usbpipe.c b/kernel/drivers/staging/vt6656/usbpipe.c new file mode 100644 index 000000000..88bf518f2 --- /dev/null +++ b/kernel/drivers/staging/vt6656/usbpipe.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * + * File: usbpipe.c + * + * Purpose: Handle USB control endpoint + * + * Author: Warren Hsu + * + * Date: Mar. 29, 2005 + * + * Functions: + * vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM + * vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM + * vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM + * vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM + * + * Revision History: + * 04-05-2004 Jerry Chen: Initial release + * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte + * + */ + +#include "int.h" +#include "rxtx.h" +#include "dpc.h" +#include "desc.h" +#include "device.h" +#include "usbpipe.h" + +#define USB_CTL_WAIT 500 /* ms */ + +int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) +{ + int status = 0; + + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) + return STATUS_FAILURE; + + mutex_lock(&priv->usb_lock); + + status = usb_control_msg(priv->usb, + usb_sndctrlpipe(priv->usb, 0), request, 0x40, value, + index, buffer, length, USB_CTL_WAIT); + + mutex_unlock(&priv->usb_lock); + + if (status < (int)length) + return STATUS_FAILURE; + + return STATUS_SUCCESS; +} + +void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) +{ + vnt_control_out(priv, MESSAGE_TYPE_WRITE, + reg_off, reg, sizeof(u8), &data); +} + +int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) +{ + int status; + + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) + return STATUS_FAILURE; + + mutex_lock(&priv->usb_lock); + + status = usb_control_msg(priv->usb, + usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value, + index, buffer, length, USB_CTL_WAIT); + + mutex_unlock(&priv->usb_lock); + + if (status < (int)length) + return STATUS_FAILURE; + + return STATUS_SUCCESS; +} + +void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data) +{ + vnt_control_in(priv, MESSAGE_TYPE_READ, + reg_off, reg, sizeof(u8), data); +} + +static void vnt_start_interrupt_urb_complete(struct urb *urb) +{ + struct vnt_private *priv = urb->context; + int status; + + switch (urb->status) { + case 0: + case -ETIMEDOUT: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + priv->int_buf.in_use = false; + return; + default: + break; + } + + status = urb->status; + + if (status != STATUS_SUCCESS) { + priv->int_buf.in_use = false; + + dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status); + } else { + vnt_int_process_data(priv); + } + + status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); + if (status) + dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); + else + priv->int_buf.in_use = true; +} + +int vnt_start_interrupt_urb(struct vnt_private *priv) +{ + int status = STATUS_FAILURE; + + if (priv->int_buf.in_use == true) + return STATUS_FAILURE; + + priv->int_buf.in_use = true; + + usb_fill_int_urb(priv->interrupt_urb, + priv->usb, + usb_rcvintpipe(priv->usb, 1), + priv->int_buf.data_buf, + MAX_INTERRUPT_SIZE, + vnt_start_interrupt_urb_complete, + priv, + priv->int_interval); + + status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); + if (status) { + dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); + priv->int_buf.in_use = false; + } + + return status; +} + +static void vnt_submit_rx_urb_complete(struct urb *urb) +{ + struct vnt_rcb *rcb = urb->context; + struct vnt_private *priv = rcb->priv; + unsigned long flags; + + switch (urb->status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + case -ETIMEDOUT: + default: + dev_dbg(&priv->usb->dev, "BULK In failed %d\n", urb->status); + break; + } + + if (urb->actual_length) { + spin_lock_irqsave(&priv->lock, flags); + + if (vnt_rx_data(priv, rcb, urb->actual_length)) { + rcb->skb = dev_alloc_skb(priv->rx_buf_sz); + if (!rcb->skb) { + dev_dbg(&priv->usb->dev, + "Failed to re-alloc rx skb\n"); + + rcb->in_use = false; + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + } else { + skb_push(rcb->skb, skb_headroom(rcb->skb)); + skb_trim(rcb->skb, 0); + } + + urb->transfer_buffer = skb_put(rcb->skb, + skb_tailroom(rcb->skb)); + + spin_unlock_irqrestore(&priv->lock, flags); + } + + if (usb_submit_urb(urb, GFP_ATOMIC)) { + dev_dbg(&priv->usb->dev, "Failed to re submit rx skb\n"); + + rcb->in_use = false; + } +} + +int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb) +{ + int status = 0; + struct urb *urb; + + urb = rcb->urb; + if (rcb->skb == NULL) { + dev_dbg(&priv->usb->dev, "rcb->skb is null\n"); + return status; + } + + usb_fill_bulk_urb(urb, + priv->usb, + usb_rcvbulkpipe(priv->usb, 2), + skb_put(rcb->skb, skb_tailroom(rcb->skb)), + MAX_TOTAL_SIZE_WITH_ALL_HEADERS, + vnt_submit_rx_urb_complete, + rcb); + + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status != 0) { + dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status); + return STATUS_FAILURE; + } + + rcb->in_use = true; + + return status; +} + +static void vnt_tx_context_complete(struct urb *urb) +{ + struct vnt_usb_send_context *context = urb->context; + struct vnt_private *priv = context->priv; + + switch (urb->status) { + case 0: + dev_dbg(&priv->usb->dev, "Write %d bytes\n", context->buf_len); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + context->in_use = false; + return; + case -ETIMEDOUT: + default: + dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status); + break; + } + + if (context->type == CONTEXT_DATA_PACKET) + ieee80211_wake_queues(priv->hw); + + if (urb->status || context->type == CONTEXT_BEACON_PACKET) { + if (context->skb) + ieee80211_free_txskb(priv->hw, context->skb); + + context->in_use = false; + } +} + +int vnt_tx_context(struct vnt_private *priv, + struct vnt_usb_send_context *context) +{ + int status; + struct urb *urb; + + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { + context->in_use = false; + return STATUS_RESOURCES; + } + + urb = context->urb; + + usb_fill_bulk_urb(urb, + priv->usb, + usb_sndbulkpipe(priv->usb, 3), + context->data, + context->buf_len, + vnt_tx_context_complete, + context); + + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status != 0) { + dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status); + + context->in_use = false; + return STATUS_FAILURE; + } + + return STATUS_PENDING; +} -- cgit 1.2.3-korg