aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/dummy_hcd.c53
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index f2b124cf3206..c1af7bab26f0 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1026,16 +1026,10 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1026 return rc; 1026 return rc;
1027} 1027}
1028 1028
1029static void maybe_set_status (struct urb *urb, int status)
1030{
1031 spin_lock (&urb->lock);
1032 urb->status = status;
1033 spin_unlock (&urb->lock);
1034}
1035
1036/* transfer up to a frame's worth; caller must own lock */ 1029/* transfer up to a frame's worth; caller must own lock */
1037static int 1030static int
1038transfer (struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit) 1031transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit,
1032 int *status)
1039{ 1033{
1040 struct dummy_request *req; 1034 struct dummy_request *req;
1041 1035
@@ -1103,15 +1097,15 @@ top:
1103 if (is_short) { 1097 if (is_short) {
1104 if (host_len == dev_len) { 1098 if (host_len == dev_len) {
1105 req->req.status = 0; 1099 req->req.status = 0;
1106 maybe_set_status (urb, 0); 1100 *status = 0;
1107 } else if (to_host) { 1101 } else if (to_host) {
1108 req->req.status = 0; 1102 req->req.status = 0;
1109 if (dev_len > host_len) 1103 if (dev_len > host_len)
1110 maybe_set_status (urb, -EOVERFLOW); 1104 *status = -EOVERFLOW;
1111 else 1105 else
1112 maybe_set_status (urb, 0); 1106 *status = 0;
1113 } else if (!to_host) { 1107 } else if (!to_host) {
1114 maybe_set_status (urb, 0); 1108 *status = 0;
1115 if (host_len > dev_len) 1109 if (host_len > dev_len)
1116 req->req.status = -EOVERFLOW; 1110 req->req.status = -EOVERFLOW;
1117 else 1111 else
@@ -1125,9 +1119,8 @@ top:
1125 req->req.status = 0; 1119 req->req.status = 0;
1126 if (urb->transfer_buffer_length == urb->actual_length 1120 if (urb->transfer_buffer_length == urb->actual_length
1127 && !(urb->transfer_flags 1121 && !(urb->transfer_flags
1128 & URB_ZERO_PACKET)) { 1122 & URB_ZERO_PACKET))
1129 maybe_set_status (urb, 0); 1123 *status = 0;
1130 }
1131 } 1124 }
1132 1125
1133 /* device side completion --> continuable */ 1126 /* device side completion --> continuable */
@@ -1143,7 +1136,7 @@ top:
1143 } 1136 }
1144 1137
1145 /* host side completion --> terminate */ 1138 /* host side completion --> terminate */
1146 if (urb->status != -EINPROGRESS) 1139 if (*status != -EINPROGRESS)
1147 break; 1140 break;
1148 1141
1149 /* rescan to continue with any other queued i/o */ 1142 /* rescan to continue with any other queued i/o */
@@ -1254,6 +1247,7 @@ restart:
1254 u8 address; 1247 u8 address;
1255 struct dummy_ep *ep = NULL; 1248 struct dummy_ep *ep = NULL;
1256 int type; 1249 int type;
1250 int status = -EINPROGRESS;
1257 1251
1258 urb = urbp->urb; 1252 urb = urbp->urb;
1259 if (urb->unlinked) 1253 if (urb->unlinked)
@@ -1279,7 +1273,7 @@ restart:
1279 dev_dbg (dummy_dev(dum), 1273 dev_dbg (dummy_dev(dum),
1280 "no ep configured for urb %p\n", 1274 "no ep configured for urb %p\n",
1281 urb); 1275 urb);
1282 maybe_set_status (urb, -EPROTO); 1276 status = -EPROTO;
1283 goto return_urb; 1277 goto return_urb;
1284 } 1278 }
1285 1279
@@ -1294,7 +1288,7 @@ restart:
1294 /* NOTE: must not be iso! */ 1288 /* NOTE: must not be iso! */
1295 dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", 1289 dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n",
1296 ep->ep.name, urb); 1290 ep->ep.name, urb);
1297 maybe_set_status (urb, -EPIPE); 1291 status = -EPIPE;
1298 goto return_urb; 1292 goto return_urb;
1299 } 1293 }
1300 /* FIXME make sure both ends agree on maxpacket */ 1294 /* FIXME make sure both ends agree on maxpacket */
@@ -1312,7 +1306,7 @@ restart:
1312 w_value = le16_to_cpu(setup.wValue); 1306 w_value = le16_to_cpu(setup.wValue);
1313 if (le16_to_cpu(setup.wLength) != 1307 if (le16_to_cpu(setup.wLength) !=
1314 urb->transfer_buffer_length) { 1308 urb->transfer_buffer_length) {
1315 maybe_set_status (urb, -EOVERFLOW); 1309 status = -EOVERFLOW;
1316 goto return_urb; 1310 goto return_urb;
1317 } 1311 }
1318 1312
@@ -1342,7 +1336,7 @@ restart:
1342 if (setup.bRequestType != Dev_Request) 1336 if (setup.bRequestType != Dev_Request)
1343 break; 1337 break;
1344 dum->address = w_value; 1338 dum->address = w_value;
1345 maybe_set_status (urb, 0); 1339 status = 0;
1346 dev_dbg (udc_dev(dum), "set_address = %d\n", 1340 dev_dbg (udc_dev(dum), "set_address = %d\n",
1347 w_value); 1341 w_value);
1348 value = 0; 1342 value = 0;
@@ -1369,7 +1363,7 @@ restart:
1369 if (value == 0) { 1363 if (value == 0) {
1370 dum->devstatus |= 1364 dum->devstatus |=
1371 (1 << w_value); 1365 (1 << w_value);
1372 maybe_set_status (urb, 0); 1366 status = 0;
1373 } 1367 }
1374 1368
1375 } else if (setup.bRequestType == Ep_Request) { 1369 } else if (setup.bRequestType == Ep_Request) {
@@ -1381,7 +1375,7 @@ restart:
1381 } 1375 }
1382 ep2->halted = 1; 1376 ep2->halted = 1;
1383 value = 0; 1377 value = 0;
1384 maybe_set_status (urb, 0); 1378 status = 0;
1385 } 1379 }
1386 break; 1380 break;
1387 case USB_REQ_CLEAR_FEATURE: 1381 case USB_REQ_CLEAR_FEATURE:
@@ -1391,7 +1385,7 @@ restart:
1391 dum->devstatus &= ~(1 << 1385 dum->devstatus &= ~(1 <<
1392 USB_DEVICE_REMOTE_WAKEUP); 1386 USB_DEVICE_REMOTE_WAKEUP);
1393 value = 0; 1387 value = 0;
1394 maybe_set_status (urb, 0); 1388 status = 0;
1395 break; 1389 break;
1396 default: 1390 default:
1397 value = -EOPNOTSUPP; 1391 value = -EOPNOTSUPP;
@@ -1406,7 +1400,7 @@ restart:
1406 } 1400 }
1407 ep2->halted = 0; 1401 ep2->halted = 0;
1408 value = 0; 1402 value = 0;
1409 maybe_set_status (urb, 0); 1403 status = 0;
1410 } 1404 }
1411 break; 1405 break;
1412 case USB_REQ_GET_STATUS: 1406 case USB_REQ_GET_STATUS:
@@ -1443,7 +1437,7 @@ restart:
1443 urb->actual_length = min (2, 1437 urb->actual_length = min (2,
1444 urb->transfer_buffer_length); 1438 urb->transfer_buffer_length);
1445 value = 0; 1439 value = 0;
1446 maybe_set_status (urb, 0); 1440 status = 0;
1447 } 1441 }
1448 break; 1442 break;
1449 } 1443 }
@@ -1470,7 +1464,7 @@ restart:
1470 dev_dbg (udc_dev(dum), 1464 dev_dbg (udc_dev(dum),
1471 "setup --> %d\n", 1465 "setup --> %d\n",
1472 value); 1466 value);
1473 maybe_set_status (urb, -EPIPE); 1467 status = -EPIPE;
1474 urb->actual_length = 0; 1468 urb->actual_length = 0;
1475 } 1469 }
1476 1470
@@ -1487,7 +1481,7 @@ restart:
1487 * report random errors, to debug drivers. 1481 * report random errors, to debug drivers.
1488 */ 1482 */
1489 limit = max (limit, periodic_bytes (dum, ep)); 1483 limit = max (limit, periodic_bytes (dum, ep));
1490 maybe_set_status (urb, -ENOSYS); 1484 status = -ENOSYS;
1491 break; 1485 break;
1492 1486
1493 case PIPE_INTERRUPT: 1487 case PIPE_INTERRUPT:
@@ -1501,12 +1495,12 @@ restart:
1501 default: 1495 default:
1502 treat_control_like_bulk: 1496 treat_control_like_bulk:
1503 ep->last_io = jiffies; 1497 ep->last_io = jiffies;
1504 total = transfer (dum, urb, ep, limit); 1498 total = transfer(dum, urb, ep, limit, &status);
1505 break; 1499 break;
1506 } 1500 }
1507 1501
1508 /* incomplete transfer? */ 1502 /* incomplete transfer? */
1509 if (urb->status == -EINPROGRESS) 1503 if (status == -EINPROGRESS)
1510 continue; 1504 continue;
1511 1505
1512return_urb: 1506return_urb:
@@ -1517,6 +1511,7 @@ return_urb:
1517 1511
1518 usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); 1512 usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb);
1519 spin_unlock (&dum->lock); 1513 spin_unlock (&dum->lock);
1514 urb->status = status;
1520 usb_hcd_giveback_urb (dummy_to_hcd(dum), urb); 1515 usb_hcd_giveback_urb (dummy_to_hcd(dum), urb);
1521 spin_lock (&dum->lock); 1516 spin_lock (&dum->lock);
1522 1517