diff options
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 53 |
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 | ||
1029 | static 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 */ |
1037 | static int | 1030 | static int |
1038 | transfer (struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit) | 1031 | transfer(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 | ||
1512 | return_urb: | 1506 | return_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 | ||