~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to drivers/usb/core/devio.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
104
104
 
105
105
#define MAX_USBFS_BUFFER_SIZE   16384
106
106
 
107
 
static inline int connected(struct dev_state *ps)
 
107
static int connected(struct dev_state *ps)
108
108
{
109
109
        return (!list_empty(&ps->list) &&
110
110
                        ps->dev->state != USB_STATE_NOTATTACHED);
248
248
        kfree(as);
249
249
}
250
250
 
251
 
static inline void async_newpending(struct async *as)
 
251
static void async_newpending(struct async *as)
252
252
{
253
253
        struct dev_state *ps = as->ps;
254
254
        unsigned long flags;
258
258
        spin_unlock_irqrestore(&ps->lock, flags);
259
259
}
260
260
 
261
 
static inline void async_removepending(struct async *as)
 
261
static void async_removepending(struct async *as)
262
262
{
263
263
        struct dev_state *ps = as->ps;
264
264
        unsigned long flags;
268
268
        spin_unlock_irqrestore(&ps->lock, flags);
269
269
}
270
270
 
271
 
static inline struct async *async_getcompleted(struct dev_state *ps)
 
271
static struct async *async_getcompleted(struct dev_state *ps)
272
272
{
273
273
        unsigned long flags;
274
274
        struct async *as = NULL;
283
283
        return as;
284
284
}
285
285
 
286
 
static inline struct async *async_getpending(struct dev_state *ps,
 
286
static struct async *async_getpending(struct dev_state *ps,
287
287
                                             void __user *userurb)
288
288
{
289
289
        unsigned long flags;
302
302
 
303
303
static void snoop_urb(struct urb *urb, void __user *userurb)
304
304
{
305
 
        int j;
 
305
        unsigned j;
306
306
        unsigned char *data = urb->transfer_buffer;
307
307
 
308
308
        if (!usbfs_snoop)
311
311
        dev_info(&urb->dev->dev, "direction=%s\n",
312
312
                        usb_urb_dir_in(urb) ? "IN" : "OUT");
313
313
        dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
314
 
        dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n",
 
314
        dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n",
315
315
                 urb->transfer_buffer_length);
316
 
        dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
 
316
        dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length);
317
317
        dev_info(&urb->dev->dev, "data: ");
318
318
        for (j = 0; j < urb->transfer_buffer_length; ++j)
319
319
                printk("%02x ", data[j]);
325
325
        struct async *as = urb->context;
326
326
        struct dev_state *ps = as->ps;
327
327
        struct siginfo sinfo;
 
328
        struct pid *pid = NULL;
 
329
        uid_t uid = 0;
 
330
        uid_t euid = 0;
 
331
        u32 secid = 0;
 
332
        int signr;
328
333
 
329
334
        spin_lock(&ps->lock);
330
335
        list_move_tail(&as->asynclist, &ps->async_completed);
331
 
        spin_unlock(&ps->lock);
332
336
        as->status = urb->status;
333
 
        if (as->signr) {
 
337
        signr = as->signr;
 
338
        if (signr) {
334
339
                sinfo.si_signo = as->signr;
335
340
                sinfo.si_errno = as->status;
336
341
                sinfo.si_code = SI_ASYNCIO;
337
342
                sinfo.si_addr = as->userurb;
338
 
                kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
339
 
                                      as->euid, as->secid);
 
343
                pid = as->pid;
 
344
                uid = as->uid;
 
345
                euid = as->euid;
 
346
                secid = as->secid;
340
347
        }
341
348
        snoop(&urb->dev->dev, "urb complete\n");
342
349
        snoop_urb(urb, as->userurb);
 
350
        spin_unlock(&ps->lock);
 
351
 
 
352
        if (signr)
 
353
                kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
 
354
                                      euid, secid);
 
355
 
343
356
        wake_up(&ps->wait);
344
357
}
345
358
 
376
389
        destroy_async(ps, &hitlist);
377
390
}
378
391
 
379
 
static inline void destroy_all_async(struct dev_state *ps)
 
392
static void destroy_all_async(struct dev_state *ps)
380
393
{
381
394
        destroy_async(ps, &ps->async_pending);
382
395
}
525
538
{
526
539
        int ret = 0;
527
540
 
528
 
        if (ps->dev->state != USB_STATE_ADDRESS
 
541
        if (ps->dev->state != USB_STATE_UNAUTHENTICATED
 
542
         && ps->dev->state != USB_STATE_ADDRESS
529
543
         && ps->dev->state != USB_STATE_CONFIGURED)
530
544
                return -EHOSTUNREACH;
531
545
        if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
840
854
        ret = checkintf(ps, ret);
841
855
        if (ret)
842
856
                return ret;
843
 
        usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0);
 
857
        usb_reset_endpoint(ps->dev, ep);
844
858
        return 0;
845
859
}
846
860
 
981
995
                                USBDEVFS_URB_ZERO_PACKET |
982
996
                                USBDEVFS_URB_NO_INTERRUPT))
983
997
                return -EINVAL;
984
 
        if (!uurb->buffer)
 
998
        if (uurb->buffer_length > 0 && !uurb->buffer)
985
999
                return -EINVAL;
986
1000
        if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
987
1001
            (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
1037
1051
                        is_in = 0;
1038
1052
                        uurb->endpoint &= ~USB_DIR_IN;
1039
1053
                }
1040
 
                if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
1041
 
                                uurb->buffer, uurb->buffer_length)) {
1042
 
                        kfree(dr);
1043
 
                        return -EFAULT;
1044
 
                }
1045
1054
                snoop(&ps->dev->dev, "control urb: bRequest=%02x "
1046
1055
                        "bRrequestType=%02x wValue=%04x "
1047
1056
                        "wIndex=%04x wLength=%04x\n",
1061
1070
                uurb->number_of_packets = 0;
1062
1071
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
1063
1072
                        return -EINVAL;
1064
 
                if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
1065
 
                                uurb->buffer, uurb->buffer_length))
1066
 
                        return -EFAULT;
1067
1073
                snoop(&ps->dev->dev, "bulk urb\n");
1068
1074
                break;
1069
1075
 
1105
1111
                        return -EINVAL;
1106
1112
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
1107
1113
                        return -EINVAL;
1108
 
                if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
1109
 
                                uurb->buffer, uurb->buffer_length))
1110
 
                        return -EFAULT;
1111
1114
                snoop(&ps->dev->dev, "interrupt urb\n");
1112
1115
                break;
1113
1116
 
1114
1117
        default:
1115
1118
                return -EINVAL;
1116
1119
        }
 
1120
        if (uurb->buffer_length > 0 &&
 
1121
                        !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
 
1122
                                uurb->buffer, uurb->buffer_length)) {
 
1123
                kfree(isopkt);
 
1124
                kfree(dr);
 
1125
                return -EFAULT;
 
1126
        }
1117
1127
        as = alloc_async(uurb->number_of_packets);
1118
1128
        if (!as) {
1119
1129
                kfree(isopkt);
1120
1130
                kfree(dr);
1121
1131
                return -ENOMEM;
1122
1132
        }
1123
 
        as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
1124
 
        if (!as->urb->transfer_buffer) {
1125
 
                kfree(isopkt);
1126
 
                kfree(dr);
1127
 
                free_async(as);
1128
 
                return -ENOMEM;
 
1133
        if (uurb->buffer_length > 0) {
 
1134
                as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
 
1135
                                GFP_KERNEL);
 
1136
                if (!as->urb->transfer_buffer) {
 
1137
                        kfree(isopkt);
 
1138
                        kfree(dr);
 
1139
                        free_async(as);
 
1140
                        return -ENOMEM;
 
1141
                }
1129
1142
        }
1130
1143
        as->urb->dev = ps->dev;
1131
1144
        as->urb->pipe = (uurb->type << 30) |
1168
1181
        kfree(isopkt);
1169
1182
        as->ps = ps;
1170
1183
        as->userurb = arg;
1171
 
        if (uurb->endpoint & USB_DIR_IN)
 
1184
        if (is_in && uurb->buffer_length > 0)
1172
1185
                as->userbuffer = uurb->buffer;
1173
1186
        else
1174
1187
                as->userbuffer = NULL;
1178
1191
        as->uid = cred->uid;
1179
1192
        as->euid = cred->euid;
1180
1193
        security_task_getsecid(current, &as->secid);
1181
 
        if (!is_in) {
 
1194
        if (!is_in && uurb->buffer_length > 0) {
1182
1195
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
1183
 
                                as->urb->transfer_buffer_length)) {
 
1196
                                uurb->buffer_length)) {
1184
1197
                        free_async(as);
1185
1198
                        return -EFAULT;
1186
1199
                }
1230
1243
        if (as->userbuffer)
1231
1244
                if (copy_to_user(as->userbuffer, urb->transfer_buffer,
1232
1245
                                 urb->transfer_buffer_length))
1233
 
                        return -EFAULT;
 
1246
                        goto err_out;
1234
1247
        if (put_user(as->status, &userurb->status))
1235
 
                return -EFAULT;
 
1248
                goto err_out;
1236
1249
        if (put_user(urb->actual_length, &userurb->actual_length))
1237
 
                return -EFAULT;
 
1250
                goto err_out;
1238
1251
        if (put_user(urb->error_count, &userurb->error_count))
1239
 
                return -EFAULT;
 
1252
                goto err_out;
1240
1253
 
1241
1254
        if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
1242
1255
                for (i = 0; i < urb->number_of_packets; i++) {
1243
1256
                        if (put_user(urb->iso_frame_desc[i].actual_length,
1244
1257
                                     &userurb->iso_frame_desc[i].actual_length))
1245
 
                                return -EFAULT;
 
1258
                                goto err_out;
1246
1259
                        if (put_user(urb->iso_frame_desc[i].status,
1247
1260
                                     &userurb->iso_frame_desc[i].status))
1248
 
                                return -EFAULT;
 
1261
                                goto err_out;
1249
1262
                }
1250
1263
        }
1251
1264
 
1254
1267
        if (put_user(addr, (void __user * __user *)arg))
1255
1268
                return -EFAULT;
1256
1269
        return 0;
 
1270
 
 
1271
err_out:
 
1272
        free_async(as);
 
1273
        return -EFAULT;
1257
1274
}
1258
1275
 
1259
1276
static struct async *reap_as(struct dev_state *ps)