コード例 #1
0
ファイル: usb.c プロジェクト: atoulme/ruby-usb
/* USB::Interface#settings */
static VALUE
rusb_interface_settings(VALUE v)
{
  struct usb_interface *p = get_usb_interface(v);
  int i;
  VALUE altsetting = rb_ary_new2(p->num_altsetting);
  for (i = 0; i < p->num_altsetting; i++)
    rb_ary_store(altsetting, i, rusb_interface_descriptor_make(&p->altsetting[i], v));
  return altsetting;
}
コード例 #2
0
ファイル: usbnet_3_0_6.c プロジェクト: tpham3783/openwrt
netdev_tx_t gobi_usbnet_start_xmit_3_0_6 (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;
#ifdef TX_URB_MONITOR   
   unsigned char b_usb_if_num = 0;
   int iRet = -1;
#endif //#ifdef TX_URB_MONITOR

	// 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->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.
	 * 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);
		spin_unlock_irqrestore(&dev->txq.lock, flags);
		netdev_dbg(dev->net, "Delaying transmission for resumption\n");
		goto deferred;
	}
#endif

#ifdef TX_URB_MONITOR
   iRet = get_usb_interface(urb, &b_usb_if_num);
#endif //#ifdef TX_URB_MONITOR  

	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;
		__skb_queue_tail (&dev->txq, skb);
		if (dev->txq.qlen >= TX_QLEN (dev))
			netif_stop_queue (net);
	}
#ifdef TX_URB_MONITOR
   /*
    * This can be called from here or from inside the
    * case 0 in the above switch. There will be one less
    * condition to check
    */
   /*
    * Call URB_monitor() with true as the URB has been successfully 
    * submitted to the txq. 
    */
   if ((URB_monitor) && (0==iRet) && (0==retval))
   {
       URB_monitor(true, b_usb_if_num);
   }
#endif //#ifdef TX_URB_MONITOR

	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;
}
コード例 #3
0
ファイル: usbnet_3_0_6.c プロジェクト: tpham3783/openwrt
static void tx_complete (struct urb *urb)
{
   struct sk_buff		*skb = (struct sk_buff *) urb->context;
   struct skb_data		*entry = (struct skb_data *) skb->cb;
   struct usbnet		*dev = entry->dev;

#ifdef TX_URB_MONITOR
	unsigned char b_usb_if_num = 0;
    int iRet = get_usb_interface(urb, &b_usb_if_num);
#endif //#ifdef TX_URB_MONITOR

   if (urb->status == 0)
   {
      if (!(dev->driver_info->flags & FLAG_MULTI_PACKET))
         dev->net->stats.tx_packets++;
      dev->net->stats.tx_bytes += entry->length;
   }
   else
   {
      dev->net->stats.tx_errors++;
      switch (urb->status)
      {
         case -EPIPE:
            usbnet_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))
            #if (LINUX_VERSION_CODE != KERNEL_VERSION( 3,0,6 ))
               devdbg (dev, "tx throttle %d",
                            urb->status);
            #else
			         	netif_dbg(dev, link, dev->net,
				                  	  "tx throttle %d\n", urb->status);
            #endif
            }
            netif_stop_queue (dev->net);
            break;
         default:
            if (netif_msg_tx_err (dev))
            #if (LINUX_VERSION_CODE != KERNEL_VERSION( 3,0,6 ))
               devdbg (dev, "tx err %d", entry->urb->status);
            #else
			          netif_dbg(dev, tx_err, dev->net,
				                       "tx err %d\n", entry->urb->status);
            #endif
            break;
    		}
  	}

   usb_autopm_put_interface_async(dev->intf);
   urb->dev = NULL;
   entry->state = tx_done;
   defer_bh(dev, skb, &dev->txq);

#ifdef TX_URB_MONITOR
   if ((URB_monitor) && (0==iRet))
   {
       URB_monitor(false, b_usb_if_num);
   }
#endif //#ifdef TX_URB_MONITOR

}
コード例 #4
0
ファイル: usb.c プロジェクト: atoulme/ruby-usb
/* USB::Interface#num_altsetting */
static VALUE rusb_interface_num_altsetting(VALUE v) { return INT2FIX(get_usb_interface(v)->num_altsetting); }