permit multiline comments and strings in macros
[bpt/coccinelle.git] / demos / usb_submit_urb.c
1 // from usbnet.c
2
3 static int gl_interrupt_read (struct usbnet *dev)
4 {
5 struct gl_priv *priv = dev->priv_data;
6 int retval;
7
8 // issue usb interrupt read
9 if (priv && priv->irq_urb) {
10 // submit urb
11 if ((retval = usb_submit_urb (priv->irq_urb)) != 0)
12 dbg ("gl_interrupt_read: submit fail - %X...", retval);
13 else
14 dbg ("gl_interrupt_read: submit success...");
15 }
16
17 return 0;
18 }
19
20
21 static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
22 {
23 struct sk_buff *skb;
24 struct skb_data *entry;
25 int retval = 0;
26 unsigned long lockflags;
27 size_t size;
28
29 #ifdef CONFIG_USB_NET1080
30 if (dev->driver_info->flags & FLAG_FRAMING_NC)
31 size = FRAMED_SIZE (dev->net.mtu);
32 else
33 #endif
34 #ifdef CONFIG_USB_GENESYS
35 if (dev->driver_info->flags & FLAG_FRAMING_GL)
36 size = GL_RCV_BUF_SIZE;
37 else
38 #endif
39 size = (sizeof (struct ethhdr) + dev->net.mtu);
40
41 if ((skb = alloc_skb (size, flags)) == 0) {
42 dbg ("no rx skb");
43 tasklet_schedule (&dev->bh);
44 usb_free_urb (urb);
45 return;
46 }
47
48 entry = (struct skb_data *) skb->cb;
49 entry->urb = urb;
50 entry->dev = dev;
51 entry->state = rx_start;
52 entry->length = 0;
53
54 FILL_BULK_URB (urb, dev->udev,
55 usb_rcvbulkpipe (dev->udev, dev->driver_info->in),
56 skb->data, size, rx_complete, skb);
57 urb->transfer_flags |= USB_ASYNC_UNLINK;
58 #ifdef REALLY_QUEUE
59 urb->transfer_flags |= USB_QUEUE_BULK;
60 #endif
61 #if 0
62 // Idle-but-posted reads with UHCI really chew up
63 // PCI bandwidth unless FSBR is disabled
64 urb->transfer_flags |= USB_NO_FSBR;
65 #endif
66
67 spin_lock_irqsave (&dev->rxq.lock, lockflags);
68
69 if (netif_running (&dev->net)) {
70 if ((retval = usb_submit_urb (urb)) != 0) {
71 dbg ("%s rx submit, %d", dev->net.name, retval);
72 tasklet_schedule (&dev->bh);
73 } else {
74 __skb_queue_tail (&dev->rxq, skb);
75 }
76 } else {
77 dbg ("rx: stopped");
78 retval = -ENOLINK;
79 }
80 spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
81 if (retval) {
82 dev_kfree_skb_any (skb);
83 usb_free_urb (urb);
84 }
85 }
86
87
88
89 static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
90 {
91 struct usbnet *dev = (struct usbnet *) net->priv;
92 int length = skb->len;
93 int retval = NET_XMIT_SUCCESS;
94 struct urb *urb = 0;
95 struct skb_data *entry;
96 struct driver_info *info = dev->driver_info;
97 unsigned long flags;
98 #ifdef CONFIG_USB_NET1080
99 struct nc_header *header = 0;
100 struct nc_trailer *trailer = 0;
101 #endif /* CONFIG_USB_NET1080 */
102
103 flags = in_interrupt () ? GFP_ATOMIC : GFP_NOIO; /* might be used for nfs */
104
105 // some devices want funky USB-level framing, for
106 // win32 driver (usually) and/or hardware quirks
107 if (info->tx_fixup) {
108 skb = info->tx_fixup (dev, skb, flags);
109 if (!skb) {
110 dbg ("can't tx_fixup skb");
111 goto drop;
112 }
113 }
114
115 if (!(urb = usb_alloc_urb (0))) {
116 dbg ("no urb");
117 goto drop;
118 }
119
120 entry = (struct skb_data *) skb->cb;
121 entry->urb = urb;
122 entry->dev = dev;
123 entry->state = tx_start;
124 entry->length = length;
125
126 // FIXME: reorganize a bit, so that fixup() fills out NetChip
127 // framing too. (Packet ID update needs the spinlock...)
128
129 #ifdef CONFIG_USB_NET1080
130 if (info->flags & FLAG_FRAMING_NC) {
131 header = (struct nc_header *) skb_push (skb, sizeof *header);
132 header->hdr_len = cpu_to_le16 (sizeof (*header));
133 header->packet_len = cpu_to_le16 (length);
134 if (!((skb->len + sizeof *trailer) & 0x01))
135 *skb_put (skb, 1) = PAD_BYTE;
136 trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
137 } else
138 #endif /* CONFIG_USB_NET1080 */
139
140 /* don't assume the hardware handles USB_ZERO_PACKET */
141 if ((length % EP_SIZE (dev)) == 0)
142 skb->len++;
143
144 FILL_BULK_URB (urb, dev->udev,
145 usb_sndbulkpipe (dev->udev, info->out),
146 skb->data, skb->len, tx_complete, skb);
147 urb->transfer_flags |= USB_ASYNC_UNLINK;
148 #ifdef REALLY_QUEUE
149 urb->transfer_flags |= USB_QUEUE_BULK;
150 #endif
151 // FIXME urb->timeout = ... jiffies ... ;
152
153 spin_lock_irqsave (&dev->txq.lock, flags);
154
155 #ifdef CONFIG_USB_NET1080
156 if (info->flags & FLAG_FRAMING_NC) {
157 header->packet_id = cpu_to_le16 (dev->packet_id++);
158 put_unaligned (header->packet_id, &trailer->packet_id);
159 #if 0
160 devdbg (dev, "frame >tx h %d p %d id %d",
161 header->hdr_len, header->packet_len,
162 header->packet_id);
163 #endif
164 }
165 #endif /* CONFIG_USB_NET1080 */
166
167 netif_stop_queue (net);
168 if ((retval = usb_submit_urb (urb)) != 0) {
169 netif_start_queue (net);
170 dbg ("%s tx: submit urb err %d", net->name, retval);
171 } else {
172 net->trans_start = jiffies;
173 __skb_queue_tail (&dev->txq, skb);
174 if (dev->txq.qlen < TX_QLEN)
175 netif_start_queue (net);
176 }
177 spin_unlock_irqrestore (&dev->txq.lock, flags);
178
179 if (retval) {
180 devdbg (dev, "drop, code %d", retval);
181 drop:
182 retval = NET_XMIT_DROP;
183 dev->stats.tx_dropped++;
184 if (skb)
185 dev_kfree_skb_any (skb);
186 usb_free_urb (urb);
187 #ifdef VERBOSE
188 } else {
189 devdbg (dev, "> tx, len %d, type 0x%x",
190 length, skb->protocol);
191 #endif
192 }
193 return retval;
194 }