aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/net/gl620a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/net/gl620a.c')
-rw-r--r--drivers/usb/net/gl620a.c180
1 files changed, 12 insertions, 168 deletions
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index a3242be21959..31e5fe363fdc 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -70,184 +70,29 @@
70 (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) 70 (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
71 71
72struct gl_packet { 72struct gl_packet {
73 u32 packet_length; 73 __le32 packet_length;
74 char packet_data [1]; 74 char packet_data [1];
75}; 75};
76 76
77struct gl_header { 77struct gl_header {
78 u32 packet_count; 78 __le32 packet_count;
79 struct gl_packet packets; 79 struct gl_packet packets;
80}; 80};
81 81
82#ifdef GENELINK_ACK
83
84// FIXME: this code is incomplete, not debugged; it doesn't
85// handle interrupts correctly; it should use the generic
86// status IRQ code (which didn't exist back in 2001).
87
88struct gl_priv {
89 struct urb *irq_urb;
90 char irq_buf [INTERRUPT_BUFSIZE];
91};
92
93static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
94{
95 int retval;
96
97 retval = usb_control_msg(dev->udev,
98 usb_sndctrlpipe(dev->udev, 0),
99 request,
100 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
101 value,
102 0, // index
103 0, // data buffer
104 0, // size
105 USB_CTRL_SET_TIMEOUT);
106 return retval;
107}
108
109static void gl_interrupt_complete(struct urb *urb)
110{
111 int status = urb->status;
112
113 switch (status) {
114 case 0:
115 /* success */
116 break;
117 case -ECONNRESET:
118 case -ENOENT:
119 case -ESHUTDOWN:
120 /* this urb is terminated, clean up */
121 dbg("%s - urb shutting down with status: %d",
122 __FUNCTION__, status);
123 return;
124 default:
125 dbg("%s - nonzero urb status received: %d",
126 __FUNCTION__, urb->status);
127 }
128
129 status = usb_submit_urb(urb, GFP_ATOMIC);
130 if (status)
131 err("%s - usb_submit_urb failed with result %d",
132 __FUNCTION__, status);
133}
134
135static int gl_interrupt_read(struct usbnet *dev)
136{
137 struct gl_priv *priv = dev->priv_data;
138 int retval;
139
140 // issue usb interrupt read
141 if (priv && priv->irq_urb) {
142 // submit urb
143 if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0)
144 dbg("gl_interrupt_read: submit fail - %X...", retval);
145 else
146 dbg("gl_interrupt_read: submit success...");
147 }
148
149 return 0;
150}
151
152// check whether another side is connected
153static int genelink_check_connect(struct usbnet *dev)
154{
155 int retval;
156
157 dbg("genelink_check_connect...");
158
159 // detect whether another side is connected
160 if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
161 dbg("%s: genelink_check_connect write fail - %X",
162 dev->net->name, retval);
163 return retval;
164 }
165
166 // usb interrupt read to ack another side
167 if ((retval = gl_interrupt_read(dev)) != 0) {
168 dbg("%s: genelink_check_connect read fail - %X",
169 dev->net->name, retval);
170 return retval;
171 }
172
173 dbg("%s: genelink_check_connect read success", dev->net->name);
174 return 0;
175}
176
177// allocate and initialize the private data for genelink
178static int genelink_init(struct usbnet *dev)
179{
180 struct gl_priv *priv;
181
182 // allocate the private data structure
183 if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) {
184 dbg("%s: cannot allocate private data per device",
185 dev->net->name);
186 return -ENOMEM;
187 }
188
189 // allocate irq urb
190 if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) {
191 dbg("%s: cannot allocate private irq urb per device",
192 dev->net->name);
193 kfree(priv);
194 return -ENOMEM;
195 }
196
197 // fill irq urb
198 usb_fill_int_urb(priv->irq_urb, dev->udev,
199 usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE),
200 priv->irq_buf, INTERRUPT_BUFSIZE,
201 gl_interrupt_complete, 0,
202 GENELINK_INTERRUPT_INTERVAL);
203
204 // set private data pointer
205 dev->priv_data = priv;
206
207 return 0;
208}
209
210// release the private data
211static int genelink_free(struct usbnet *dev)
212{
213 struct gl_priv *priv = dev->priv_data;
214
215 if (!priv)
216 return 0;
217
218// FIXME: can't cancel here; it's synchronous, and
219// should have happened earlier in any case (interrupt
220// handling needs to be generic)
221
222 // cancel irq urb first
223 usb_kill_urb(priv->irq_urb);
224
225 // free irq urb
226 usb_free_urb(priv->irq_urb);
227
228 // free the private data structure
229 kfree(priv);
230
231 return 0;
232}
233
234#endif
235
236static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 82static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
237{ 83{
238 struct gl_header *header; 84 struct gl_header *header;
239 struct gl_packet *packet; 85 struct gl_packet *packet;
240 struct sk_buff *gl_skb; 86 struct sk_buff *gl_skb;
241 u32 size; 87 u32 size;
88 u32 count;
242 89
243 header = (struct gl_header *) skb->data; 90 header = (struct gl_header *) skb->data;
244 91
245 // get the packet count of the received skb 92 // get the packet count of the received skb
246 le32_to_cpus(&header->packet_count); 93 count = le32_to_cpu(header->packet_count);
247 if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS) 94 if (count > GL_MAX_TRANSMIT_PACKETS) {
248 || (header->packet_count < 0)) { 95 dbg("genelink: invalid received packet count %u", count);
249 dbg("genelink: invalid received packet count %d",
250 header->packet_count);
251 return 0; 96 return 0;
252 } 97 }
253 98
@@ -257,7 +102,7 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
257 // decrement the length for the packet count size 4 bytes 102 // decrement the length for the packet count size 4 bytes
258 skb_pull(skb, 4); 103 skb_pull(skb, 4);
259 104
260 while (header->packet_count > 1) { 105 while (count > 1) {
261 // get the packet length 106 // get the packet length
262 size = le32_to_cpu(packet->packet_length); 107 size = le32_to_cpu(packet->packet_length);
263 108
@@ -278,9 +123,8 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
278 } 123 }
279 124
280 // advance to the next packet 125 // advance to the next packet
281 packet = (struct gl_packet *) 126 packet = (struct gl_packet *)&packet->packet_data[size];
282 &packet->packet_data [size]; 127 count--;
283 header->packet_count--;
284 128
285 // shift the data pointer to the next gl_packet 129 // shift the data pointer to the next gl_packet
286 skb_pull(skb, size + 4); 130 skb_pull(skb, size + 4);
@@ -303,8 +147,8 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
303 int length = skb->len; 147 int length = skb->len;
304 int headroom = skb_headroom(skb); 148 int headroom = skb_headroom(skb);
305 int tailroom = skb_tailroom(skb); 149 int tailroom = skb_tailroom(skb);
306 u32 *packet_count; 150 __le32 *packet_count;
307 u32 *packet_len; 151 __le32 *packet_len;
308 152
309 // FIXME: magic numbers, bleech 153 // FIXME: magic numbers, bleech
310 padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; 154 padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
@@ -326,7 +170,7 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
326 } 170 }
327 171
328 // attach the packet count to the header 172 // attach the packet count to the header
329 packet_count = (u32 *) skb_push(skb, (4 + 4*1)); 173 packet_count = (__le32 *) skb_push(skb, (4 + 4*1));
330 packet_len = packet_count + 1; 174 packet_len = packet_count + 1;
331 175
332 *packet_count = cpu_to_le32(1); 176 *packet_count = cpu_to_le32(1);