aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-11-25 10:00:22 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:42:12 -0500
commit6241d8ca1dc27356180011dff4d93a3c5b3cbd76 (patch)
treed406a9dd8f8cdad7054d5de42f3262a248e2c5d3 /drivers/media
parentbce039c099e97b07534518b5f3c0ce31b1606ff6 (diff)
V4L/DVB (13503): uvcvideo: Merge iterms, oterms and units linked lists
All terminals and units are now added to a single linked list of entities per chain. This makes terminals and units handling code more generic. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c29
-rw-r--r--drivers/media/video/uvc/uvc_driver.c48
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c10
-rw-r--r--drivers/media/video/uvc/uvcvideo.h5
4 files changed, 36 insertions, 56 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 6f1487fc3d7c..0469d7a876a8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -742,17 +742,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
742 v4l2_id &= V4L2_CTRL_ID_MASK; 742 v4l2_id &= V4L2_CTRL_ID_MASK;
743 743
744 /* Find the control. */ 744 /* Find the control. */
745 __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next); 745 list_for_each_entry(entity, &chain->entities, chain) {
746 if (ctrl && !next)
747 return ctrl;
748
749 list_for_each_entry(entity, &chain->iterms, chain) {
750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
751 if (ctrl && !next)
752 return ctrl;
753 }
754
755 list_for_each_entry(entity, &chain->extensions, chain) {
756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 746 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
757 if (ctrl && !next) 747 if (ctrl && !next)
758 return ctrl; 748 return ctrl;
@@ -951,17 +941,7 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
951 int ret = 0; 941 int ret = 0;
952 942
953 /* Find the control. */ 943 /* Find the control. */
954 ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback); 944 list_for_each_entry(entity, &chain->entities, chain) {
955 if (ret < 0)
956 goto done;
957
958 list_for_each_entry(entity, &chain->iterms, chain) {
959 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
960 if (ret < 0)
961 goto done;
962 }
963
964 list_for_each_entry(entity, &chain->extensions, chain) {
965 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); 945 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
966 if (ret < 0) 946 if (ret < 0)
967 goto done; 947 goto done;
@@ -1075,8 +1055,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1075 int ret; 1055 int ret;
1076 1056
1077 /* Find the extension unit. */ 1057 /* Find the extension unit. */
1078 list_for_each_entry(entity, &chain->extensions, chain) { 1058 list_for_each_entry(entity, &chain->entities, chain) {
1079 if (entity->id == xctrl->unit) 1059 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1060 entity->id == xctrl->unit)
1080 break; 1061 break;
1081 } 1062 }
1082 1063
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index b8b33a05cabd..db28311d6ec8 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1224,7 +1224,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1224 return -1; 1224 return -1;
1225 } 1225 }
1226 1226
1227 list_add_tail(&entity->chain, &chain->extensions);
1228 break; 1227 break;
1229 1228
1230 case UVC_VC_PROCESSING_UNIT: 1229 case UVC_VC_PROCESSING_UNIT:
@@ -1263,7 +1262,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1263 if (uvc_trace_param & UVC_TRACE_PROBE) 1262 if (uvc_trace_param & UVC_TRACE_PROBE)
1264 printk(" <- IT %d\n", entity->id); 1263 printk(" <- IT %d\n", entity->id);
1265 1264
1266 list_add_tail(&entity->chain, &chain->iterms);
1267 break; 1265 break;
1268 1266
1269 case UVC_TT_STREAMING: 1267 case UVC_TT_STREAMING:
@@ -1276,7 +1274,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1276 return -1; 1274 return -1;
1277 } 1275 }
1278 1276
1279 list_add_tail(&entity->chain, &chain->iterms);
1280 break; 1277 break;
1281 1278
1282 default: 1279 default:
@@ -1285,6 +1282,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1285 return -1; 1282 return -1;
1286 } 1283 }
1287 1284
1285 list_add_tail(&entity->chain, &chain->entities);
1288 return 0; 1286 return 0;
1289} 1287}
1290 1288
@@ -1315,7 +1313,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1315 return -EINVAL; 1313 return -EINVAL;
1316 } 1314 }
1317 1315
1318 list_add_tail(&forward->chain, &chain->extensions); 1316 list_add_tail(&forward->chain, &chain->entities);
1319 if (uvc_trace_param & UVC_TRACE_PROBE) { 1317 if (uvc_trace_param & UVC_TRACE_PROBE) {
1320 if (!found) 1318 if (!found)
1321 printk(" (->"); 1319 printk(" (->");
@@ -1335,7 +1333,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1335 return -EINVAL; 1333 return -EINVAL;
1336 } 1334 }
1337 1335
1338 list_add_tail(&forward->chain, &chain->oterms); 1336 list_add_tail(&forward->chain, &chain->entities);
1339 if (uvc_trace_param & UVC_TRACE_PROBE) { 1337 if (uvc_trace_param & UVC_TRACE_PROBE) {
1340 if (!found) 1338 if (!found)
1341 printk(" (->"); 1339 printk(" (->");
@@ -1391,7 +1389,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1391 if (uvc_trace_param & UVC_TRACE_PROBE) 1389 if (uvc_trace_param & UVC_TRACE_PROBE)
1392 printk(" %d", term->id); 1390 printk(" %d", term->id);
1393 1391
1394 list_add_tail(&term->chain, &chain->iterms); 1392 list_add_tail(&term->chain, &chain->entities);
1395 uvc_scan_chain_forward(chain, term, entity); 1393 uvc_scan_chain_forward(chain, term, entity);
1396 } 1394 }
1397 1395
@@ -1412,7 +1410,7 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
1412 int id; 1410 int id;
1413 1411
1414 entity = oterm; 1412 entity = oterm;
1415 list_add_tail(&entity->chain, &chain->oterms); 1413 list_add_tail(&entity->chain, &chain->entities);
1416 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); 1414 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1417 1415
1418 id = entity->output.bSourceID; 1416 id = entity->output.bSourceID;
@@ -1452,21 +1450,25 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
1452 return 0; 1450 return 0;
1453} 1451}
1454 1452
1455static unsigned int uvc_print_terms(struct list_head *terms, char *buffer) 1453static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
1454 char *buffer)
1456{ 1455{
1457 struct uvc_entity *term; 1456 struct uvc_entity *term;
1458 unsigned int nterms = 0; 1457 unsigned int nterms = 0;
1459 char *p = buffer; 1458 char *p = buffer;
1460 1459
1461 list_for_each_entry(term, terms, chain) { 1460 list_for_each_entry(term, terms, chain) {
1462 p += sprintf(p, "%u", term->id); 1461 if (!UVC_ENTITY_IS_TERM(term) ||
1463 if (term->chain.next != terms) { 1462 UVC_TERM_DIRECTION(term) != dir)
1463 continue;
1464
1465 if (nterms)
1464 p += sprintf(p, ","); 1466 p += sprintf(p, ",");
1465 if (++nterms >= 4) { 1467 if (++nterms >= 4) {
1466 p += sprintf(p, "..."); 1468 p += sprintf(p, "...");
1467 break; 1469 break;
1468 }
1469 } 1470 }
1471 p += sprintf(p, "%u", term->id);
1470 } 1472 }
1471 1473
1472 return p - buffer; 1474 return p - buffer;
@@ -1477,9 +1479,9 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain)
1477 static char buffer[43]; 1479 static char buffer[43];
1478 char *p = buffer; 1480 char *p = buffer;
1479 1481
1480 p += uvc_print_terms(&chain->iterms, p); 1482 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
1481 p += sprintf(p, " -> "); 1483 p += sprintf(p, " -> ");
1482 uvc_print_terms(&chain->oterms, p); 1484 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
1483 1485
1484 return buffer; 1486 return buffer;
1485} 1487}
@@ -1510,9 +1512,7 @@ static int uvc_scan_device(struct uvc_device *dev)
1510 if (chain == NULL) 1512 if (chain == NULL)
1511 return -ENOMEM; 1513 return -ENOMEM;
1512 1514
1513 INIT_LIST_HEAD(&chain->iterms); 1515 INIT_LIST_HEAD(&chain->entities);
1514 INIT_LIST_HEAD(&chain->oterms);
1515 INIT_LIST_HEAD(&chain->extensions);
1516 mutex_init(&chain->ctrl_mutex); 1516 mutex_init(&chain->ctrl_mutex);
1517 chain->dev = dev; 1517 chain->dev = dev;
1518 1518
@@ -1685,13 +1685,13 @@ static int uvc_register_video(struct uvc_device *dev,
1685 * Register all video devices in all chains. 1685 * Register all video devices in all chains.
1686 */ 1686 */
1687static int uvc_register_terms(struct uvc_device *dev, 1687static int uvc_register_terms(struct uvc_device *dev,
1688 struct uvc_video_chain *chain, struct list_head *terms) 1688 struct uvc_video_chain *chain)
1689{ 1689{
1690 struct uvc_streaming *stream; 1690 struct uvc_streaming *stream;
1691 struct uvc_entity *term; 1691 struct uvc_entity *term;
1692 int ret; 1692 int ret;
1693 1693
1694 list_for_each_entry(term, terms, chain) { 1694 list_for_each_entry(term, &chain->entities, chain) {
1695 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING) 1695 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1696 continue; 1696 continue;
1697 1697
@@ -1717,11 +1717,7 @@ static int uvc_register_chains(struct uvc_device *dev)
1717 int ret; 1717 int ret;
1718 1718
1719 list_for_each_entry(chain, &dev->chains, list) { 1719 list_for_each_entry(chain, &dev->chains, list) {
1720 ret = uvc_register_terms(dev, chain, &chain->iterms); 1720 ret = uvc_register_terms(dev, chain);
1721 if (ret < 0)
1722 return ret;
1723
1724 ret = uvc_register_terms(dev, chain, &chain->oterms);
1725 if (ret < 0) 1721 if (ret < 0)
1726 return ret; 1722 return ret;
1727 } 1723 }
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index be3da56d4db3..9e1f2c208ed8 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -620,12 +620,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
620 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 620 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
621 if (index != 0) 621 if (index != 0)
622 return -EINVAL; 622 return -EINVAL;
623 iterm = list_first_entry(&chain->iterms, 623 list_for_each_entry(iterm, &chain->entities, chain) {
624 struct uvc_entity, chain); 624 if (UVC_ENTITY_IS_ITERM(iterm))
625 break;
626 }
625 pin = iterm->id; 627 pin = iterm->id;
626 } else if (pin < selector->selector.bNrInPins) { 628 } else if (pin < selector->selector.bNrInPins) {
627 pin = selector->selector.baSourceID[index]; 629 pin = selector->selector.baSourceID[index];
628 list_for_each_entry(iterm, chain->iterms.next, chain) { 630 list_for_each_entry(iterm, &chain->entities, chain) {
631 if (!UVC_ENTITY_IS_ITERM(iterm))
632 continue;
629 if (iterm->id == pin) 633 if (iterm->id == pin)
630 break; 634 break;
631 } 635 }
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index fb3342ae6d7c..9e6948fb3e61 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -75,6 +75,7 @@ struct uvc_xu_control {
75 75
76#define UVC_TERM_INPUT 0x0000 76#define UVC_TERM_INPUT 0x0000
77#define UVC_TERM_OUTPUT 0x8000 77#define UVC_TERM_OUTPUT 0x8000
78#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
78 79
79#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) 80#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 81#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
@@ -408,11 +409,9 @@ struct uvc_video_chain {
408 struct uvc_device *dev; 409 struct uvc_device *dev;
409 struct list_head list; 410 struct list_head list;
410 411
411 struct list_head iterms; /* Input terminals */ 412 struct list_head entities; /* All entities */
412 struct list_head oterms; /* Output terminals */
413 struct uvc_entity *processing; /* Processing unit */ 413 struct uvc_entity *processing; /* Processing unit */
414 struct uvc_entity *selector; /* Selector unit */ 414 struct uvc_entity *selector; /* Selector unit */
415 struct list_head extensions; /* Extension units */
416 415
417 struct mutex ctrl_mutex; 416 struct mutex ctrl_mutex;
418}; 417};