/* * Copyright (c) 2014 Redpine Signals Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
*/
/** * rsi_usb_card_write() - This function writes to the USB Card. * @adapter: Pointer to the adapter structure. * @buf: Pointer to the buffer from where the data has to be taken. * @len: Length to be written. * @endpoint: Type of endpoint. * * Return: status: 0 on success, a negative error code on failure.
*/ staticint rsi_usb_card_write(struct rsi_hw *adapter,
u8 *buf,
u16 len,
u8 endpoint)
{ struct rsi_91x_usbdev *dev = adapter->rsi_dev; int status;
u8 *seg = dev->tx_buffer; int transfer; int ep = dev->bulkout_endpoint_addr[endpoint - 1];
memset(seg, 0, len + RSI_USB_TX_HEAD_ROOM);
memcpy(seg + RSI_USB_TX_HEAD_ROOM, buf, len);
len += RSI_USB_TX_HEAD_ROOM;
transfer = len;
status = usb_bulk_msg(dev->usbdev,
usb_sndbulkpipe(dev->usbdev, ep),
(void *)seg,
(int)len,
&transfer,
USB_CTRL_SET_TIMEOUT);
/** * rsi_write_multiple() - This function writes multiple bytes of information * to the USB card. * @adapter: Pointer to the adapter structure. * @endpoint: Type of endpoint. * @data: Pointer to the data that has to be written. * @count: Number of multiple bytes to be written. * * Return: 0 on success, a negative error code on failure.
*/ staticint rsi_write_multiple(struct rsi_hw *adapter,
u8 endpoint,
u8 *data,
u32 count)
{ struct rsi_91x_usbdev *dev;
if (!adapter) return -ENODEV;
if (endpoint == 0) return -EINVAL;
dev = adapter->rsi_dev; if (dev->write_fail) return -ENETDOWN;
/** * rsi_find_bulk_in_and_out_endpoints() - This function initializes the bulk * endpoints to the device. * @interface: Pointer to the USB interface structure. * @adapter: Pointer to the adapter structure. * * Return: ret_val: 0 on success, -ENOMEM on failure.
*/ staticint rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, struct rsi_hw *adapter)
{ struct rsi_91x_usbdev *dev = adapter->rsi_dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint;
__le16 buffer_size; int ii, bin_found = 0, bout_found = 0;
iface_desc = interface->cur_altsetting;
for (ii = 0; ii < iface_desc->desc.bNumEndpoints; ++ii) {
endpoint = &(iface_desc->endpoint[ii].desc);
/* rsi_usb_reg_read() - This function reads data from given register address. * @usbdev: Pointer to the usb_device structure. * @reg: Address of the register to be read. * @value: Value to be read. * @len: length of data to be read. * * Return: status: 0 on success, a negative error code on failure.
*/ staticint rsi_usb_reg_read(struct usb_device *usbdev,
u32 reg,
u16 *value,
u16 len)
{
u8 *buf; int status = -ENOMEM;
if (len > RSI_USB_CTRL_BUF_SIZE) return -EINVAL;
buf = kmalloc(RSI_USB_CTRL_BUF_SIZE, GFP_KERNEL); if (!buf) return status;
/** * rsi_usb_reg_write() - This function writes the given data into the given * register address. * @usbdev: Pointer to the usb_device structure. * @reg: Address of the register. * @value: Value to write. * @len: Length of data to be written. * * Return: status: 0 on success, a negative error code on failure.
*/ staticint rsi_usb_reg_write(struct usb_device *usbdev,
u32 reg,
u32 value,
u16 len)
{
u8 *usb_reg_buf; int status = -ENOMEM;
if (len > RSI_USB_CTRL_BUF_SIZE) return -EINVAL;
usb_reg_buf = kmalloc(RSI_USB_CTRL_BUF_SIZE, GFP_KERNEL); if (!usb_reg_buf) return status;
/** * rsi_rx_done_handler() - This function is called when a packet is received * from USB stack. This is callback to receive done. * @urb: Received URB. * * Return: None.
*/ staticvoid rsi_rx_done_handler(struct urb *urb)
{ struct rx_usb_ctrl_block *rx_cb = urb->context; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data; int status = -EINVAL;
if (!rx_cb->rx_skb) return;
if (urb->status) {
dev_kfree_skb(rx_cb->rx_skb);
rx_cb->rx_skb = NULL; return;
}
/** * rsi_rx_urb_submit() - This function submits the given URB to the USB stack. * @adapter: Pointer to the adapter structure. * @ep_num: Endpoint number. * @mem_flags: The type of memory to allocate. * * Return: 0 on success, a negative error code on failure.
*/ staticint rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags)
{ struct rsi_91x_usbdev *dev = adapter->rsi_dev; struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; struct urb *urb = rx_cb->rx_urb; int status; struct sk_buff *skb;
u8 dword_align_bytes = 0;
/** * rsi_usb_write_register_multiple() - This function writes multiple bytes of * information to multiple registers. * @adapter: Pointer to the adapter structure. * @addr: Address of the register. * @data: Pointer to the data that has to be written. * @count: Number of multiple bytes to be written on to the registers. * * Return: status: 0 on success, a negative error code on failure.
*/ staticint rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr,
u8 *data, u16 count)
{ struct rsi_91x_usbdev *dev = adapter->rsi_dev;
u8 *buf;
u16 transfer; int status = 0;
buf = kzalloc(RSI_USB_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM;
while (count) {
transfer = min_t(u16, count, RSI_USB_BUF_SIZE);
memcpy(buf, data, transfer);
status = usb_control_msg(dev->usbdev,
usb_sndctrlpipe(dev->usbdev, 0),
USB_VENDOR_REGISTER_WRITE,
RSI_USB_REQ_OUT,
((addr & 0xffff0000) >> 16),
(addr & 0xffff),
(void *)buf,
transfer,
USB_CTRL_SET_TIMEOUT); if (status < 0) {
rsi_dbg(ERR_ZONE, "Reg write failed with error code :%d\n",
status);
kfree(buf); return status;
}
count -= transfer;
data += transfer;
addr += transfer;
}
kfree(buf); return 0;
}
/** *rsi_usb_host_intf_write_pkt() - This function writes the packet to the * USB card. * @adapter: Pointer to the adapter structure. * @pkt: Pointer to the data to be written on to the card. * @len: Length of the data to be written on to the card. * * Return: 0 on success, a negative error code on failure.
*/ staticint rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u8 *pkt,
u32 len)
{
u32 queueno = ((pkt[1] >> 4) & 0x7);
u8 endpoint;
err:
usb_free_urb(dev->rx_cb[0].rx_urb); if (adapter->priv->coex_mode > 1)
usb_free_urb(dev->rx_cb[1].rx_urb);
return -1;
}
/** * rsi_init_usb_interface() - This function initializes the usb interface. * @adapter: Pointer to the adapter structure. * @pfunction: Pointer to USB interface structure. * * Return: 0 on success, a negative error code on failure.
*/ staticint rsi_init_usb_interface(struct rsi_hw *adapter, struct usb_interface *pfunction)
{ struct rsi_91x_usbdev *rsi_dev; int status;
rsi_dev = kzalloc(sizeof(*rsi_dev), GFP_KERNEL); if (!rsi_dev) return -ENOMEM;
#ifdef CONFIG_RSI_DEBUGFS /* In USB, one less than the MAX_DEBUGFS_ENTRIES entries is required */
adapter->num_debugfs_entries = (MAX_DEBUGFS_ENTRIES - 1); #endif
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); return 0;
/** * rsi_probe() - This function is called by kernel when the driver provided * Vendor and device IDs are matched. All the initialization * work is done here. * @pfunction: Pointer to the USB interface structure. * @id: Pointer to the usb_device_id structure. * * Return: 0 on success, a negative error code on failure.
*/ staticint rsi_probe(struct usb_interface *pfunction, conststruct usb_device_id *id)
{ struct rsi_hw *adapter; struct rsi_91x_usbdev *dev;
u16 fw_status; int status;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
adapter = rsi_91x_init(dev_oper_mode); if (!adapter) {
rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
__func__); return -ENOMEM;
}
adapter->rsi_host_intf = RSI_HOST_INTF_USB;
status = rsi_init_usb_interface(adapter, pfunction); if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
__func__); goto err;
}
rsi_dbg(ERR_ZONE, "%s: Initialized os intf ops\n", __func__);
/** * rsi_disconnect() - This function performs the reverse of the probe function, * it deinitialize the driver structure. * @pfunction: Pointer to the USB interface structure. * * Return: None.
*/ staticvoid rsi_disconnect(struct usb_interface *pfunction)
{ struct rsi_hw *adapter = usb_get_intfdata(pfunction);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.