~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/usbip/stub_tx.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * USA.
18
18
 */
19
19
 
20
 
#include <linux/slab.h>
 
20
#include <linux/kthread.h>
 
21
#include <linux/socket.h>
21
22
 
22
23
#include "usbip_common.h"
23
24
#include "stub.h"
24
25
 
25
 
 
26
26
static void stub_free_priv_and_urb(struct stub_priv *priv)
27
27
{
28
28
        struct urb *urb = priv->urb;
70
70
 
71
71
        usbip_dbg_stub_tx("complete! status %d\n", urb->status);
72
72
 
73
 
 
74
73
        switch (urb->status) {
75
74
        case 0:
76
75
                /* OK */
77
76
                break;
78
77
        case -ENOENT:
79
 
                usbip_uinfo("stopped by a call of usb_kill_urb() because of"
80
 
                                        "cleaning up a virtual connection\n");
 
78
                dev_info(&urb->dev->dev, "stopped by a call to usb_kill_urb() "
 
79
                         "because of cleaning up a virtual connection\n");
81
80
                return;
82
81
        case -ECONNRESET:
83
 
                usbip_uinfo("unlinked by a call of usb_unlink_urb()\n");
 
82
                dev_info(&urb->dev->dev, "unlinked by a call to "
 
83
                         "usb_unlink_urb()\n");
84
84
                break;
85
85
        case -EPIPE:
86
 
                usbip_uinfo("endpoint %d is stalled\n",
87
 
                                                usb_pipeendpoint(urb->pipe));
 
86
                dev_info(&urb->dev->dev, "endpoint %d is stalled\n",
 
87
                         usb_pipeendpoint(urb->pipe));
88
88
                break;
89
89
        case -ESHUTDOWN:
90
 
                usbip_uinfo("device removed?\n");
 
90
                dev_info(&urb->dev->dev, "device removed?\n");
91
91
                break;
92
92
        default:
93
 
                usbip_uinfo("urb completion with non-zero status %d\n",
94
 
                                                        urb->status);
 
93
                dev_info(&urb->dev->dev, "urb completion with non-zero status "
 
94
                         "%d\n", urb->status);
 
95
                break;
95
96
        }
96
97
 
97
98
        /* link a urb to the queue of tx. */
103
104
        } else
104
105
                list_move_tail(&priv->list, &sdev->priv_tx);
105
106
 
106
 
 
107
107
        spin_unlock_irqrestore(&sdev->priv_lock, flags);
108
108
 
109
109
        /* wake up tx_thread */
110
110
        wake_up(&sdev->tx_waitq);
111
111
}
112
112
 
113
 
 
114
 
/*-------------------------------------------------------------------------*/
115
 
/* fill PDU */
116
 
 
117
113
static inline void setup_base_pdu(struct usbip_header_basic *base,
118
 
                __u32 command, __u32 seqnum)
 
114
                                  __u32 command, __u32 seqnum)
119
115
{
120
116
        base->command = command;
121
117
        base->seqnum  = seqnum;
122
118
        base->devid   = 0;
123
119
        base->ep      = 0;
124
 
        base->direction   = 0;
 
120
        base->direction = 0;
125
121
}
126
122
 
127
123
static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
129
125
        struct stub_priv *priv = (struct stub_priv *) urb->context;
130
126
 
131
127
        setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
132
 
 
133
128
        usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
134
129
}
135
130
 
136
131
static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
137
 
                struct stub_unlink *unlink)
 
132
                                 struct stub_unlink *unlink)
138
133
{
139
134
        setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
140
 
 
141
135
        rpdu->u.ret_unlink.status = unlink->status;
142
136
}
143
137
 
144
 
 
145
 
/*-------------------------------------------------------------------------*/
146
 
/* send RET_SUBMIT */
147
 
 
148
138
static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
149
139
{
150
140
        unsigned long flags;
202
192
                /* 1. setup usbip_header */
203
193
                setup_ret_submit_pdu(&pdu_header, urb);
204
194
                usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n",
205
 
                                                pdu_header.base.seqnum, urb);
 
195
                                  pdu_header.base.seqnum, urb);
206
196
                /*usbip_dump_header(pdu_header);*/
207
197
                usbip_header_correct_endian(&pdu_header, 1);
208
198
 
213
203
 
214
204
                /* 2. setup transfer buffer */
215
205
                if (usb_pipein(urb->pipe) &&
216
 
                                usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS &&
217
 
                                        urb->actual_length > 0) {
 
206
                    usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS &&
 
207
                    urb->actual_length > 0) {
218
208
                        iov[iovnum].iov_base = urb->transfer_buffer;
219
209
                        iov[iovnum].iov_len  = urb->actual_length;
220
210
                        iovnum++;
221
211
                        txsize += urb->actual_length;
222
212
                } else if (usb_pipein(urb->pipe) &&
223
 
                                usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 
213
                           usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
224
214
                        /*
225
215
                         * For isochronous packets: actual length is the sum of
226
216
                         * the actual length of the individual, packets, but as
231
221
 
232
222
                        int i;
233
223
                        for (i = 0; i < urb->number_of_packets; i++) {
234
 
                                iov[iovnum].iov_base = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
235
 
                                iov[iovnum].iov_len = urb->iso_frame_desc[i].actual_length;
 
224
                                iov[iovnum].iov_base = urb->transfer_buffer +
 
225
                                        urb->iso_frame_desc[i].offset;
 
226
                                iov[iovnum].iov_len =
 
227
                                        urb->iso_frame_desc[i].actual_length;
236
228
                                iovnum++;
237
229
                                txsize += urb->iso_frame_desc[i].actual_length;
238
230
                        }
239
231
 
240
232
                        if (txsize != sizeof(pdu_header) + urb->actual_length) {
241
233
                                dev_err(&sdev->interface->dev,
242
 
                                        "actual length of urb (%d) does not match iso packet sizes (%d)\n",
243
 
                                        urb->actual_length, txsize-sizeof(pdu_header));
 
234
                                        "actual length of urb %d does not "
 
235
                                        "match iso packet sizes %lu\n",
 
236
                                        urb->actual_length,
 
237
                                        txsize-sizeof(pdu_header));
244
238
                                kfree(iov);
245
 
                                usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
 
239
                                usbip_event_add(&sdev->ud,
 
240
                                                SDEV_EVENT_ERROR_TCP);
246
241
                           return -1;
247
242
                        }
248
243
                }
284
279
        }
285
280
 
286
281
        spin_lock_irqsave(&sdev->priv_lock, flags);
287
 
 
288
282
        list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
289
283
                stub_free_priv_and_urb(priv);
290
284
        }
291
 
 
292
285
        spin_unlock_irqrestore(&sdev->priv_lock, flags);
293
286
 
294
287
        return total_size;
295
288
}
296
289
 
297
 
 
298
 
/*-------------------------------------------------------------------------*/
299
 
/* send RET_UNLINK */
300
 
 
301
290
static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
302
291
{
303
292
        unsigned long flags;
316
305
        return NULL;
317
306
}
318
307
 
319
 
 
320
308
static int stub_send_ret_unlink(struct stub_device *sdev)
321
309
{
322
310
        unsigned long flags;
357
345
                        return -1;
358
346
                }
359
347
 
360
 
 
361
348
                usbip_dbg_stub_tx("send txdata\n");
362
 
 
363
349
                total_size += txsize;
364
350
        }
365
351
 
366
 
 
367
352
        spin_lock_irqsave(&sdev->priv_lock, flags);
368
353
 
369
354
        list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
376
361
        return total_size;
377
362
}
378
363
 
379
 
 
380
 
/*-------------------------------------------------------------------------*/
381
 
 
382
 
void stub_tx_loop(struct usbip_task *ut)
 
364
int stub_tx_loop(void *data)
383
365
{
384
 
        struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
 
366
        struct usbip_device *ud = data;
385
367
        struct stub_device *sdev = container_of(ud, struct stub_device, ud);
386
368
 
387
 
        while (1) {
388
 
                if (signal_pending(current)) {
389
 
                        usbip_dbg_stub_tx("signal catched\n");
390
 
                        break;
391
 
                }
392
 
 
 
369
        while (!kthread_should_stop()) {
393
370
                if (usbip_event_happened(ud))
394
371
                        break;
395
372
 
414
391
                        break;
415
392
 
416
393
                wait_event_interruptible(sdev->tx_waitq,
417
 
                                (!list_empty(&sdev->priv_tx) ||
418
 
                                 !list_empty(&sdev->unlink_tx)));
 
394
                                         (!list_empty(&sdev->priv_tx) ||
 
395
                                          !list_empty(&sdev->unlink_tx) ||
 
396
                                          kthread_should_stop()));
419
397
        }
 
398
 
 
399
        return 0;
420
400
}