diff options
author | Tatyana Brokhman <tlinder@codeaurora.org> | 2010-11-01 11:38:05 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-11-11 09:19:35 -0500 |
commit | 8be8a9d3d16a25645b7869e4544a9d0ec386966a (patch) | |
tree | c1f7b1854aab0dca0086bfa712437fd0388ddde0 | |
parent | 0eadcc09203349b11ca477ec367079b23d32ab91 (diff) |
usb: dummy_hcd code simplification
Take handling of the control requests out from dummy_timer to a different
function.
Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 251 |
1 files changed, 135 insertions, 116 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 1d2a2abbfa80..13b9f47feecd 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1197,6 +1197,139 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | |||
1197 | #define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) | 1197 | #define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) |
1198 | #define Ep_InRequest (Ep_Request | USB_DIR_IN) | 1198 | #define Ep_InRequest (Ep_Request | USB_DIR_IN) |
1199 | 1199 | ||
1200 | |||
1201 | /** | ||
1202 | * handle_control_request() - handles all control transfers | ||
1203 | * @dum: pointer to dummy (the_controller) | ||
1204 | * @urb: the urb request to handle | ||
1205 | * @setup: pointer to the setup data for a USB device control | ||
1206 | * request | ||
1207 | * @status: pointer to request handling status | ||
1208 | * | ||
1209 | * Return 0 - if the request was handled | ||
1210 | * 1 - if the request wasn't handles | ||
1211 | * error code on error | ||
1212 | */ | ||
1213 | static int handle_control_request(struct dummy *dum, struct urb *urb, | ||
1214 | struct usb_ctrlrequest *setup, | ||
1215 | int *status) | ||
1216 | { | ||
1217 | struct dummy_ep *ep2; | ||
1218 | int ret_val = 1; | ||
1219 | unsigned w_index; | ||
1220 | unsigned w_value; | ||
1221 | |||
1222 | w_index = le16_to_cpu(setup->wIndex); | ||
1223 | w_value = le16_to_cpu(setup->wValue); | ||
1224 | switch (setup->bRequest) { | ||
1225 | case USB_REQ_SET_ADDRESS: | ||
1226 | if (setup->bRequestType != Dev_Request) | ||
1227 | break; | ||
1228 | dum->address = w_value; | ||
1229 | *status = 0; | ||
1230 | dev_dbg(udc_dev(dum), "set_address = %d\n", | ||
1231 | w_value); | ||
1232 | ret_val = 0; | ||
1233 | break; | ||
1234 | case USB_REQ_SET_FEATURE: | ||
1235 | if (setup->bRequestType == Dev_Request) { | ||
1236 | ret_val = 0; | ||
1237 | switch (w_value) { | ||
1238 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1239 | break; | ||
1240 | case USB_DEVICE_B_HNP_ENABLE: | ||
1241 | dum->gadget.b_hnp_enable = 1; | ||
1242 | break; | ||
1243 | case USB_DEVICE_A_HNP_SUPPORT: | ||
1244 | dum->gadget.a_hnp_support = 1; | ||
1245 | break; | ||
1246 | case USB_DEVICE_A_ALT_HNP_SUPPORT: | ||
1247 | dum->gadget.a_alt_hnp_support = 1; | ||
1248 | break; | ||
1249 | default: | ||
1250 | ret_val = -EOPNOTSUPP; | ||
1251 | } | ||
1252 | if (ret_val == 0) { | ||
1253 | dum->devstatus |= (1 << w_value); | ||
1254 | *status = 0; | ||
1255 | } | ||
1256 | } else if (setup->bRequestType == Ep_Request) { | ||
1257 | /* endpoint halt */ | ||
1258 | ep2 = find_endpoint(dum, w_index); | ||
1259 | if (!ep2 || ep2->ep.name == ep0name) { | ||
1260 | ret_val = -EOPNOTSUPP; | ||
1261 | break; | ||
1262 | } | ||
1263 | ep2->halted = 1; | ||
1264 | ret_val = 0; | ||
1265 | *status = 0; | ||
1266 | } | ||
1267 | break; | ||
1268 | case USB_REQ_CLEAR_FEATURE: | ||
1269 | if (setup->bRequestType == Dev_Request) { | ||
1270 | ret_val = 0; | ||
1271 | switch (w_value) { | ||
1272 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1273 | w_value = USB_DEVICE_REMOTE_WAKEUP; | ||
1274 | break; | ||
1275 | default: | ||
1276 | ret_val = -EOPNOTSUPP; | ||
1277 | break; | ||
1278 | } | ||
1279 | if (ret_val == 0) { | ||
1280 | dum->devstatus &= ~(1 << w_value); | ||
1281 | *status = 0; | ||
1282 | } | ||
1283 | } else if (setup->bRequestType == Ep_Request) { | ||
1284 | /* endpoint halt */ | ||
1285 | ep2 = find_endpoint(dum, w_index); | ||
1286 | if (!ep2) { | ||
1287 | ret_val = -EOPNOTSUPP; | ||
1288 | break; | ||
1289 | } | ||
1290 | if (!ep2->wedged) | ||
1291 | ep2->halted = 0; | ||
1292 | ret_val = 0; | ||
1293 | *status = 0; | ||
1294 | } | ||
1295 | break; | ||
1296 | case USB_REQ_GET_STATUS: | ||
1297 | if (setup->bRequestType == Dev_InRequest | ||
1298 | || setup->bRequestType == Intf_InRequest | ||
1299 | || setup->bRequestType == Ep_InRequest) { | ||
1300 | char *buf; | ||
1301 | /* | ||
1302 | * device: remote wakeup, selfpowered | ||
1303 | * interface: nothing | ||
1304 | * endpoint: halt | ||
1305 | */ | ||
1306 | buf = (char *)urb->transfer_buffer; | ||
1307 | if (urb->transfer_buffer_length > 0) { | ||
1308 | if (setup->bRequestType == Ep_InRequest) { | ||
1309 | ep2 = find_endpoint(dum, w_index); | ||
1310 | if (!ep2) { | ||
1311 | ret_val = -EOPNOTSUPP; | ||
1312 | break; | ||
1313 | } | ||
1314 | buf[0] = ep2->halted; | ||
1315 | } else if (setup->bRequestType == | ||
1316 | Dev_InRequest) { | ||
1317 | buf[0] = (u8)dum->devstatus; | ||
1318 | } else | ||
1319 | buf[0] = 0; | ||
1320 | } | ||
1321 | if (urb->transfer_buffer_length > 1) | ||
1322 | buf[1] = 0; | ||
1323 | urb->actual_length = min_t(u32, 2, | ||
1324 | urb->transfer_buffer_length); | ||
1325 | ret_val = 0; | ||
1326 | *status = 0; | ||
1327 | } | ||
1328 | break; | ||
1329 | } | ||
1330 | return ret_val; | ||
1331 | } | ||
1332 | |||
1200 | /* drive both sides of the transfers; looks like irq handlers to | 1333 | /* drive both sides of the transfers; looks like irq handlers to |
1201 | * both drivers except the callbacks aren't in_irq(). | 1334 | * both drivers except the callbacks aren't in_irq(). |
1202 | */ | 1335 | */ |
@@ -1299,14 +1432,8 @@ restart: | |||
1299 | if (ep == &dum->ep [0] && ep->setup_stage) { | 1432 | if (ep == &dum->ep [0] && ep->setup_stage) { |
1300 | struct usb_ctrlrequest setup; | 1433 | struct usb_ctrlrequest setup; |
1301 | int value = 1; | 1434 | int value = 1; |
1302 | struct dummy_ep *ep2; | ||
1303 | unsigned w_index; | ||
1304 | unsigned w_value; | ||
1305 | 1435 | ||
1306 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; | 1436 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; |
1307 | w_index = le16_to_cpu(setup.wIndex); | ||
1308 | w_value = le16_to_cpu(setup.wValue); | ||
1309 | |||
1310 | /* paranoia, in case of stale queued data */ | 1437 | /* paranoia, in case of stale queued data */ |
1311 | list_for_each_entry (req, &ep->queue, queue) { | 1438 | list_for_each_entry (req, &ep->queue, queue) { |
1312 | list_del_init (&req->queue); | 1439 | list_del_init (&req->queue); |
@@ -1328,117 +1455,9 @@ restart: | |||
1328 | ep->last_io = jiffies; | 1455 | ep->last_io = jiffies; |
1329 | ep->setup_stage = 0; | 1456 | ep->setup_stage = 0; |
1330 | ep->halted = 0; | 1457 | ep->halted = 0; |
1331 | switch (setup.bRequest) { | ||
1332 | case USB_REQ_SET_ADDRESS: | ||
1333 | if (setup.bRequestType != Dev_Request) | ||
1334 | break; | ||
1335 | dum->address = w_value; | ||
1336 | status = 0; | ||
1337 | dev_dbg (udc_dev(dum), "set_address = %d\n", | ||
1338 | w_value); | ||
1339 | value = 0; | ||
1340 | break; | ||
1341 | case USB_REQ_SET_FEATURE: | ||
1342 | if (setup.bRequestType == Dev_Request) { | ||
1343 | value = 0; | ||
1344 | switch (w_value) { | ||
1345 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1346 | break; | ||
1347 | case USB_DEVICE_B_HNP_ENABLE: | ||
1348 | dum->gadget.b_hnp_enable = 1; | ||
1349 | break; | ||
1350 | case USB_DEVICE_A_HNP_SUPPORT: | ||
1351 | dum->gadget.a_hnp_support = 1; | ||
1352 | break; | ||
1353 | case USB_DEVICE_A_ALT_HNP_SUPPORT: | ||
1354 | dum->gadget.a_alt_hnp_support | ||
1355 | = 1; | ||
1356 | break; | ||
1357 | default: | ||
1358 | value = -EOPNOTSUPP; | ||
1359 | } | ||
1360 | if (value == 0) { | ||
1361 | dum->devstatus |= | ||
1362 | (1 << w_value); | ||
1363 | status = 0; | ||
1364 | } | ||
1365 | 1458 | ||
1366 | } else if (setup.bRequestType == Ep_Request) { | 1459 | value = handle_control_request(dum, urb, &setup, |
1367 | // endpoint halt | 1460 | &status); |
1368 | ep2 = find_endpoint (dum, w_index); | ||
1369 | if (!ep2 || ep2->ep.name == ep0name) { | ||
1370 | value = -EOPNOTSUPP; | ||
1371 | break; | ||
1372 | } | ||
1373 | ep2->halted = 1; | ||
1374 | value = 0; | ||
1375 | status = 0; | ||
1376 | } | ||
1377 | break; | ||
1378 | case USB_REQ_CLEAR_FEATURE: | ||
1379 | if (setup.bRequestType == Dev_Request) { | ||
1380 | switch (w_value) { | ||
1381 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1382 | dum->devstatus &= ~(1 << | ||
1383 | USB_DEVICE_REMOTE_WAKEUP); | ||
1384 | value = 0; | ||
1385 | status = 0; | ||
1386 | break; | ||
1387 | default: | ||
1388 | value = -EOPNOTSUPP; | ||
1389 | break; | ||
1390 | } | ||
1391 | } else if (setup.bRequestType == Ep_Request) { | ||
1392 | // endpoint halt | ||
1393 | ep2 = find_endpoint (dum, w_index); | ||
1394 | if (!ep2) { | ||
1395 | value = -EOPNOTSUPP; | ||
1396 | break; | ||
1397 | } | ||
1398 | if (!ep2->wedged) | ||
1399 | ep2->halted = 0; | ||
1400 | value = 0; | ||
1401 | status = 0; | ||
1402 | } | ||
1403 | break; | ||
1404 | case USB_REQ_GET_STATUS: | ||
1405 | if (setup.bRequestType == Dev_InRequest | ||
1406 | || setup.bRequestType | ||
1407 | == Intf_InRequest | ||
1408 | || setup.bRequestType | ||
1409 | == Ep_InRequest | ||
1410 | ) { | ||
1411 | char *buf; | ||
1412 | |||
1413 | // device: remote wakeup, selfpowered | ||
1414 | // interface: nothing | ||
1415 | // endpoint: halt | ||
1416 | buf = (char *)urb->transfer_buffer; | ||
1417 | if (urb->transfer_buffer_length > 0) { | ||
1418 | if (setup.bRequestType == | ||
1419 | Ep_InRequest) { | ||
1420 | ep2 = find_endpoint (dum, w_index); | ||
1421 | if (!ep2) { | ||
1422 | value = -EOPNOTSUPP; | ||
1423 | break; | ||
1424 | } | ||
1425 | buf [0] = ep2->halted; | ||
1426 | } else if (setup.bRequestType == | ||
1427 | Dev_InRequest) { | ||
1428 | buf [0] = (u8) | ||
1429 | dum->devstatus; | ||
1430 | } else | ||
1431 | buf [0] = 0; | ||
1432 | } | ||
1433 | if (urb->transfer_buffer_length > 1) | ||
1434 | buf [1] = 0; | ||
1435 | urb->actual_length = min_t(u32, 2, | ||
1436 | urb->transfer_buffer_length); | ||
1437 | value = 0; | ||
1438 | status = 0; | ||
1439 | } | ||
1440 | break; | ||
1441 | } | ||
1442 | 1461 | ||
1443 | /* gadget driver handles all other requests. block | 1462 | /* gadget driver handles all other requests. block |
1444 | * until setup() returns; no reentrancy issues etc. | 1463 | * until setup() returns; no reentrancy issues etc. |