aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
committerTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
commitd702d12167a2c05a346f49aac7a311d597762495 (patch)
treebaae42c299cce34d6df24b5d01f8b1d0b481bd9a /drivers/usb/core/devio.c
parent9418c65f9bd861d0f7e39aab9cfb3aa6f2275d11 (diff)
parentac0f6f927db539e03e1f3f61bcd4ed57d5cde7a9 (diff)
Merge with mainline to remove plat-omap/Kconfig conflict
Conflicts: arch/arm/plat-omap/Kconfig
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 6e8bcdfd23b4..a678186f218f 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1312,9 +1312,9 @@ static int processcompl(struct async *as, void __user * __user *arg)
1312 void __user *addr = as->userurb; 1312 void __user *addr = as->userurb;
1313 unsigned int i; 1313 unsigned int i;
1314 1314
1315 if (as->userbuffer) 1315 if (as->userbuffer && urb->actual_length)
1316 if (copy_to_user(as->userbuffer, urb->transfer_buffer, 1316 if (copy_to_user(as->userbuffer, urb->transfer_buffer,
1317 urb->transfer_buffer_length)) 1317 urb->actual_length))
1318 goto err_out; 1318 goto err_out;
1319 if (put_user(as->status, &userurb->status)) 1319 if (put_user(as->status, &userurb->status))
1320 goto err_out; 1320 goto err_out;
@@ -1334,14 +1334,11 @@ static int processcompl(struct async *as, void __user * __user *arg)
1334 } 1334 }
1335 } 1335 }
1336 1336
1337 free_async(as);
1338
1339 if (put_user(addr, (void __user * __user *)arg)) 1337 if (put_user(addr, (void __user * __user *)arg))
1340 return -EFAULT; 1338 return -EFAULT;
1341 return 0; 1339 return 0;
1342 1340
1343err_out: 1341err_out:
1344 free_async(as);
1345 return -EFAULT; 1342 return -EFAULT;
1346} 1343}
1347 1344
@@ -1371,8 +1368,11 @@ static struct async *reap_as(struct dev_state *ps)
1371static int proc_reapurb(struct dev_state *ps, void __user *arg) 1368static int proc_reapurb(struct dev_state *ps, void __user *arg)
1372{ 1369{
1373 struct async *as = reap_as(ps); 1370 struct async *as = reap_as(ps);
1374 if (as) 1371 if (as) {
1375 return processcompl(as, (void __user * __user *)arg); 1372 int retval = processcompl(as, (void __user * __user *)arg);
1373 free_async(as);
1374 return retval;
1375 }
1376 if (signal_pending(current)) 1376 if (signal_pending(current))
1377 return -EINTR; 1377 return -EINTR;
1378 return -EIO; 1378 return -EIO;
@@ -1380,11 +1380,16 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)
1380 1380
1381static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) 1381static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
1382{ 1382{
1383 int retval;
1383 struct async *as; 1384 struct async *as;
1384 1385
1385 if (!(as = async_getcompleted(ps))) 1386 as = async_getcompleted(ps);
1386 return -EAGAIN; 1387 retval = -EAGAIN;
1387 return processcompl(as, (void __user * __user *)arg); 1388 if (as) {
1389 retval = processcompl(as, (void __user * __user *)arg);
1390 free_async(as);
1391 }
1392 return retval;
1388} 1393}
1389 1394
1390#ifdef CONFIG_COMPAT 1395#ifdef CONFIG_COMPAT
@@ -1475,9 +1480,9 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1475 void __user *addr = as->userurb; 1480 void __user *addr = as->userurb;
1476 unsigned int i; 1481 unsigned int i;
1477 1482
1478 if (as->userbuffer) 1483 if (as->userbuffer && urb->actual_length)
1479 if (copy_to_user(as->userbuffer, urb->transfer_buffer, 1484 if (copy_to_user(as->userbuffer, urb->transfer_buffer,
1480 urb->transfer_buffer_length)) 1485 urb->actual_length))
1481 return -EFAULT; 1486 return -EFAULT;
1482 if (put_user(as->status, &userurb->status)) 1487 if (put_user(as->status, &userurb->status))
1483 return -EFAULT; 1488 return -EFAULT;
@@ -1497,7 +1502,6 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1497 } 1502 }
1498 } 1503 }
1499 1504
1500 free_async(as);
1501 if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) 1505 if (put_user(ptr_to_compat(addr), (u32 __user *)arg))
1502 return -EFAULT; 1506 return -EFAULT;
1503 return 0; 1507 return 0;
@@ -1506,8 +1510,11 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1506static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) 1510static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
1507{ 1511{
1508 struct async *as = reap_as(ps); 1512 struct async *as = reap_as(ps);
1509 if (as) 1513 if (as) {
1510 return processcompl_compat(as, (void __user * __user *)arg); 1514 int retval = processcompl_compat(as, (void __user * __user *)arg);
1515 free_async(as);
1516 return retval;
1517 }
1511 if (signal_pending(current)) 1518 if (signal_pending(current))
1512 return -EINTR; 1519 return -EINTR;
1513 return -EIO; 1520 return -EIO;
@@ -1515,11 +1522,16 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
1515 1522
1516static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) 1523static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
1517{ 1524{
1525 int retval;
1518 struct async *as; 1526 struct async *as;
1519 1527
1520 if (!(as = async_getcompleted(ps))) 1528 retval = -EAGAIN;
1521 return -EAGAIN; 1529 as = async_getcompleted(ps);
1522 return processcompl_compat(as, (void __user * __user *)arg); 1530 if (as) {
1531 retval = processcompl_compat(as, (void __user * __user *)arg);
1532 free_async(as);
1533 }
1534 return retval;
1523} 1535}
1524 1536
1525 1537