static int bpa10x_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct bpa10x_data *data = hdev->driver_data; struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; /* Prepend skb with frame type */ *skb_push(skb, 1) = bt_cb(skb)->pkt_type; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: dr = kmalloc(sizeof(*dr), GFP_ATOMIC); if (!dr) { usb_free_urb(urb); return -ENOMEM; } dr->bRequestType = USB_TYPE_VENDOR; dr->bRequest = 0; dr->wIndex = 0; dr->wValue = 0; dr->wLength = __cpu_to_le16(skb->len); pipe = usb_sndctrlpipe(data->udev, 0x00); usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, skb->data, skb->len, bpa10x_tx_complete, skb); hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: pipe = usb_sndbulkpipe(data->udev, 0x02); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bpa10x_tx_complete, skb); hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: pipe = usb_sndbulkpipe(data->udev, 0x02); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bpa10x_tx_complete, skb); hdev->stat.sco_tx++; break; default: usb_free_urb(urb); return -EILSEQ; } usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { BT_ERR("%s urb %p submission failed", hdev->name, urb); kfree(urb->setup_packet); usb_unanchor_urb(urb); } usb_free_urb(urb); return 0; }
static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) { struct sk_buff *skb; struct skb_data *entry; int retval = 0; unsigned long lockflags; size_t size = dev->rx_urb_size; if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return -ENOMEM; } skb_reserve (skb, NET_IP_ALIGN); entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, skb->data, size, rx_complete, skb); spin_lock_irqsave (&dev->rxq.lock, lockflags); if (netif_running (dev->net) && netif_device_present (dev->net) && !test_bit (EVENT_RX_HALT, &dev->flags) && !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) { switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { case -EPIPE: usbnet_defer_kevent (dev, EVENT_RX_HALT); break; case -ENOMEM: usbnet_defer_kevent (dev, EVENT_RX_MEMORY); break; case -ENODEV: netif_dbg(dev, ifdown, dev->net, "device gone\n"); netif_device_detach (dev->net); break; case -EHOSTUNREACH: retval = -ENOLINK; break; default: netif_dbg(dev, rx_err, dev->net, "rx submit, %d\n", retval); tasklet_schedule (&dev->bh); break; case 0: __usbnet_queue_skb(&dev->rxq, skb, rx_start); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); retval = -ENOLINK; } spin_unlock_irqrestore (&dev->rxq.lock, lockflags); if (retval) { dev_kfree_skb_any (skb); usb_free_urb (urb); } return retval; }
static int btusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; dr = kmalloc(sizeof(*dr), GFP_ATOMIC); if (!dr) { usb_free_urb(urb); return -ENOMEM; } dr->bRequestType = data->cmdreq_type; dr->bRequest = 0; dr->wIndex = 0; dr->wValue = 0; dr->wLength = __cpu_to_le16(skb->len); pipe = usb_sndctrlpipe(data->udev, 0x00); usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: if (!data->bulk_tx_ep) return -ENODEV; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) return -ENODEV; urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_isoc_tx_complete, skb, data->isoc_tx_ep->bInterval); urb->transfer_flags = URB_ISO_ASAP; __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); hdev->stat.sco_tx++; goto skip_waking; default: return -EILSEQ; } err = inc_tx(data); if (err) { usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); err = 0; goto done; } skip_waking: usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); kfree(urb->setup_packet); usb_unanchor_urb(urb); } else { usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; }
/* * callback for bulk IN urb */ static void ems_usb_read_bulk_callback(struct urb *urb) { struct ems_usb *dev = urb->context; struct net_device *netdev; int retval; netdev = dev->netdev; if (!netif_device_present(netdev)) return; switch (urb->status) { case 0: /* success */ break; case -ENOENT: return; default: netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); goto resubmit_urb; } if (urb->actual_length > CPC_HEADER_SIZE) { struct ems_cpc_msg *msg; u8 *ibuf = urb->transfer_buffer; u8 msg_count, again, start; msg_count = ibuf[0] & ~0x80; again = ibuf[0] & 0x80; start = CPC_HEADER_SIZE; while (msg_count) { msg = (struct ems_cpc_msg *)&ibuf[start]; switch (msg->type) { case CPC_MSG_TYPE_CAN_STATE: /* Process CAN state changes */ ems_usb_rx_err(dev, msg); break; case CPC_MSG_TYPE_CAN_FRAME: case CPC_MSG_TYPE_EXT_CAN_FRAME: case CPC_MSG_TYPE_RTR_FRAME: case CPC_MSG_TYPE_EXT_RTR_FRAME: ems_usb_rx_can_msg(dev, msg); break; case CPC_MSG_TYPE_CAN_FRAME_ERROR: /* Process errorframe */ ems_usb_rx_err(dev, msg); break; case CPC_MSG_TYPE_OVERRUN: /* Message lost while receiving */ ems_usb_rx_err(dev, msg); break; } start += CPC_MSG_HEADER_LEN + msg->length; msg_count--; if (start > urb->transfer_buffer_length) { netdev_err(netdev, "format error\n"); break; } } } resubmit_urb: usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), urb->transfer_buffer, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval == -ENODEV) netif_device_detach(netdev); else if (retval) netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", retval); }
static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct ems_usb *dev = netdev_priv(netdev); struct ems_tx_urb_context *context = NULL; struct net_device_stats *stats = &netdev->stats; struct can_frame *cf = (struct can_frame *)skb->data; struct ems_cpc_msg *msg; struct urb *urb; u8 *buf; int i, err; size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN + sizeof(struct cpc_can_msg); if (can_dropped_invalid_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); goto nomem; } msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE]; msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK; msg->msg.can_msg.length = cf->can_dlc; if (cf->can_id & CAN_RTR_FLAG) { msg->type = cf->can_id & CAN_EFF_FLAG ? CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME; msg->length = CPC_CAN_MSG_MIN_SIZE; } else { msg->type = cf->can_id & CAN_EFF_FLAG ? CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME; for (i = 0; i < cf->can_dlc; i++) msg->msg.can_msg.msg[i] = cf->data[i]; msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; } /* Respect byte order */ msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); for (i = 0; i < MAX_TX_URBS; i++) { if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { context = &dev->tx_contexts[i]; break; } } /* * May never happen! When this happens we'd more URBs in flight as * allowed (MAX_TX_URBS). */ if (!context) { usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); netdev_warn(netdev, "couldn't find free context\n"); return NETDEV_TX_BUSY; } context->dev = dev; context->echo_index = i; context->dlc = cf->can_dlc; usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, size, ems_usb_write_bulk_callback, context); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->tx_submitted); can_put_echo_skb(skb, netdev, context->echo_index); atomic_inc(&dev->active_tx_urbs); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) { can_free_echo_skb(netdev, context->echo_index); usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); dev_kfree_skb(skb); atomic_dec(&dev->active_tx_urbs); if (err == -ENODEV) { netif_device_detach(netdev); } else { netdev_warn(netdev, "failed tx_urb %d\n", err); stats->tx_dropped++; } } else { netdev->trans_start = jiffies; /* Slow down tx path */ if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS || dev->free_slots < 5) { netif_stop_queue(netdev); } } /* * Release our reference to this URB, the USB core will eventually free * it entirely. */ usb_free_urb(urb); return NETDEV_TX_OK; nomem: dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; }
static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) { struct sk_buff *skb; struct skb_data *entry; int retval = 0; unsigned long lockflags; size_t size = dev->rx_urb_size; struct driver_info *info = dev->driver_info; u8 align; #if (AX_FORCE_BUFF_ALIGN) align = 0; #else if (!(info->flags & FLAG_HW_IP_ALIGNMENT)) align = NET_IP_ALIGN; else align = 0; #endif if ((skb = alloc_skb (size + align, flags)) == NULL) { if (netif_msg_rx_err (dev)) devdbg (dev, "no rx skb"); axusbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return; } if (align) skb_reserve (skb, NET_IP_ALIGN); entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; entry->state = rx_start; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, skb->data, size, rx_complete, skb); spin_lock_irqsave (&dev->rxq.lock, lockflags); if (netif_running (dev->net) && netif_device_present (dev->net) && !test_bit (EVENT_RX_HALT, &dev->flags)) { switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { case -EPIPE: axusbnet_defer_kevent (dev, EVENT_RX_HALT); break; case -ENOMEM: axusbnet_defer_kevent (dev, EVENT_RX_MEMORY); break; case -ENODEV: if (netif_msg_ifdown (dev)) devdbg (dev, "device gone"); netif_device_detach (dev->net); break; default: if (netif_msg_rx_err (dev)) devdbg (dev, "rx submit, %d", retval); tasklet_schedule (&dev->bh); break; case 0: __skb_queue_tail (&dev->rxq, skb); } } else { if (netif_msg_ifdown (dev)) deverr (dev, "rx: stopped"); retval = -ENOLINK; } spin_unlock_irqrestore (&dev->rxq.lock, lockflags); if (retval) { dev_kfree_skb_any (skb); usb_free_urb (urb); } }
static int usb_serial_multi_urb_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { unsigned long flags; struct urb *urb; unsigned char *buffer; int status; int towrite; int bwrite = 0; dbg("%s - port %d", __func__, port->number); if (count == 0) dbg("%s - write request of 0 bytes", __func__); while (count > 0) { towrite = (count > port->bulk_out_size) ? port->bulk_out_size : count; spin_lock_irqsave(&port->lock, flags); if (port->urbs_in_flight > port->serial->type->max_in_flight_urbs) { spin_unlock_irqrestore(&port->lock, flags); dbg("%s - write limit hit", __func__); return bwrite; } port->tx_bytes_flight += towrite; port->urbs_in_flight++; spin_unlock_irqrestore(&port->lock, flags); buffer = kmalloc(towrite, GFP_ATOMIC); if (!buffer) { dev_err(&port->dev, "%s ran out of kernel memory for urb ...\n", __func__); goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "%s - no more free urbs\n", __func__); goto error_no_urb; } /* Copy data */ memcpy(buffer, buf + bwrite, towrite); usb_serial_debug_data(debug, &port->dev, __func__, towrite, buffer); /* fill the buffer and send it */ usb_fill_bulk_urb(urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), buffer, towrite, usb_serial_generic_write_bulk_callback, port); status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, status); goto error; } /* This urb is the responsibility of the host driver now */ usb_free_urb(urb); dbg("%s write: %d", __func__, towrite); count -= towrite; bwrite += towrite; } return bwrite; error: usb_free_urb(urb); error_no_urb: kfree(buffer); error_no_buffer: spin_lock_irqsave(&port->lock, flags); port->urbs_in_flight--; port->tx_bytes_flight -= towrite; spin_unlock_irqrestore(&port->lock, flags); return bwrite; }
/* * The ES1 USB Bridge device contains 4 endpoints * 1 Control - usual USB stuff + AP -> SVC messages * 1 Interrupt IN - SVC -> AP messages * 1 Bulk IN - CPort data in * 1 Bulk OUT - CPort data out */ static int ap_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct es1_ap_dev *es1; struct greybus_host_device *hd; struct usb_device *udev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int bulk_in = 0; int bulk_out = 0; int retval = -ENOMEM; int i; int num_cports; udev = usb_get_dev(interface_to_usbdev(interface)); num_cports = apb1_get_cport_count(udev); if (num_cports < 0) { usb_put_dev(udev); dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n", num_cports); return num_cports; } hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX, num_cports); if (IS_ERR(hd)) { usb_put_dev(udev); return PTR_ERR(hd); } es1 = hd_to_es1(hd); es1->hd = hd; es1->usb_intf = interface; es1->usb_dev = udev; spin_lock_init(&es1->cport_out_urb_lock); usb_set_intfdata(interface, es1); es1->cport_to_ep = kcalloc(hd->num_cports, sizeof(*es1->cport_to_ep), GFP_KERNEL); if (!es1->cport_to_ep) { retval = -ENOMEM; goto error; } /* find all 3 of our endpoints */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_bulk_in(endpoint)) { es1->cport_in[bulk_in++].endpoint = endpoint->bEndpointAddress; } else if (usb_endpoint_is_bulk_out(endpoint)) { es1->cport_out[bulk_out++].endpoint = endpoint->bEndpointAddress; } else { dev_err(&udev->dev, "Unknown endpoint type found, address %x\n", endpoint->bEndpointAddress); } } if ((bulk_in == 0) || (bulk_out == 0)) { dev_err(&udev->dev, "Not enough endpoints found in device, aborting!\n"); goto error; } /* Allocate buffers for our cport in messages and start them up */ for (bulk_in = 0; bulk_in < NUM_BULKS; bulk_in++) { struct es1_cport_in *cport_in = &es1->cport_in[bulk_in]; for (i = 0; i < NUM_CPORT_IN_URB; ++i) { struct urb *urb; u8 *buffer; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) goto error; buffer = kmalloc(ES1_GBUF_MSG_SIZE_MAX, GFP_KERNEL); if (!buffer) goto error; usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, cport_in->endpoint), buffer, ES1_GBUF_MSG_SIZE_MAX, cport_in_callback, hd); cport_in->urb[i] = urb; cport_in->buffer[i] = buffer; retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) goto error; } } /* Allocate urbs for our CPort OUT messages */ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { struct urb *urb; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) goto error; es1->cport_out_urb[i] = urb; es1->cport_out_urb_busy[i] = false; /* just to be anal */ } apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable", (S_IWUSR | S_IRUGO), gb_debugfs_get(), es1, &apb1_log_enable_fops); return 0; error: ap_disconnect(interface); return retval; }
static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) { struct sk_buff *skb; struct skb_data *entry; usb_complete_t complete_fn; int retval = 0; unsigned long lockflags; size_t size = dev->rx_urb_size; skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return -ENOMEM; } entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; entry->length = 0; if (dev->driver_info->rx_complete) complete_fn = dev->driver_info->rx_complete; else complete_fn = rx_complete; usb_fill_bulk_urb (urb, dev->udev, dev->in, skb->data, size, complete_fn, skb); spin_lock_irqsave (&dev->rxq.lock, lockflags); if (netif_running (dev->net) && netif_device_present (dev->net) && !test_bit (EVENT_RX_HALT, &dev->flags) && !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) { switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { case -EPIPE: usbnet_defer_kevent (dev, EVENT_RX_HALT); break; case -ENOMEM: usbnet_defer_kevent (dev, EVENT_RX_MEMORY); break; case -ENODEV: netif_dbg(dev, ifdown, dev->net, "device gone\n"); netif_device_detach (dev->net); break; case -EHOSTUNREACH: retval = -ENOLINK; break; default: netif_dbg(dev, rx_err, dev->net, "rx submit, %d\n", retval); queue_work(usbnet_wq, &dev->bh_w); break; case 0: usb_mark_last_busy(dev->udev); __usbnet_queue_skb(&dev->rxq, skb, rx_start); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); retval = -ENOLINK; } spin_unlock_irqrestore (&dev->rxq.lock, lockflags); if (retval) { dev_kfree_skb_any (skb); usb_free_urb (urb); } return retval; }
u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) { _irqL irqL; int err, pipe; u32 tmpaddr=0; int alignment=0; u32 ret = _SUCCESS; PURB purb = NULL; struct recv_buf *precvbuf = (struct recv_buf *)rmem; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; _adapter *adapter = (_adapter *)pdvobj->padapter; struct recv_priv *precvpriv = &adapter->recvpriv; struct usb_device *pusbd = pdvobj->pusbdev; _func_enter_; if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); return _FAIL; } #ifdef CONFIG_PREALLOC_RECV_SKB if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) { if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue))) { precvbuf->reuse = _TRUE; } } #endif if(precvbuf !=NULL) { init_recvbuf(adapter, precvbuf); //re-assign for linux based on skb if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) { //precvbuf->pskb = alloc_skb(MAX_RECVBUF_SZ, GFP_ATOMIC);//don't use this after v2.6.25 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/[email protected]/msg17214.html precvbuf->pskb = dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); #else precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); #endif if(precvbuf->pskb == NULL) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("init_recvbuf(): alloc_skb fail!\n")); return _FAIL; } tmpaddr = (u32)precvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); precvbuf->phead = precvbuf->pskb->head; precvbuf->pdata = precvbuf->pskb->data; precvbuf->ptail = precvbuf->pskb->tail; precvbuf->pend = precvbuf->pskb->end; precvbuf->pbuf = precvbuf->pskb->data; } else//reuse skb { precvbuf->phead = precvbuf->pskb->head; precvbuf->pdata = precvbuf->pskb->data; precvbuf->ptail = precvbuf->pskb->tail; precvbuf->pend = precvbuf->pskb->end; precvbuf->pbuf = precvbuf->pskb->data; precvbuf->reuse = _FALSE; } //Useless for linux usb driver. //2010-03-10 by Thomas //_enter_critical(&precvpriv->lock, &irqL); //precvpriv->rx_pending_cnt++; //precvbuf->irp_pending = _TRUE; //_exit_critical(&precvpriv->lock, &irqL); purb = precvbuf->purb; //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pbuf, MAX_RECVBUF_SZ, usb_read_port_complete, precvbuf);//context is precvbuf err = usb_submit_urb(purb, GFP_ATOMIC); if((err) && (err != (-EPERM))) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status)); ret = _FAIL; } } else { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n")); ret = _FAIL; } _func_exit_; return ret; }
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { _irqL irqL; int i, pipe, status; u32 ret, bwritezero; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->adapter; struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem; struct usb_device *pusbd = pdvobj->pusbdev; struct pkt_attrib *pattrib = &pxmitframe->attrib; _func_enter_; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n")); if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); return _FAIL; } for(i=0; i<8; i++) { if(pxmitframe->bpending[i] == _FALSE) { _enter_critical(&pxmitpriv->lock, &irqL); pxmitpriv->txirp_cnt++; pxmitframe->bpending[i] = _TRUE; switch(pattrib->priority) { case 1: case 2: pxmitpriv->bkq_cnt++; break; case 4: case 5: pxmitpriv->viq_cnt++; break; case 6: case 7: pxmitpriv->voq_cnt++; break; case 0: case 3: default: pxmitpriv->beq_cnt++; break; } _exit_critical(&pxmitpriv->lock, &irqL); pxmitframe->sz[i] = (u16)cnt; purb = pxmitframe->pxmit_urb[i]; break; } } bwritezero = _FALSE; if(pdvobj->ishighspeed) { if(cnt> 0 && cnt%512 == 0) { //printk("ishighspeed, cnt=%d\n", cnt); bwritezero = _TRUE; } } else { if(cnt > 0 && cnt%64 == 0) { //printk("cnt=%d\n", cnt); bwritezero = _TRUE; } } //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); #ifdef CONFIG_REDUCE_USB_TX_INT //if ( (pxmitpriv->free_xmitbuf_cnt%2 == 0)) if ( pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0 ) { purb->transfer_flags &= (~URB_NO_INTERRUPT); } else { purb->transfer_flags |= URB_NO_INTERRUPT; //printk("URB_NO_INTERRUPT "); } #endif if ( bwritezero ) { cnt += 8; } usb_fill_bulk_urb(purb, pusbd, pipe, pxmitframe->mem_addr, cnt, usb_write_port_complete, pxmitframe);//context is xmit_frame status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { ret= _SUCCESS; } else { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status)); ret= _FAIL; } // Commented by Albert 2009/10/13 // We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. /* if(bwritezero == _TRUE) { usb_bulkout_zero(pintfhdl, addr); } */ _func_exit_; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n")); return ret; }
static int __devinit if_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *data_desc; struct usb_link_device *usb_ld = (struct usb_link_device *)id->driver_info; struct link_device *ld = &usb_ld->ld; struct usb_interface *data_intf; struct usb_device *usbdev = interface_to_usbdev(intf); struct device *dev, *ehci_dev, *root_hub; struct if_usb_devdata *pipe; struct urb *urb; int i; int j; int dev_id; int err; /* To detect usb device order probed */ dev_id = intf->cur_altsetting->desc.bInterfaceNumber; if (dev_id >= IF_USB_DEVNUM_MAX) { dev_err(&intf->dev, "Device id %d cannot support\n", dev_id); return -EINVAL; } if (!usb_ld) { dev_err(&intf->dev, "if_usb device doesn't be allocated\n"); err = ENOMEM; goto out; } mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n", dev_id, id, usb_ld); usb_ld->usbdev = usbdev; usb_get_dev(usbdev); for (i = 0; i < IF_USB_DEVNUM_MAX; i++) { data_intf = usb_ifnum_to_if(usbdev, i); /* remap endpoint of RAW to no.1 for LTE modem */ if (i == 0) pipe = &usb_ld->devdata[1]; else if (i == 1) pipe = &usb_ld->devdata[0]; else pipe = &usb_ld->devdata[i]; pipe->disconnected = 0; pipe->data_intf = data_intf; data_desc = data_intf->cur_altsetting; /* Endpoints */ if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } else { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } if (i == 0) { dev_info(&usbdev->dev, "USB IF USB device found\n"); } else { err = usb_driver_claim_interface(&if_usb_driver, data_intf, usb_ld); if (err < 0) { mif_err("failed to cliam usb interface\n"); goto out; } } usb_set_intfdata(data_intf, usb_ld); usb_ld->dev_count++; pm_suspend_ignore_children(&data_intf->dev, true); for (j = 0; j < URB_COUNT; j++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { mif_err("alloc urb fail\n"); err = -ENOMEM; goto out2; } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = usb_alloc_coherent(usbdev, pipe->rx_buf_size, GFP_KERNEL, &urb->transfer_dma); if (!urb->transfer_buffer) { mif_err( "Failed to allocate transfer buffer\n"); usb_free_urb(urb); err = -ENOMEM; goto out2; } usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe, urb->transfer_buffer, pipe->rx_buf_size, usb_rx_complete, pipe); usb_anchor_urb(urb, &pipe->urbs); } } /* temporary call reset_resume */ atomic_set(&usb_ld->suspend_count, 1); if_usb_reset_resume(data_intf); atomic_set(&usb_ld->suspend_count, 0); SET_HOST_ACTIVE(usb_ld->pdata, 1); usb_ld->host_wake_timeout_flag = 0; if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) { struct link_pm_data *pm_data = usb_ld->link_pm_data; int delay = pm_data->autosuspend_delay_ms ?: DEFAULT_AUTOSUSPEND_DELAY_MS; pm_runtime_set_autosuspend_delay(&usbdev->dev, delay); dev = &usbdev->dev; if (dev->parent) { dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n"); usb_enable_autosuspend(usb_ld->usbdev); /* s5p-ehci runtime pm allow - usb phy suspend mode */ root_hub = &usbdev->bus->root_hub->dev; ehci_dev = root_hub->parent; mif_debug("ehci device = %s, %s\n", dev_driver_string(ehci_dev), dev_name(ehci_dev)); pm_runtime_allow(ehci_dev); if (!pm_data->autosuspend) pm_runtime_forbid(dev); if (has_hub(usb_ld)) link_pm_preactive(pm_data); pm_data->root_hub = root_hub; } usb_ld->flow_suspend = 0; /* Queue work if skbs were pending before a disconnect/probe */ if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0); usb_ld->if_usb_connected = 1; /*USB3503*/ mif_debug("hub active complete\n"); usb_change_modem_state(usb_ld, STATE_ONLINE); } else {
static int usb_tx_urb_with_skb(struct usb_link_device *usb_ld, struct sk_buff *skb, struct if_usb_devdata *pipe_data) { int ret, cnt = 0; struct urb *urb; struct usb_device *usbdev = usb_ld->usbdev; unsigned long flags; if (!usbdev || (usbdev->state == USB_STATE_NOTATTACHED) || usb_ld->host_wake_timeout_flag) return -ENODEV; pm_runtime_get_noresume(&usbdev->dev); if (usbdev->dev.power.runtime_status == RPM_SUSPENDED || usbdev->dev.power.runtime_status == RPM_SUSPENDING) { usb_ld->resume_status = AP_INITIATED_RESUME; SET_SLAVE_WAKEUP(usb_ld->pdata, 1); while (!wait_event_interruptible_timeout(usb_ld->l2_wait, usbdev->dev.power.runtime_status == RPM_ACTIVE || pipe_data->disconnected, HOST_WAKEUP_TIMEOUT_JIFFIES)) { if (cnt == MAX_RETRY) { mif_err("host wakeup timeout !!\n"); SET_SLAVE_WAKEUP(usb_ld->pdata, 0); pm_runtime_put_autosuspend(&usbdev->dev); schedule_work(&usb_ld->disconnect_work); usb_ld->host_wake_timeout_flag = 1; return -1; } mif_err("host wakeup timeout ! retry..\n"); SET_SLAVE_WAKEUP(usb_ld->pdata, 0); udelay(100); SET_SLAVE_WAKEUP(usb_ld->pdata, 1); cnt++; } if (pipe_data->disconnected) { SET_SLAVE_WAKEUP(usb_ld->pdata, 0); pm_runtime_put_autosuspend(&usbdev->dev); return -ENODEV; } mif_debug("wait_q done (runtime_status=%d)\n", usbdev->dev.power.runtime_status); } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { mif_err("alloc urb error\n"); if (pm_runtime_put_autosuspend(&usbdev->dev) < 0) mif_debug("pm_runtime_put_autosuspend fail\n"); return -ENOMEM; } urb->transfer_flags = URB_ZERO_PACKET; usb_fill_bulk_urb(urb, usbdev, pipe_data->tx_pipe, skb->data, skb->len, usb_tx_complete, (void *)skb); spin_lock_irqsave(&usb_ld->lock, flags); if (atomic_read(&usb_ld->suspend_count)) { /* transmission will be done in resume */ usb_anchor_urb(urb, &usb_ld->deferred); usb_put_urb(urb); mif_debug("anchor urb (0x%p)\n", urb); spin_unlock_irqrestore(&usb_ld->lock, flags); return 0; } spin_unlock_irqrestore(&usb_ld->lock, flags); ret = usb_submit_urb(urb, GFP_KERNEL); if (ret < 0) { mif_err("usb_submit_urb with ret(%d)\n", ret); if (pm_runtime_put_autosuspend(&usbdev->dev) < 0) mif_debug("pm_runtime_put_autosuspend fail\n"); } return ret; }
u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) { int err; unsigned int pipe; u32 ret = _FAIL; PURB purb = NULL; struct recv_buf *precvbuf = (struct recv_buf *)rmem; _adapter *adapter = pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct recv_priv *precvpriv = &adapter->recvpriv; struct usb_device *pusbd = pdvobj->pusbdev; _func_enter_; if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( RTW_CANNOT_RX ) || precvbuf == NULL!!!\n")); goto exit; } usb_init_recvbuf(adapter, precvbuf); if (precvbuf->pskb == NULL) { SIZE_PTR tmpaddr = 0; SIZE_PTR alignment = 0; if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue))) goto recv_buf_hook; #ifndef CONFIG_FIX_NR_BULKIN_BUFFER precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); #endif if (precvbuf->pskb == NULL) { if (0) DBG_871X("usb_read_port() enqueue precvbuf=%p \n", precvbuf); /* enqueue precvbuf and wait for free skb */ rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue); goto exit; } tmpaddr = (SIZE_PTR)precvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); } recv_buf_hook: precvbuf->phead = precvbuf->pskb->head; precvbuf->pdata = precvbuf->pskb->data; precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); precvbuf->pend = skb_end_pointer(precvbuf->pskb); precvbuf->pbuf = precvbuf->pskb->data; purb = precvbuf->purb; /* translate DMA FIFO addr to pipehandle */ pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pbuf, MAX_RECVBUF_SZ, usb_read_port_complete, precvbuf); err = usb_submit_urb(purb, GFP_ATOMIC); if (err && err != (-EPERM)) { DBG_871X("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n" , err, purb->status); goto exit; } ATOMIC_INC(&(precvpriv->rx_pending_cnt)); ret = _SUCCESS; exit: _func_exit_; return ret; }
static void cyberjack_write_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); int status = urb->status; dbg("%s - port %d", __func__, port->number); port->write_urb_busy = 0; if (status) { dbg("%s - nonzero write bulk status received: %d", __func__, status); return; } spin_lock(&priv->lock); /* only do something if we have more data to send */ if (priv->wrfilled) { int length, blksize, result; dbg("%s - transmitting data (frame n)", __func__); length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ? port->bulk_out_size : (priv->wrfilled - priv->wrsent); memcpy(port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent, length); priv->wrsent += length; /* set up our urb */ usb_fill_bulk_urb(port->write_urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, length, ((port->serial->type->write_bulk_callback) ? port->serial->type->write_bulk_callback : cyberjack_write_bulk_callback), port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled = 0; priv->wrsent = 0; goto exit; } dbg("%s - priv->wrsent=%d", __func__, priv->wrsent); dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled); blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; if (priv->wrsent >= priv->wrfilled || priv->wrsent >= blksize) { dbg("%s - buffer cleaned", __func__); memset(priv->wrbuf, 0, sizeof(priv->wrbuf)); priv->wrfilled = 0; priv->wrsent = 0; } } exit: spin_unlock(&priv->lock); usb_serial_port_softint(port); }
static void opticon_read_bulk_callback(struct urb *urb) { struct opticon_private *priv = urb->context; unsigned char *data = urb->transfer_buffer; struct usb_serial_port *port = priv->port; int status = urb->status; struct tty_struct *tty; int result; int data_length; unsigned long flags; dbg("%s - port %d", __func__, port->number); switch (status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __func__, status); return; default: dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); if (urb->actual_length > 2) { data_length = urb->actual_length - 2; /* * Data from the device comes with a 2 byte header: * * <0x00><0x00>data... * This is real data to be sent to the tty layer * <0x00><0x01)level * This is a CTS level change, the third byte is the CTS * value (0 for low, 1 for high). */ if ((data[0] == 0x00) && (data[1] == 0x00)) { /* real data, send it to the tty layer */ tty = tty_port_tty_get(&port->port); if (tty) { tty_insert_flip_string(tty, data + 2, data_length); tty_flip_buffer_push(tty); tty_kref_put(tty); } } else { if ((data[0] == 0x00) && (data[1] == 0x01)) { spin_lock_irqsave(&priv->lock, flags); /* CTS status information package */ if (data[2] == 0x00) priv->cts = false; else priv->cts = true; spin_unlock_irqrestore(&priv->lock, flags); } else { dev_dbg(&priv->udev->dev, "Unknown data packet received from the device:" " %2x %2x\n", data[0], data[1]); } } } else { dev_dbg(&priv->udev->dev, "Improper amount of data received from the device, " "%d bytes", urb->actual_length); } exit: spin_lock(&priv->lock); /* Continue trying to always read if we should */ if (!priv->throttled) { usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, usb_rcvbulkpipe(priv->udev, priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, opticon_read_bulk_callback, priv); result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); } else priv->actually_throttled = true; spin_unlock(&priv->lock); }
static int usbsvn_write(struct net_device *dev, struct sipc4_tx_data *tx_data) { struct usbsvn *svn = netdev_priv(dev); struct sk_buff *skb; struct usbsvn_devdata *devdata; struct urb *req; int dev_id; int err; if (!svn->usbdev) return -1; /*hold on active mode until xmit*/ usb_mark_last_busy(svn->usbdev); wake_lock_pm(svn); err = usbsvn_initiated_resume(dev); if (err < 0) { printk(KERN_ERR "%s: usbsvn_initated_resume fail\n", __func__); goto exit; } skb = tx_data->skb; dev_id = SIPC4_FORMAT(tx_data->res); devdata = &svn->devdata[dev_id]; req = usb_alloc_urb(0, GFP_ATOMIC); if (!req) { printk(KERN_ERR "%s: can't get urb\n", __func__); err = -ENOMEM; goto exit; } usb_fill_bulk_urb(req, svn->usbdev, devdata->tx_pipe, skb->data, skb->len, tx_complete, skb); if (tx_debug) { char *buf = skb->data; int i; printk(KERN_ERR "[TX] dev_id: %d, size: %d\n", dev_id, skb->len); for (i = 0; i < skb->len; i++) printk(KERN_ERR "%x ", *(buf + i)); if (skb->len) printk(KERN_ERR "\n"); } req->transfer_flags = URB_ZERO_PACKET; err = usb_submit_urb(req, GFP_ATOMIC); if (err < 0) { printk(KERN_ERR "%s:usb_submit_urb fail\n", __func__); usb_free_urb(req); goto exit; } usb_mark_last_busy(svn->usbdev); if (dev_id == SIPC4_RAW) wake_lock_timeout_data(svn); exit: return err; }
static void ushc_request(struct mmc_host *mmc, struct mmc_request *req) { struct ushc_data *ushc = mmc_priv(mmc); int ret; unsigned long flags; spin_lock_irqsave(&ushc->lock, flags); if (test_bit(DISCONNECTED, &ushc->flags)) { ret = -ENODEV; goto out; } /* Version 2 firmware doesn't support the R2 response format. */ if (req->cmd->flags & MMC_RSP_136) { ret = -EINVAL; goto out; } /* The Astoria's data FIFOs don't work with clock speeds < 5MHz so limit commands with data to 6MHz or more. */ if (req->data && ushc->clock_freq < 6000000) { ret = -EINVAL; goto out; } ushc->current_req = req; /* Start cmd with CBW. */ ushc->cbw->cmd_idx = cpu_to_le16(req->cmd->opcode); if (req->data) ushc->cbw->block_size = cpu_to_le16(req->data->blksz); else ushc->cbw->block_size = 0; ushc->cbw->arg = cpu_to_le32(req->cmd->arg); ret = usb_submit_urb(ushc->cbw_urb, GFP_ATOMIC); if (ret < 0) goto out; /* Submit data (if any). */ if (req->data) { struct mmc_data *data = req->data; int pipe; if (data->flags & MMC_DATA_READ) pipe = usb_rcvbulkpipe(ushc->usb_dev, 6); else pipe = usb_sndbulkpipe(ushc->usb_dev, 2); usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, sg_virt(data->sg), data->sg->length, data_callback, ushc); ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); if (ret < 0) goto out; } /* Submit CSW. */ ret = usb_submit_urb(ushc->csw_urb, GFP_ATOMIC); if (ret < 0) goto out; out: spin_unlock_irqrestore(&ushc->lock, flags); if (ret < 0) { usb_unlink_urb(ushc->cbw_urb); usb_unlink_urb(ushc->data_urb); req->cmd->error = ret; mmc_request_done(mmc, req); } }
static void kevent (void *data) { struct usbnet *dev = (struct usbnet *)data; #else static void kevent (struct work_struct *work) { struct usbnet *dev = container_of(work, struct usbnet, kevent); #endif int status; /* usb_clear_halt() needs a thread context */ if (test_bit (EVENT_TX_HALT, &dev->flags)) { printk ("EVENT_TX_HALT\n"); unlink_urbs (dev, &dev->txq); status = usb_clear_halt (dev->udev, dev->out); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_tx_err (dev)) deverr (dev, "can't clear tx halt, status %d", status); } else { clear_bit (EVENT_TX_HALT, &dev->flags); if (status != -ESHUTDOWN) netif_wake_queue (dev->net); } } if (test_bit (EVENT_RX_HALT, &dev->flags)) { printk ("EVENT_RX_HALT\n"); unlink_urbs (dev, &dev->rxq); status = usb_clear_halt (dev->udev, dev->in); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_rx_err (dev)) deverr (dev, "can't clear rx halt, status %d", status); } else { clear_bit (EVENT_RX_HALT, &dev->flags); tasklet_schedule (&dev->bh); } } /* tasklet could resubmit itself forever if memory is tight */ if (test_bit (EVENT_RX_MEMORY, &dev->flags)) { struct urb *urb = NULL; printk ("EVENT_RX_MEMORY\n"); if (netif_running (dev->net)) urb = usb_alloc_urb (0, GFP_KERNEL); else clear_bit (EVENT_RX_MEMORY, &dev->flags); if (urb != NULL) { clear_bit (EVENT_RX_MEMORY, &dev->flags); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) urb->transfer_flags |= URB_ASYNC_UNLINK; #endif rx_submit (dev, urb, GFP_KERNEL); tasklet_schedule (&dev->bh); } } if (test_bit (EVENT_LINK_RESET, &dev->flags)) { struct driver_info *info = dev->driver_info; int retval = 0; clear_bit (EVENT_LINK_RESET, &dev->flags); if(info->link_reset && (retval = info->link_reset(dev)) < 0) { devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", retval, dev->udev->bus->bus_name, dev->udev->devpath, info->description); } } if (dev->flags) devdbg (dev, "kevent done, flags = 0x%lx", dev->flags); } /*-------------------------------------------------------------------------*/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void tx_complete (struct urb *urb, struct pt_regs *regs) #else static void tx_complete (struct urb *urb) #endif { struct sk_buff *skb = (struct sk_buff *) urb->context; struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; if (urb->status == 0) { dev->stats.tx_packets++; dev->stats.tx_bytes += entry->length; } else { dev->stats.tx_errors++; switch (urb->status) { case -EPIPE: axusbnet_defer_kevent (dev, EVENT_TX_HALT); break; /* software-driven interface shutdown */ case -ECONNRESET: // async unlink case -ESHUTDOWN: // hardware gone break; // like rx, tx gets controller i/o faults during khubd delays // and so it uses the same throttling mechanism. case -EPROTO: case -ETIME: case -EILSEQ: if (!timer_pending (&dev->delay)) { mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); if (netif_msg_link (dev)) devdbg (dev, "tx throttle %d", urb->status); } netif_stop_queue (dev->net); break; default: if (netif_msg_tx_err (dev)) devdbg (dev, "tx err %d", entry->urb->status); break; } } urb->dev = NULL; entry->state = tx_done; defer_bh(dev, skb, &dev->txq); } /*-------------------------------------------------------------------------*/ static void axusbnet_tx_timeout (struct net_device *net) { struct usbnet *dev = netdev_priv(net); unlink_urbs (dev, &dev->txq); tasklet_schedule (&dev->bh); // FIXME: device recovery -- reset? } /*-------------------------------------------------------------------------*/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) static int #else static netdev_tx_t #endif axusbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { struct usbnet *dev = netdev_priv(net); int length; struct urb *urb = NULL; struct skb_data *entry; struct driver_info *info = dev->driver_info; unsigned long flags; int retval; // some devices want funky USB-level framing, for // win32 driver (usually) and/or hardware quirks if (info->tx_fixup) { skb = info->tx_fixup (dev, skb, GFP_ATOMIC); if (!skb) { if (netif_msg_tx_err (dev)) devdbg (dev, "can't tx_fixup skb"); goto drop; } } length = skb->len; if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { if (netif_msg_tx_err (dev)) devdbg (dev, "no urb"); goto drop; } entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; entry->state = tx_start; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, skb->data, skb->len, tx_complete, skb); /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect * the ZLP here, but ignore the one-byte packet. */ if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) { urb->transfer_buffer_length++; if (skb_tailroom(skb)) { skb->data[skb->len] = 0; __skb_put(skb, 1); } } spin_lock_irqsave (&dev->txq.lock, flags); switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { case -EPIPE: netif_stop_queue (net); axusbnet_defer_kevent (dev, EVENT_TX_HALT); break; default: if (netif_msg_tx_err (dev)) devdbg (dev, "tx: submit urb err %d", retval); break; case 0: net->trans_start = jiffies; __skb_queue_tail (&dev->txq, skb); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); } spin_unlock_irqrestore (&dev->txq.lock, flags); if (retval) { if (netif_msg_tx_err (dev)) devdbg (dev, "drop, code %d", retval); drop: dev->stats.tx_dropped++; if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); } else if (netif_msg_tx_queued (dev)) { devdbg (dev, "> tx, len %d, type 0x%x", length, skb->protocol); } return NETDEV_TX_OK; } /*-------------------------------------------------------------------------*/ // tasklet (work deferred from completions, in_irq) or timer static void axusbnet_bh (unsigned long param) { struct usbnet *dev = (struct usbnet *) param; struct sk_buff *skb; struct skb_data *entry; while ((skb = skb_dequeue (&dev->done))) { entry = (struct skb_data *) skb->cb; switch (entry->state) { case rx_done: entry->state = rx_cleanup; rx_process (dev, skb); continue; case tx_done: case rx_cleanup: usb_free_urb (entry->urb); dev_kfree_skb (skb); continue; default: devdbg (dev, "bogus skb state %d", entry->state); } } // waiting for all pending urbs to complete? if (dev->wait) { if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { wake_up (dev->wait); } // or are we maybe short a few urbs? } else if (netif_running (dev->net) && netif_device_present (dev->net) && !timer_pending (&dev->delay) && !test_bit (EVENT_RX_HALT, &dev->flags)) { int temp = dev->rxq.qlen; int qlen = RX_QLEN (dev); if (temp < qlen) { struct urb *urb; int i; // don't refill the queue all at once for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { urb = usb_alloc_urb (0, GFP_ATOMIC); if (urb != NULL) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) urb->transfer_flags |= URB_ASYNC_UNLINK; #endif rx_submit (dev, urb, GFP_ATOMIC); } } if (temp != dev->rxq.qlen && netif_msg_link (dev)) devdbg (dev, "rxqlen %d --> %d", temp, dev->rxq.qlen); if (dev->rxq.qlen < qlen) tasklet_schedule (&dev->bh); } if (dev->txq.qlen < TX_QLEN (dev)) netif_wake_queue (dev->net); } } /*------------------------------------------------------------------------- * * USB Device Driver support * *-------------------------------------------------------------------------*/ // precondition: never called in_interrupt static void axusbnet_disconnect (struct usb_interface *intf) { struct usbnet *dev; struct usb_device *xdev; struct net_device *net; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); if (!dev) return; xdev = interface_to_usbdev (intf); if (netif_msg_probe (dev)) devinfo (dev, "unregister '%s' usb-%s-%s, %s", intf->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); net = dev->net; unregister_netdev (net); /* we don't hold rtnl here ... */ flush_scheduled_work (); if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); free_netdev(net); usb_put_dev (xdev); } /*-------------------------------------------------------------------------*/ // precondition: never called in_interrupt static int axusbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; struct usb_host_interface *interface; struct driver_info *info; struct usb_device *xdev; int status; const char *name; name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; if (!info) { printk (KERN_ERR "blacklisted by %s\n", name); return -ENODEV; } xdev = interface_to_usbdev (udev); interface = udev->cur_altsetting; usb_get_dev (xdev); status = -ENOMEM; // set up our own records net = alloc_etherdev(sizeof(*dev)); if (!net) { dbg ("can't kmalloc dev"); goto out; } dev = netdev_priv(net); dev->udev = xdev; dev->intf = udev; dev->driver_info = info; dev->driver_name = name; dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFDOWN |NETIF_MSG_IFUP); skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); dev->bh.func = axusbnet_bh; dev->bh.data = (unsigned long) dev; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK (&dev->kevent, kevent, dev); #else INIT_WORK (&dev->kevent, kevent); #endif dev->delay.function = axusbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); // mutex_init (&dev->phy_mutex); dev->net = net; /* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case. */ dev->hard_mtu = net->mtu + net->hard_header_len; #if 0 // dma_supported() is deeply broken on almost all architectures // possible with some EHCI controllers if (dma_supported (&udev->dev, DMA_BIT_MASK(64))) net->features |= NETIF_F_HIGHDMA; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) net->open = axusbnet_open, net->stop = axusbnet_stop, net->hard_start_xmit = axusbnet_start_xmit, net->tx_timeout = axusbnet_tx_timeout, net->get_stats = axusbnet_get_stats; #endif net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &axusbnet_ethtool_ops; // allow device-specific bind/init procedures // NOTE net->name still not usable ... status = info->bind (dev, udev); if (status < 0) { deverr(dev, "Binding device failed: %d", status); goto out1; } else { } /* maybe the remote can't receive an Ethernet MTU */ if (net->mtu > (dev->hard_mtu - net->hard_header_len)) net->mtu = dev->hard_mtu - net->hard_header_len; status = init_status (dev, udev); if (status < 0) goto out3; if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); SET_NETDEV_DEV(net, &udev->dev); status = register_netdev (net); if (status) { deverr(dev, "net device registration failed: %d", status); goto out3; } if (netif_msg_probe (dev)) devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM", udev->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description, net->dev_addr); // ok, it's ready to go. usb_set_intfdata (udev, dev); // start as if the link is up netif_device_attach (net); return 0; out3: if (info->unbind) info->unbind (dev, udev); out1: free_netdev(net); out: usb_put_dev(xdev); return status; } /*-------------------------------------------------------------------------*/ /* * suspend the whole driver as soon as the first interface is suspended * resume only when the last interface is resumed */ static int axusbnet_suspend (struct usb_interface *intf, #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10) pm_message_t message) #else u32 message) #endif { struct usbnet *dev = usb_get_intfdata(intf); if (!dev->suspend_count++) { /* * accelerate emptying of the rx and queues, to avoid * having everything error out. */ netif_device_detach (dev->net); (void) unlink_urbs (dev, &dev->rxq); (void) unlink_urbs (dev, &dev->txq); /* * reattach so runtime management can use and * wake the device */ netif_device_attach (dev->net); } return 0; } static int axusbnet_resume (struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); if (!--dev->suspend_count) tasklet_schedule (&dev->bh); return 0; }
static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); struct mmc_host *mmc; struct ushc_data *ushc; int ret; if (intf->cur_altsetting->desc.bNumEndpoints < 1) return -ENODEV; mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); if (mmc == NULL) return -ENOMEM; ushc = mmc_priv(mmc); usb_set_intfdata(intf, ushc); ushc->usb_dev = usb_dev; ushc->mmc = mmc; spin_lock_init(&ushc->lock); ret = ushc_hw_reset(ushc); if (ret < 0) goto err; /* Read capabilities. */ ret = ushc_hw_get_caps(ushc); if (ret < 0) goto err; mmc->ops = &ushc_ops; mmc->f_min = 400000; mmc->f_max = 50000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; mmc->caps |= (ushc->caps & USHC_GET_CAPS_HIGH_SPD) ? MMC_CAP_SD_HIGHSPEED : 0; mmc->max_seg_size = 512*511; mmc->max_segs = 1; mmc->max_req_size = 512*511; mmc->max_blk_size = 512; mmc->max_blk_count = 511; ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); if (ushc->int_urb == NULL) { ret = -ENOMEM; goto err; } ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); if (ushc->int_data == NULL) { ret = -ENOMEM; goto err; } usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, usb_rcvintpipe(usb_dev, intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), ushc->int_data, sizeof(struct ushc_int_data), int_callback, ushc, intf->cur_altsetting->endpoint[0].desc.bInterval); ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); if (ushc->cbw_urb == NULL) { ret = -ENOMEM; goto err; } ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); if (ushc->cbw == NULL) { ret = -ENOMEM; goto err; } ushc->cbw->signature = USHC_CBW_SIGNATURE; usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), ushc->cbw, sizeof(struct ushc_cbw), cbw_callback, ushc); ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); if (ushc->data_urb == NULL) { ret = -ENOMEM; goto err; } ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); if (ushc->csw_urb == NULL) { ret = -ENOMEM; goto err; } ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); if (ushc->csw == NULL) { ret = -ENOMEM; goto err; } usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), ushc->csw, sizeof(struct ushc_csw), csw_callback, ushc); ret = mmc_add_host(ushc->mmc); if (ret) goto err; ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL); if (ret < 0) { mmc_remove_host(ushc->mmc); goto err; } return 0; err: ushc_clean_up(ushc); return ret; }
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_skel *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; size_t writesize = min(count, (size_t)MAX_TRANSFER); dev = file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* * limit the number of URBs in flight to stop a user from using up all * RAM */ if (!(file->f_flags & O_NONBLOCK)) { if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } } else { if (down_trylock(&dev->limit_sem)) { retval = -EAGAIN; goto exit; } } spin_lock_irq(&dev->err_lock); retval = dev->errors; if (retval < 0) { /* any error is reported once */ dev->errors = 0; /* to preserve notifications about reset */ retval = (retval == -EPIPE) ? retval : -EIO; } spin_unlock_irq(&dev->err_lock); if (retval < 0) goto error; /* create a urb, and a buffer for it, and copy the data to the urb */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { retval = -ENOMEM; goto error; } buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, writesize)) { retval = -EFAULT; goto error; } /* this lock makes sure we don't submit URBs to gone devices */ mutex_lock(&dev->io_mutex); if (!dev->interface) { /* disconnect() was called */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error; } /* initialize the urb properly */ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, skel_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->submitted); /* send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); mutex_unlock(&dev->io_mutex); if (retval) { err("%s - failed submitting write urb, error %d", __func__, retval); goto error_unanchor; } /* * release our reference to this urb, the USB core will eventually free * it entirely */ usb_free_urb(urb); return writesize; error_unanchor: usb_unanchor_urb(urb); error: if (urb) { usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma); usb_free_urb(urb); } up(&dev->limit_sem); exit: return retval; }
static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) { int pipe, status, len; u32 ret; unsigned char *pbuf; struct zero_bulkout_context *pcontext; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct usb_device *pusbd = pdvobj->pusbdev; //DBG_871X("%s\n", __func__); if (RTW_CANNOT_TX(padapter)) { return _FAIL; } pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context)); if (pcontext == NULL) { return _FAIL; } pbuf = (unsigned char *)rtw_zmalloc(sizeof(int)); purb = usb_alloc_urb(0, GFP_ATOMIC); //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); len = 0; pcontext->pbuf = pbuf; pcontext->purb = purb; pcontext->pirp = NULL; pcontext->padapter = padapter; //translate DMA FIFO addr to pipehandle //pipe = ffaddr2pipehdl(pdvobj, addr); usb_fill_bulk_urb(purb, pusbd, pipe, pbuf, len, usb_bulkout_zero_complete, pcontext);//context is pcontext status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { ret= _SUCCESS; } else { ret= _FAIL; } return _SUCCESS; }
/* * Start interface */ static int ems_usb_start(struct ems_usb *dev) { struct net_device *netdev = dev->netdev; int err, i; dev->intr_in_buffer[0] = 0; dev->free_slots = 15; /* initial size */ for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); err = -ENOMEM; break; } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); err = -ENOMEM; break; } usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), buf, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->rx_submitted); err = usb_submit_urb(urb, GFP_KERNEL); if (err) { usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); break; } /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } /* Did we submit any URBs */ if (i == 0) { netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) netdev_warn(netdev, "rx performance may be slow\n"); /* Setup and start interrupt URB */ usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 1), dev->intr_in_buffer, INTR_IN_BUFFER_SIZE, ems_usb_read_interrupt_callback, dev, 1); err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { netdev_warn(netdev, "intr URB submit failed: %d\n", err); return err; } /* CPC-USB will transfer received message to host */ err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON); if (err) goto failed; /* CPC-USB will transfer CAN state changes to host */ err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON); if (err) goto failed; /* CPC-USB will transfer bus errors to host */ err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON); if (err) goto failed; err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL); if (err) goto failed; dev->can.state = CAN_STATE_ERROR_ACTIVE; return 0; failed: netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; }
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { _irqL irqL; unsigned int pipe; int status; u32 ret = _FAIL, bwritezero = _FALSE; PURB purb = NULL; _adapter *padapter = (_adapter *)pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; struct usb_device *pusbd = pdvobj->pusbdev; struct pkt_attrib *pattrib = &pxmitframe->attrib; _func_enter_; RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n")); if (RTW_CANNOT_TX(padapter)) { #ifdef DBG_TX DBG_871X(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d\n",__FUNCTION__, __LINE__ ,padapter->bDriverStopped, padapter->bSurpriseRemoved); #endif RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved )!!!\n")); rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); goto exit; } _enter_critical(&pxmitpriv->lock, &irqL); switch(addr) { case VO_QUEUE_INX: pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: pxmitbuf->flags = HIGH_QUEUE_INX; break; default: pxmitbuf->flags = MGT_QUEUE_INX; break; } _exit_critical(&pxmitpriv->lock, &irqL); purb = pxmitbuf->pxmit_urb[0]; //translate DMA FIFO addr to pipehandle pipe = ffaddr2pipehdl(pdvobj, addr); #ifdef CONFIG_REDUCE_USB_TX_INT if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0) || (pxmitbuf->buf_tag > XMITBUF_DATA) ) { purb->transfer_flags &= (~URB_NO_INTERRUPT); } else { purb->transfer_flags |= URB_NO_INTERRUPT; //DBG_8192C("URB_NO_INTERRUPT "); } #endif usb_fill_bulk_urb(purb, pusbd, pipe, pxmitframe->buf_addr, //= pxmitbuf->pbuf cnt, usb_write_port_complete, pxmitbuf);//context is pxmitbuf #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX purb->transfer_dma = pxmitbuf->dma_transfer_addr; purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; purb->transfer_flags |= URB_ZERO_PACKET; #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX #ifdef USB_PACKET_OFFSET_SZ #if (USB_PACKET_OFFSET_SZ == 0) purb->transfer_flags |= URB_ZERO_PACKET; #endif #endif #if 0 if (bwritezero) { purb->transfer_flags |= URB_ZERO_PACKET; } #endif status = usb_submit_urb(purb, GFP_ATOMIC); if (!status) { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.last_tx_time = rtw_get_current_time(); } #endif } else { rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); DBG_871X("usb_write_port, status=%d\n", status); RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status)); switch (status) { case -ENODEV: padapter->bDriverStopped=_TRUE; break; default: break; } goto exit; } ret= _SUCCESS; // Commented by Albert 2009/10/13 // We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. /* if(bwritezero == _TRUE) { usb_bulkout_zero(pintfhdl, addr); } */ RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n")); exit: if (ret != _SUCCESS) rtw_free_xmitbuf(pxmitpriv, pxmitbuf); _func_exit_; return ret; }
netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { struct usbnet *dev = netdev_priv(net); int length; struct urb *urb = NULL; struct skb_data *entry; struct driver_info *info = dev->driver_info; unsigned long flags; int retval; // some devices want funky USB-level framing, for // win32 driver (usually) and/or hardware quirks if (info->tx_fixup) { skb = info->tx_fixup (dev, skb, GFP_ATOMIC); if (!skb) { if (netif_msg_tx_err(dev)) { netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); goto drop; } else { /* cdc_ncm collected packet; waits for more */ goto not_drop; } } } length = skb->len; if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { netif_dbg(dev, tx_err, dev->net, "no urb\n"); goto drop; } entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, skb->data, skb->len, tx_complete, skb); /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect * the ZLP here, but ignore the one-byte packet. * NOTE2: CDC NCM specification is different from CDC ECM when * handling ZLP/short packets, so cdc_ncm driver will make short * packet itself if needed. */ if (length % dev->maxpacket == 0) { if (!(info->flags & FLAG_SEND_ZLP)) { if (!(info->flags & FLAG_MULTI_PACKET)) { urb->transfer_buffer_length++; if (skb_tailroom(skb)) { skb->data[skb->len] = 0; __skb_put(skb, 1); } } } else urb->transfer_flags |= URB_ZERO_PACKET; } spin_lock_irqsave(&dev->txq.lock, flags); retval = usb_autopm_get_interface_async(dev->intf); if (retval < 0) { spin_unlock_irqrestore(&dev->txq.lock, flags); goto drop; } #ifdef CONFIG_PM /* if this triggers the device is still a sleep */ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { /* transmission will be done in resume */ usb_anchor_urb(urb, &dev->deferred); /* no use to process more packets */ netif_stop_queue(net); usb_put_urb(urb); spin_unlock_irqrestore(&dev->txq.lock, flags); netdev_dbg(dev->net, "Delaying transmission for resumption\n"); goto deferred; } #endif switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { case -EPIPE: netif_stop_queue (net); usbnet_defer_kevent (dev, EVENT_TX_HALT); usb_autopm_put_interface_async(dev->intf); break; default: usb_autopm_put_interface_async(dev->intf); netif_dbg(dev, tx_err, dev->net, "tx: submit urb err %d\n", retval); break; case 0: net->trans_start = jiffies; __usbnet_queue_skb(&dev->txq, skb, tx_start); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); } spin_unlock_irqrestore (&dev->txq.lock, flags); if (retval) { netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval); drop: dev->net->stats.tx_dropped++; not_drop: if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); } else netif_dbg(dev, tx_queued, dev->net, "> tx, len %d, type 0x%x\n", length, skb->protocol); #ifdef CONFIG_PM deferred: #endif return NETDEV_TX_OK; }
int data_bridge_write(unsigned int id, struct sk_buff *skb) { int result; int size = skb->len; int pending; struct urb *txurb; struct timestamp_info *info = (struct timestamp_info *)skb->cb; struct data_bridge *dev = __dev[id]; struct bridge *brdg; if (!dev || !dev->brdg || dev->err || !usb_get_intfdata(dev->intf)) return -ENODEV; brdg = dev->brdg; if (!brdg) return -ENODEV; dev_dbg(&dev->udev->dev, "%s: write (%d bytes)\n", __func__, skb->len); result = usb_autopm_get_interface(dev->intf); if (result < 0) { dev_err(&dev->udev->dev, "%s: resume failure\n", __func__); goto error; } txurb = usb_alloc_urb(0, GFP_KERNEL); if (!txurb) { dev_err(&dev->udev->dev, "%s: error allocating read urb\n", __func__); result = -ENOMEM; goto error; } /* store dev pointer in skb */ info->dev = dev; info->tx_queued = get_timestamp(); usb_fill_bulk_urb(txurb, dev->udev, dev->bulk_out, skb->data, skb->len, data_bridge_write_cb, skb); if (test_bit(SUSPENDED, &dev->flags)) { usb_anchor_urb(txurb, &dev->delayed); goto free_urb; } pending = atomic_inc_return(&dev->pending_txurbs); usb_anchor_urb(txurb, &dev->tx_active); if (atomic_read(&dev->pending_txurbs) % tx_urb_mult) txurb->transfer_flags |= URB_NO_INTERRUPT; result = usb_submit_urb(txurb, GFP_KERNEL); if (result < 0) { usb_unanchor_urb(txurb); atomic_dec(&dev->pending_txurbs); dev_err(&dev->udev->dev, "%s: submit URB error %d\n", __func__, result); goto free_urb; } dev->to_modem++; dev_dbg(&dev->udev->dev, "%s: pending_txurbs: %u\n", __func__, pending); /* flow control: last urb submitted but return -EBUSY */ if (fctrl_support && pending > fctrl_en_thld) { set_bit(TX_THROTTLED, &brdg->flags); dev->tx_throttled_cnt++; pr_debug_ratelimited("%s: enable flow ctrl pend txurbs:%u\n", __func__, pending); return -EBUSY; } return size; free_urb: usb_free_urb(txurb); error: dev->txurb_drp_cnt++; usb_autopm_put_interface(dev->intf); return result; }
static int redrat3_dev_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct device *dev = &intf->dev; struct usb_host_interface *uhi; struct redrat3_dev *rr3; struct usb_endpoint_descriptor *ep; struct usb_endpoint_descriptor *ep_in = NULL; struct usb_endpoint_descriptor *ep_out = NULL; u8 addr, attrs; int pipe, i; int retval = -ENOMEM; rr3_ftr(dev, "%s called\n", __func__); uhi = intf->cur_altsetting; /* find our bulk-in and bulk-out endpoints */ for (i = 0; i < uhi->desc.bNumEndpoints; ++i) { ep = &uhi->endpoint[i].desc; addr = ep->bEndpointAddress; attrs = ep->bmAttributes; if ((ep_in == NULL) && ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && ((attrs & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { rr3_dbg(dev, "found bulk-in endpoint at 0x%02x\n", ep->bEndpointAddress); /* data comes in on 0x82, 0x81 is for other data... */ if (ep->bEndpointAddress == RR3_BULK_IN_EP_ADDR) ep_in = ep; } if ((ep_out == NULL) && ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && ((attrs & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { rr3_dbg(dev, "found bulk-out endpoint at 0x%02x\n", ep->bEndpointAddress); ep_out = ep; } } if (!ep_in || !ep_out) { dev_err(dev, "Couldn't find both in and out endpoints\n"); retval = -ENODEV; goto no_endpoints; } /* allocate memory for our device state and initialize it */ rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL); if (rr3 == NULL) { dev_err(dev, "Memory allocation failure\n"); goto no_endpoints; } rr3->dev = &intf->dev; /* set up bulk-in endpoint */ rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->read_urb) { dev_err(dev, "Read urb allocation failure\n"); goto error; } rr3->ep_in = ep_in; rr3->bulk_in_buf = usb_alloc_coherent(udev, ep_in->wMaxPacketSize, GFP_ATOMIC, &rr3->dma_in); if (!rr3->bulk_in_buf) { dev_err(dev, "Read buffer allocation failure\n"); goto error; } pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, ep_in->wMaxPacketSize, (usb_complete_t)redrat3_handle_async, rr3); /* set up bulk-out endpoint*/ rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->write_urb) { dev_err(dev, "Write urb allocation failure\n"); goto error; } rr3->ep_out = ep_out; rr3->bulk_out_buf = usb_alloc_coherent(udev, ep_out->wMaxPacketSize, GFP_ATOMIC, &rr3->dma_out); if (!rr3->bulk_out_buf) { dev_err(dev, "Write buffer allocation failure\n"); goto error; } pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress); usb_fill_bulk_urb(rr3->write_urb, udev, pipe, rr3->bulk_out_buf, ep_out->wMaxPacketSize, (usb_complete_t)redrat3_write_bulk_callback, rr3); rr3->udev = udev; redrat3_reset(rr3); redrat3_get_firmware_rev(rr3); /* might be all we need to do? */ retval = redrat3_enable_detector(rr3); if (retval < 0) goto error; /* store current hardware timeout, in us, will use for kfifo resets */ rr3->hw_timeout = redrat3_get_timeout(rr3); /* default.. will get overridden by any sends with a freq defined */ rr3->carrier = 38000; rr3->rc = redrat3_init_rc_dev(rr3); if (!rr3->rc) { retval = -ENOMEM; goto error; } setup_timer(&rr3->rx_timeout, redrat3_rx_timeout, (unsigned long)rr3); /* we can register the device now, as it is ready */ usb_set_intfdata(intf, rr3); rr3_ftr(dev, "Exiting %s\n", __func__); return 0; error: redrat3_delete(rr3, rr3->udev); no_endpoints: dev_err(dev, "%s: retval = %x", __func__, retval); return retval; }
static int cyberjack_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; struct cyberjack_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result; int wrexpected; dbg("%s - port %d", __func__, port->number); if (count == 0) { dbg("%s - write request of 0 bytes", __func__); return 0; } spin_lock_bh(&port->lock); if (port->write_urb_busy) { spin_unlock_bh(&port->lock); dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; spin_unlock_bh(&port->lock); spin_lock_irqsave(&priv->lock, flags); if (count+priv->wrfilled > sizeof(priv->wrbuf)) { /* To much data for buffer. Reset buffer. */ priv->wrfilled = 0; port->write_urb_busy = 0; spin_unlock_irqrestore(&priv->lock, flags); return 0; } /* Copy data */ memcpy(priv->wrbuf + priv->wrfilled, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, priv->wrbuf + priv->wrfilled); priv->wrfilled += count; if (priv->wrfilled >= 3) { wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; dbg("%s - expected data: %d", __func__, wrexpected); } else wrexpected = sizeof(priv->wrbuf); if (priv->wrfilled >= wrexpected) { /* We have enough data to begin transmission */ int length; dbg("%s - transmitting data (frame 1)", __func__); length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected; memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length); priv->wrsent = length; /* set up our urb */ usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, length, ((serial->type->write_bulk_callback) ? serial->type->write_bulk_callback : cyberjack_write_bulk_callback), port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d", __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled = 0; priv->wrsent = 0; spin_unlock_irqrestore(&priv->lock, flags); port->write_urb_busy = 0; return 0; } dbg("%s - priv->wrsent=%d", __func__, priv->wrsent); dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled); if (priv->wrsent >= priv->wrfilled) { dbg("%s - buffer cleaned", __func__); memset(priv->wrbuf, 0, sizeof(priv->wrbuf)); priv->wrfilled = 0; priv->wrsent = 0; } } spin_unlock_irqrestore(&priv->lock, flags); return count; }
int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; int result; unsigned char *data; dbg("%s - port %d", __func__, port->number); if (count == 0) { dbg("%s - write request of 0 bytes", __func__); return 0; } /* only do something if we have a bulk out endpoint */ if (serial->num_bulk_out) { unsigned long flags; spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy) { spin_unlock_irqrestore(&port->lock, flags); dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; spin_unlock_irqrestore(&port->lock, flags); count = (count > port->bulk_out_size) ? port->bulk_out_size : count; memcpy(port->write_urb->transfer_buffer, buf, count); data = port->write_urb->transfer_buffer; usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ((serial->type->write_bulk_callback) ? serial->type->write_bulk_callback : usb_serial_generic_write_bulk_callback), port); /* send the data out the bulk port */ port->write_urb_busy = 1; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); /* don't have to grab the lock here, as we will retry if != 0 */ port->write_urb_busy = 0; } else result = count; return result; } /* no bulk out, so return 0 bytes written */ return 0; }
static void bcm203x_complete(struct urb *urb) { struct bcm203x_data *data = urb->context; struct usb_device *udev = urb->dev; int len; BT_DBG("udev %p urb %p", udev, urb); if (urb->status) { BT_ERR("URB failed with status %d", urb->status); data->state = BCM203X_ERROR; return; } switch (data->state) { case BCM203X_LOAD_MINIDRV: memcpy(data->buffer, "#", 1); usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, 1, bcm203x_complete, data); data->state = BCM203X_SELECT_MEMORY; /* use workqueue to have a small delay */ schedule_work(&data->work); break; case BCM203X_SELECT_MEMORY: usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_MEMORY; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); break; case BCM203X_CHECK_MEMORY: if (data->buffer[0] != '#') { BT_ERR("Memory select failed"); data->state = BCM203X_ERROR; break; } data->state = BCM203X_LOAD_FIRMWARE; case BCM203X_LOAD_FIRMWARE: if (data->fw_sent == data->fw_size) { usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_FIRMWARE; } else { len = min_t(uint, data->fw_size - data->fw_sent, 4096); usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->fw_data + data->fw_sent, len, bcm203x_complete, data); data->fw_sent += len; } if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); break; case BCM203X_CHECK_FIRMWARE: if (data->buffer[0] != '.') { BT_ERR("Firmware loading failed"); data->state = BCM203X_ERROR; break; } data->state = BCM203X_RESET; break; } }