1 /* 2 * Copyright (c) 2006-2008 Intel Corporation 3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 4 * Copyright (c) 2008 Red Hat Inc. 5 * 6 * DRM core CRTC related functions 7 * 8 * Permission to use, copy, modify, distribute, and sell this software and its 9 * documentation for any purpose is hereby granted without fee, provided that 10 * the above copyright notice appear in all copies and that both that copyright 11 * notice and this permission notice appear in supporting documentation, and 12 * that the name of the copyright holders not be used in advertising or 13 * publicity pertaining to distribution of the software without specific, 14 * written prior permission. The copyright holders make no representations 15 * about the suitability of this software for any purpose. It is provided "as 16 * is" without express or implied warranty. 17 * 18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 * 26 * Authors: 27 * Keith Packard 28 * Eric Anholt <eric@anholt.net> 29 * Dave Airlie <airlied@linux.ie> 30 * Jesse Barnes <jesse.barnes@intel.com> 31 */ 32 #include <linux/list.h> 33 #include "drm.h" 34 #include "drmP.h" 35 #include "drm_crtc.h" 36 37 struct drm_prop_enum_list { 38 int type; 39 char *name; 40 }; 41 42 /* Avoid boilerplate. I'm tired of typing. */ 43 #define DRM_ENUM_NAME_FN(fnname, list) \ 44 char *fnname(int val) \ 45 { \ 46 int i; \ 47 for (i = 0; i < ARRAY_SIZE(list); i++) { \ 48 if (list[i].type == val) \ 49 return list[i].name; \ 50 } \ 51 return "(unknown)"; \ 52 } 53 54 /* 55 * Global properties 56 */ 57 static struct drm_prop_enum_list drm_dpms_enum_list[] = 58 { { DRM_MODE_DPMS_ON, "On" }, 59 { DRM_MODE_DPMS_STANDBY, "Standby" }, 60 { DRM_MODE_DPMS_SUSPEND, "Suspend" }, 61 { DRM_MODE_DPMS_OFF, "Off" } 62 }; 63 64 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) 65 66 /* 67 * Optional properties 68 */ 69 static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = 70 { 71 { DRM_MODE_SCALE_NONE, "None" }, 72 { DRM_MODE_SCALE_FULLSCREEN, "Full" }, 73 { DRM_MODE_SCALE_CENTER, "Center" }, 74 { DRM_MODE_SCALE_ASPECT, "Full aspect" }, 75 }; 76 77 static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = 78 { 79 { DRM_MODE_DITHERING_OFF, "Off" }, 80 { DRM_MODE_DITHERING_ON, "On" }, 81 }; 82 83 /* 84 * Non-global properties, but "required" for certain connectors. 85 */ 86 static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = 87 { 88 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 89 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 90 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 91 }; 92 93 DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) 94 95 static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = 96 { 97 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 98 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 99 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 100 }; 101 102 DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, 103 drm_dvi_i_subconnector_enum_list) 104 105 static struct drm_prop_enum_list drm_tv_select_enum_list[] = 106 { 107 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 108 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 109 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 110 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 111 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 112 }; 113 114 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) 115 116 static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = 117 { 118 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 119 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 120 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 121 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 122 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 123 }; 124 125 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, 126 drm_tv_subconnector_enum_list) 127 128 static struct drm_prop_enum_list drm_dirty_info_enum_list[] = { 129 { DRM_MODE_DIRTY_OFF, "Off" }, 130 { DRM_MODE_DIRTY_ON, "On" }, 131 { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, 132 }; 133 134 DRM_ENUM_NAME_FN(drm_get_dirty_info_name, 135 drm_dirty_info_enum_list) 136 137 struct drm_conn_prop_enum_list { 138 int type; 139 char *name; 140 int count; 141 }; 142 143 /* 144 * Connector and encoder types. 145 */ 146 static struct drm_conn_prop_enum_list drm_connector_enum_list[] = 147 { { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 }, 148 { DRM_MODE_CONNECTOR_VGA, "VGA", 0 }, 149 { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 }, 150 { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 }, 151 { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 }, 152 { DRM_MODE_CONNECTOR_Composite, "Composite", 0 }, 153 { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, 154 { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, 155 { DRM_MODE_CONNECTOR_Component, "Component", 0 }, 156 { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 }, 157 { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, 158 { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, 159 { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, 160 { DRM_MODE_CONNECTOR_TV, "TV", 0 }, 161 }; 162 163 static struct drm_prop_enum_list drm_encoder_enum_list[] = 164 { { DRM_MODE_ENCODER_NONE, "None" }, 165 { DRM_MODE_ENCODER_DAC, "DAC" }, 166 { DRM_MODE_ENCODER_TMDS, "TMDS" }, 167 { DRM_MODE_ENCODER_LVDS, "LVDS" }, 168 { DRM_MODE_ENCODER_TVDAC, "TV" }, 169 }; 170 171 char *drm_get_encoder_name(struct drm_encoder *encoder) 172 { 173 static char buf[32]; 174 175 snprintf(buf, 32, "%s-%d", 176 drm_encoder_enum_list[encoder->encoder_type].name, 177 encoder->base.id); 178 return buf; 179 } 180 EXPORT_SYMBOL(drm_get_encoder_name); 181 182 char *drm_get_connector_name(struct drm_connector *connector) 183 { 184 static char buf[32]; 185 186 snprintf(buf, 32, "%s-%d", 187 drm_connector_enum_list[connector->connector_type].name, 188 connector->connector_type_id); 189 return buf; 190 } 191 EXPORT_SYMBOL(drm_get_connector_name); 192 193 char *drm_get_connector_status_name(enum drm_connector_status status) 194 { 195 if (status == connector_status_connected) 196 return "connected"; 197 else if (status == connector_status_disconnected) 198 return "disconnected"; 199 else 200 return "unknown"; 201 } 202 203 /** 204 * drm_mode_object_get - allocate a new identifier 205 * @dev: DRM device 206 * @ptr: object pointer, used to generate unique ID 207 * @type: object type 208 * 209 * LOCKING: 210 * 211 * Create a unique identifier based on @ptr in @dev's identifier space. Used 212 * for tracking modes, CRTCs and connectors. 213 * 214 * RETURNS: 215 * New unique (relative to other objects in @dev) integer identifier for the 216 * object. 217 */ 218 static int drm_mode_object_get(struct drm_device *dev, 219 struct drm_mode_object *obj, uint32_t obj_type) 220 { 221 int new_id = 0; 222 int ret; 223 224 again: 225 if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { 226 DRM_ERROR("Ran out memory getting a mode number\n"); 227 return -EINVAL; 228 } 229 230 mutex_lock(&dev->mode_config.idr_mutex); 231 ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); 232 mutex_unlock(&dev->mode_config.idr_mutex); 233 if (ret == -EAGAIN) 234 goto again; 235 236 obj->id = new_id; 237 obj->type = obj_type; 238 return 0; 239 } 240 241 /** 242 * drm_mode_object_put - free an identifer 243 * @dev: DRM device 244 * @id: ID to free 245 * 246 * LOCKING: 247 * Caller must hold DRM mode_config lock. 248 * 249 * Free @id from @dev's unique identifier pool. 250 */ 251 static void drm_mode_object_put(struct drm_device *dev, 252 struct drm_mode_object *object) 253 { 254 mutex_lock(&dev->mode_config.idr_mutex); 255 idr_remove(&dev->mode_config.crtc_idr, object->id); 256 mutex_unlock(&dev->mode_config.idr_mutex); 257 } 258 259 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 260 uint32_t id, uint32_t type) 261 { 262 struct drm_mode_object *obj = NULL; 263 264 mutex_lock(&dev->mode_config.idr_mutex); 265 obj = idr_find(&dev->mode_config.crtc_idr, id); 266 if (!obj || (obj->type != type) || (obj->id != id)) 267 obj = NULL; 268 mutex_unlock(&dev->mode_config.idr_mutex); 269 270 return obj; 271 } 272 EXPORT_SYMBOL(drm_mode_object_find); 273 274 /** 275 * drm_framebuffer_init - initialize a framebuffer 276 * @dev: DRM device 277 * 278 * LOCKING: 279 * Caller must hold mode config lock. 280 * 281 * Allocates an ID for the framebuffer's parent mode object, sets its mode 282 * functions & device file and adds it to the master fd list. 283 * 284 * RETURNS: 285 * Zero on success, error code on failure. 286 */ 287 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, 288 const struct drm_framebuffer_funcs *funcs) 289 { 290 int ret; 291 292 ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); 293 if (ret) { 294 return ret; 295 } 296 297 fb->dev = dev; 298 fb->funcs = funcs; 299 dev->mode_config.num_fb++; 300 list_add(&fb->head, &dev->mode_config.fb_list); 301 302 return 0; 303 } 304 EXPORT_SYMBOL(drm_framebuffer_init); 305 306 /** 307 * drm_framebuffer_cleanup - remove a framebuffer object 308 * @fb: framebuffer to remove 309 * 310 * LOCKING: 311 * Caller must hold mode config lock. 312 * 313 * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes 314 * it, setting it to NULL. 315 */ 316 void drm_framebuffer_cleanup(struct drm_framebuffer *fb) 317 { 318 struct drm_device *dev = fb->dev; 319 struct drm_crtc *crtc; 320 struct drm_mode_set set; 321 int ret; 322 323 /* remove from any CRTC */ 324 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 325 if (crtc->fb == fb) { 326 /* should turn off the crtc */ 327 memset(&set, 0, sizeof(struct drm_mode_set)); 328 set.crtc = crtc; 329 set.fb = NULL; 330 ret = crtc->funcs->set_config(&set); 331 if (ret) 332 DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); 333 } 334 } 335 336 drm_mode_object_put(dev, &fb->base); 337 list_del(&fb->head); 338 dev->mode_config.num_fb--; 339 } 340 EXPORT_SYMBOL(drm_framebuffer_cleanup); 341 342 /** 343 * drm_crtc_init - Initialise a new CRTC object 344 * @dev: DRM device 345 * @crtc: CRTC object to init 346 * @funcs: callbacks for the new CRTC 347 * 348 * LOCKING: 349 * Caller must hold mode config lock. 350 * 351 * Inits a new object created as base part of an driver crtc object. 352 */ 353 void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 354 const struct drm_crtc_funcs *funcs) 355 { 356 crtc->dev = dev; 357 crtc->funcs = funcs; 358 359 mutex_lock(&dev->mode_config.mutex); 360 drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); 361 362 list_add_tail(&crtc->head, &dev->mode_config.crtc_list); 363 dev->mode_config.num_crtc++; 364 mutex_unlock(&dev->mode_config.mutex); 365 } 366 EXPORT_SYMBOL(drm_crtc_init); 367 368 /** 369 * drm_crtc_cleanup - Cleans up the core crtc usage. 370 * @crtc: CRTC to cleanup 371 * 372 * LOCKING: 373 * Caller must hold mode config lock. 374 * 375 * Cleanup @crtc. Removes from drm modesetting space 376 * does NOT free object, caller does that. 377 */ 378 void drm_crtc_cleanup(struct drm_crtc *crtc) 379 { 380 struct drm_device *dev = crtc->dev; 381 382 if (crtc->gamma_store) { 383 kfree(crtc->gamma_store); 384 crtc->gamma_store = NULL; 385 } 386 387 drm_mode_object_put(dev, &crtc->base); 388 list_del(&crtc->head); 389 dev->mode_config.num_crtc--; 390 } 391 EXPORT_SYMBOL(drm_crtc_cleanup); 392 393 /** 394 * drm_mode_probed_add - add a mode to a connector's probed mode list 395 * @connector: connector the new mode 396 * @mode: mode data 397 * 398 * LOCKING: 399 * Caller must hold mode config lock. 400 * 401 * Add @mode to @connector's mode list for later use. 402 */ 403 void drm_mode_probed_add(struct drm_connector *connector, 404 struct drm_display_mode *mode) 405 { 406 list_add(&mode->head, &connector->probed_modes); 407 } 408 EXPORT_SYMBOL(drm_mode_probed_add); 409 410 /** 411 * drm_mode_remove - remove and free a mode 412 * @connector: connector list to modify 413 * @mode: mode to remove 414 * 415 * LOCKING: 416 * Caller must hold mode config lock. 417 * 418 * Remove @mode from @connector's mode list, then free it. 419 */ 420 void drm_mode_remove(struct drm_connector *connector, 421 struct drm_display_mode *mode) 422 { 423 list_del(&mode->head); 424 kfree(mode); 425 } 426 EXPORT_SYMBOL(drm_mode_remove); 427 428 /** 429 * drm_connector_init - Init a preallocated connector 430 * @dev: DRM device 431 * @connector: the connector to init 432 * @funcs: callbacks for this connector 433 * @name: user visible name of the connector 434 * 435 * LOCKING: 436 * Caller must hold @dev's mode_config lock. 437 * 438 * Initialises a preallocated connector. Connectors should be 439 * subclassed as part of driver connector objects. 440 */ 441 void drm_connector_init(struct drm_device *dev, 442 struct drm_connector *connector, 443 const struct drm_connector_funcs *funcs, 444 int connector_type) 445 { 446 mutex_lock(&dev->mode_config.mutex); 447 448 connector->dev = dev; 449 connector->funcs = funcs; 450 drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); 451 connector->connector_type = connector_type; 452 connector->connector_type_id = 453 ++drm_connector_enum_list[connector_type].count; /* TODO */ 454 INIT_LIST_HEAD(&connector->user_modes); 455 INIT_LIST_HEAD(&connector->probed_modes); 456 INIT_LIST_HEAD(&connector->modes); 457 connector->edid_blob_ptr = NULL; 458 459 list_add_tail(&connector->head, &dev->mode_config.connector_list); 460 dev->mode_config.num_connector++; 461 462 drm_connector_attach_property(connector, 463 dev->mode_config.edid_property, 0); 464 465 drm_connector_attach_property(connector, 466 dev->mode_config.dpms_property, 0); 467 468 mutex_unlock(&dev->mode_config.mutex); 469 } 470 EXPORT_SYMBOL(drm_connector_init); 471 472 /** 473 * drm_connector_cleanup - cleans up an initialised connector 474 * @connector: connector to cleanup 475 * 476 * LOCKING: 477 * Caller must hold @dev's mode_config lock. 478 * 479 * Cleans up the connector but doesn't free the object. 480 */ 481 void drm_connector_cleanup(struct drm_connector *connector) 482 { 483 struct drm_device *dev = connector->dev; 484 struct drm_display_mode *mode, *t; 485 486 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) 487 drm_mode_remove(connector, mode); 488 489 list_for_each_entry_safe(mode, t, &connector->modes, head) 490 drm_mode_remove(connector, mode); 491 492 list_for_each_entry_safe(mode, t, &connector->user_modes, head) 493 drm_mode_remove(connector, mode); 494 495 kfree(connector->fb_helper_private); 496 mutex_lock(&dev->mode_config.mutex); 497 drm_mode_object_put(dev, &connector->base); 498 list_del(&connector->head); 499 mutex_unlock(&dev->mode_config.mutex); 500 } 501 EXPORT_SYMBOL(drm_connector_cleanup); 502 503 void drm_encoder_init(struct drm_device *dev, 504 struct drm_encoder *encoder, 505 const struct drm_encoder_funcs *funcs, 506 int encoder_type) 507 { 508 mutex_lock(&dev->mode_config.mutex); 509 510 encoder->dev = dev; 511 512 drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); 513 encoder->encoder_type = encoder_type; 514 encoder->funcs = funcs; 515 516 list_add_tail(&encoder->head, &dev->mode_config.encoder_list); 517 dev->mode_config.num_encoder++; 518 519 mutex_unlock(&dev->mode_config.mutex); 520 } 521 EXPORT_SYMBOL(drm_encoder_init); 522 523 void drm_encoder_cleanup(struct drm_encoder *encoder) 524 { 525 struct drm_device *dev = encoder->dev; 526 mutex_lock(&dev->mode_config.mutex); 527 drm_mode_object_put(dev, &encoder->base); 528 list_del(&encoder->head); 529 mutex_unlock(&dev->mode_config.mutex); 530 } 531 EXPORT_SYMBOL(drm_encoder_cleanup); 532 533 /** 534 * drm_mode_create - create a new display mode 535 * @dev: DRM device 536 * 537 * LOCKING: 538 * Caller must hold DRM mode_config lock. 539 * 540 * Create a new drm_display_mode, give it an ID, and return it. 541 * 542 * RETURNS: 543 * Pointer to new mode on success, NULL on error. 544 */ 545 struct drm_display_mode *drm_mode_create(struct drm_device *dev) 546 { 547 struct drm_display_mode *nmode; 548 549 nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL); 550 if (!nmode) 551 return NULL; 552 553 drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE); 554 return nmode; 555 } 556 EXPORT_SYMBOL(drm_mode_create); 557 558 /** 559 * drm_mode_destroy - remove a mode 560 * @dev: DRM device 561 * @mode: mode to remove 562 * 563 * LOCKING: 564 * Caller must hold mode config lock. 565 * 566 * Free @mode's unique identifier, then free it. 567 */ 568 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode) 569 { 570 drm_mode_object_put(dev, &mode->base); 571 572 kfree(mode); 573 } 574 EXPORT_SYMBOL(drm_mode_destroy); 575 576 static int drm_mode_create_standard_connector_properties(struct drm_device *dev) 577 { 578 struct drm_property *edid; 579 struct drm_property *dpms; 580 int i; 581 582 /* 583 * Standard properties (apply to all connectors) 584 */ 585 edid = drm_property_create(dev, DRM_MODE_PROP_BLOB | 586 DRM_MODE_PROP_IMMUTABLE, 587 "EDID", 0); 588 dev->mode_config.edid_property = edid; 589 590 dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM, 591 "DPMS", ARRAY_SIZE(drm_dpms_enum_list)); 592 for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++) 593 drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type, 594 drm_dpms_enum_list[i].name); 595 dev->mode_config.dpms_property = dpms; 596 597 return 0; 598 } 599 600 /** 601 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties 602 * @dev: DRM device 603 * 604 * Called by a driver the first time a DVI-I connector is made. 605 */ 606 int drm_mode_create_dvi_i_properties(struct drm_device *dev) 607 { 608 struct drm_property *dvi_i_selector; 609 struct drm_property *dvi_i_subconnector; 610 int i; 611 612 if (dev->mode_config.dvi_i_select_subconnector_property) 613 return 0; 614 615 dvi_i_selector = 616 drm_property_create(dev, DRM_MODE_PROP_ENUM, 617 "select subconnector", 618 ARRAY_SIZE(drm_dvi_i_select_enum_list)); 619 for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++) 620 drm_property_add_enum(dvi_i_selector, i, 621 drm_dvi_i_select_enum_list[i].type, 622 drm_dvi_i_select_enum_list[i].name); 623 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; 624 625 dvi_i_subconnector = 626 drm_property_create(dev, DRM_MODE_PROP_ENUM | 627 DRM_MODE_PROP_IMMUTABLE, 628 "subconnector", 629 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); 630 for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++) 631 drm_property_add_enum(dvi_i_subconnector, i, 632 drm_dvi_i_subconnector_enum_list[i].type, 633 drm_dvi_i_subconnector_enum_list[i].name); 634 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; 635 636 return 0; 637 } 638 EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); 639 640 /** 641 * drm_create_tv_properties - create TV specific connector properties 642 * @dev: DRM device 643 * @num_modes: number of different TV formats (modes) supported 644 * @modes: array of pointers to strings containing name of each format 645 * 646 * Called by a driver's TV initialization routine, this function creates 647 * the TV specific connector properties for a given device. Caller is 648 * responsible for allocating a list of format names and passing them to 649 * this routine. 650 */ 651 int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, 652 char *modes[]) 653 { 654 struct drm_property *tv_selector; 655 struct drm_property *tv_subconnector; 656 int i; 657 658 if (dev->mode_config.tv_select_subconnector_property) 659 return 0; 660 661 /* 662 * Basic connector properties 663 */ 664 tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM, 665 "select subconnector", 666 ARRAY_SIZE(drm_tv_select_enum_list)); 667 for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++) 668 drm_property_add_enum(tv_selector, i, 669 drm_tv_select_enum_list[i].type, 670 drm_tv_select_enum_list[i].name); 671 dev->mode_config.tv_select_subconnector_property = tv_selector; 672 673 tv_subconnector = 674 drm_property_create(dev, DRM_MODE_PROP_ENUM | 675 DRM_MODE_PROP_IMMUTABLE, "subconnector", 676 ARRAY_SIZE(drm_tv_subconnector_enum_list)); 677 for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++) 678 drm_property_add_enum(tv_subconnector, i, 679 drm_tv_subconnector_enum_list[i].type, 680 drm_tv_subconnector_enum_list[i].name); 681 dev->mode_config.tv_subconnector_property = tv_subconnector; 682 683 /* 684 * Other, TV specific properties: margins & TV modes. 685 */ 686 dev->mode_config.tv_left_margin_property = 687 drm_property_create(dev, DRM_MODE_PROP_RANGE, 688 "left margin", 2); 689 dev->mode_config.tv_left_margin_property->values[0] = 0; 690 dev->mode_config.tv_left_margin_property->values[1] = 100; 691 692 dev->mode_config.tv_right_margin_property = 693 drm_property_create(dev, DRM_MODE_PROP_RANGE, 694 "right margin", 2); 695 dev->mode_config.tv_right_margin_property->values[0] = 0; 696 dev->mode_config.tv_right_margin_property->values[1] = 100; 697 698 dev->mode_config.tv_top_margin_property = 699 drm_property_create(dev, DRM_MODE_PROP_RANGE, 700 "top margin", 2); 701 dev->mode_config.tv_top_margin_property->values[0] = 0; 702 dev->mode_config.tv_top_margin_property->values[1] = 100; 703 704 dev->mode_config.tv_bottom_margin_property = 705 drm_property_create(dev, DRM_MODE_PROP_RANGE, 706 "bottom margin", 2); 707 dev->mode_config.tv_bottom_margin_property->values[0] = 0; 708 dev->mode_config.tv_bottom_margin_property->values[1] = 100; 709 710 dev->mode_config.tv_mode_property = 711 drm_property_create(dev, DRM_MODE_PROP_ENUM, 712 "mode", num_modes); 713 for (i = 0; i < num_modes; i++) 714 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 715 i, modes[i]); 716 717 dev->mode_config.tv_brightness_property = 718 drm_property_create(dev, DRM_MODE_PROP_RANGE, 719 "brightness", 2); 720 dev->mode_config.tv_brightness_property->values[0] = 0; 721 dev->mode_config.tv_brightness_property->values[1] = 100; 722 723 dev->mode_config.tv_contrast_property = 724 drm_property_create(dev, DRM_MODE_PROP_RANGE, 725 "contrast", 2); 726 dev->mode_config.tv_contrast_property->values[0] = 0; 727 dev->mode_config.tv_contrast_property->values[1] = 100; 728 729 dev->mode_config.tv_flicker_reduction_property = 730 drm_property_create(dev, DRM_MODE_PROP_RANGE, 731 "flicker reduction", 2); 732 dev->mode_config.tv_flicker_reduction_property->values[0] = 0; 733 dev->mode_config.tv_flicker_reduction_property->values[1] = 100; 734 735 dev->mode_config.tv_overscan_property = 736 drm_property_create(dev, DRM_MODE_PROP_RANGE, 737 "overscan", 2); 738 dev->mode_config.tv_overscan_property->values[0] = 0; 739 dev->mode_config.tv_overscan_property->values[1] = 100; 740 741 dev->mode_config.tv_saturation_property = 742 drm_property_create(dev, DRM_MODE_PROP_RANGE, 743 "saturation", 2); 744 dev->mode_config.tv_saturation_property->values[0] = 0; 745 dev->mode_config.tv_saturation_property->values[1] = 100; 746 747 dev->mode_config.tv_hue_property = 748 drm_property_create(dev, DRM_MODE_PROP_RANGE, 749 "hue", 2); 750 dev->mode_config.tv_hue_property->values[0] = 0; 751 dev->mode_config.tv_hue_property->values[1] = 100; 752 753 return 0; 754 } 755 EXPORT_SYMBOL(drm_mode_create_tv_properties); 756 757 /** 758 * drm_mode_create_scaling_mode_property - create scaling mode property 759 * @dev: DRM device 760 * 761 * Called by a driver the first time it's needed, must be attached to desired 762 * connectors. 763 */ 764 int drm_mode_create_scaling_mode_property(struct drm_device *dev) 765 { 766 struct drm_property *scaling_mode; 767 int i; 768 769 if (dev->mode_config.scaling_mode_property) 770 return 0; 771 772 scaling_mode = 773 drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode", 774 ARRAY_SIZE(drm_scaling_mode_enum_list)); 775 for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) 776 drm_property_add_enum(scaling_mode, i, 777 drm_scaling_mode_enum_list[i].type, 778 drm_scaling_mode_enum_list[i].name); 779 780 dev->mode_config.scaling_mode_property = scaling_mode; 781 782 return 0; 783 } 784 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); 785 786 /** 787 * drm_mode_create_dithering_property - create dithering property 788 * @dev: DRM device 789 * 790 * Called by a driver the first time it's needed, must be attached to desired 791 * connectors. 792 */ 793 int drm_mode_create_dithering_property(struct drm_device *dev) 794 { 795 struct drm_property *dithering_mode; 796 int i; 797 798 if (dev->mode_config.dithering_mode_property) 799 return 0; 800 801 dithering_mode = 802 drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering", 803 ARRAY_SIZE(drm_dithering_mode_enum_list)); 804 for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++) 805 drm_property_add_enum(dithering_mode, i, 806 drm_dithering_mode_enum_list[i].type, 807 drm_dithering_mode_enum_list[i].name); 808 dev->mode_config.dithering_mode_property = dithering_mode; 809 810 return 0; 811 } 812 EXPORT_SYMBOL(drm_mode_create_dithering_property); 813 814 /** 815 * drm_mode_create_dirty_property - create dirty property 816 * @dev: DRM device 817 * 818 * Called by a driver the first time it's needed, must be attached to desired 819 * connectors. 820 */ 821 int drm_mode_create_dirty_info_property(struct drm_device *dev) 822 { 823 struct drm_property *dirty_info; 824 int i; 825 826 if (dev->mode_config.dirty_info_property) 827 return 0; 828 829 dirty_info = 830 drm_property_create(dev, DRM_MODE_PROP_ENUM | 831 DRM_MODE_PROP_IMMUTABLE, 832 "dirty", 833 ARRAY_SIZE(drm_dirty_info_enum_list)); 834 for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++) 835 drm_property_add_enum(dirty_info, i, 836 drm_dirty_info_enum_list[i].type, 837 drm_dirty_info_enum_list[i].name); 838 dev->mode_config.dirty_info_property = dirty_info; 839 840 return 0; 841 } 842 EXPORT_SYMBOL(drm_mode_create_dirty_info_property); 843 844 /** 845 * drm_mode_config_init - initialize DRM mode_configuration structure 846 * @dev: DRM device 847 * 848 * LOCKING: 849 * None, should happen single threaded at init time. 850 * 851 * Initialize @dev's mode_config structure, used for tracking the graphics 852 * configuration of @dev. 853 */ 854 void drm_mode_config_init(struct drm_device *dev) 855 { 856 mutex_init(&dev->mode_config.mutex); 857 mutex_init(&dev->mode_config.idr_mutex); 858 INIT_LIST_HEAD(&dev->mode_config.fb_list); 859 INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list); 860 INIT_LIST_HEAD(&dev->mode_config.crtc_list); 861 INIT_LIST_HEAD(&dev->mode_config.connector_list); 862 INIT_LIST_HEAD(&dev->mode_config.encoder_list); 863 INIT_LIST_HEAD(&dev->mode_config.property_list); 864 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 865 idr_init(&dev->mode_config.crtc_idr); 866 867 mutex_lock(&dev->mode_config.mutex); 868 drm_mode_create_standard_connector_properties(dev); 869 mutex_unlock(&dev->mode_config.mutex); 870 871 /* Just to be sure */ 872 dev->mode_config.num_fb = 0; 873 dev->mode_config.num_connector = 0; 874 dev->mode_config.num_crtc = 0; 875 dev->mode_config.num_encoder = 0; 876 } 877 EXPORT_SYMBOL(drm_mode_config_init); 878 879 int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) 880 { 881 uint32_t total_objects = 0; 882 883 total_objects += dev->mode_config.num_crtc; 884 total_objects += dev->mode_config.num_connector; 885 total_objects += dev->mode_config.num_encoder; 886 887 if (total_objects == 0) 888 return -EINVAL; 889 890 group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); 891 if (!group->id_list) 892 return -ENOMEM; 893 894 group->num_crtcs = 0; 895 group->num_connectors = 0; 896 group->num_encoders = 0; 897 return 0; 898 } 899 900 int drm_mode_group_init_legacy_group(struct drm_device *dev, 901 struct drm_mode_group *group) 902 { 903 struct drm_crtc *crtc; 904 struct drm_encoder *encoder; 905 struct drm_connector *connector; 906 int ret; 907 908 if ((ret = drm_mode_group_init(dev, group))) 909 return ret; 910 911 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 912 group->id_list[group->num_crtcs++] = crtc->base.id; 913 914 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 915 group->id_list[group->num_crtcs + group->num_encoders++] = 916 encoder->base.id; 917 918 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 919 group->id_list[group->num_crtcs + group->num_encoders + 920 group->num_connectors++] = connector->base.id; 921 922 return 0; 923 } 924 925 /** 926 * drm_mode_config_cleanup - free up DRM mode_config info 927 * @dev: DRM device 928 * 929 * LOCKING: 930 * Caller must hold mode config lock. 931 * 932 * Free up all the connectors and CRTCs associated with this DRM device, then 933 * free up the framebuffers and associated buffer objects. 934 * 935 * FIXME: cleanup any dangling user buffer objects too 936 */ 937 void drm_mode_config_cleanup(struct drm_device *dev) 938 { 939 struct drm_connector *connector, *ot; 940 struct drm_crtc *crtc, *ct; 941 struct drm_encoder *encoder, *enct; 942 struct drm_framebuffer *fb, *fbt; 943 struct drm_property *property, *pt; 944 945 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, 946 head) { 947 encoder->funcs->destroy(encoder); 948 } 949 950 list_for_each_entry_safe(connector, ot, 951 &dev->mode_config.connector_list, head) { 952 connector->funcs->destroy(connector); 953 } 954 955 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, 956 head) { 957 drm_property_destroy(dev, property); 958 } 959 960 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { 961 fb->funcs->destroy(fb); 962 } 963 964 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { 965 crtc->funcs->destroy(crtc); 966 } 967 968 } 969 EXPORT_SYMBOL(drm_mode_config_cleanup); 970 971 /** 972 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo 973 * @out: drm_mode_modeinfo struct to return to the user 974 * @in: drm_display_mode to use 975 * 976 * LOCKING: 977 * None. 978 * 979 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to 980 * the user. 981 */ 982 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, 983 struct drm_display_mode *in) 984 { 985 out->clock = in->clock; 986 out->hdisplay = in->hdisplay; 987 out->hsync_start = in->hsync_start; 988 out->hsync_end = in->hsync_end; 989 out->htotal = in->htotal; 990 out->hskew = in->hskew; 991 out->vdisplay = in->vdisplay; 992 out->vsync_start = in->vsync_start; 993 out->vsync_end = in->vsync_end; 994 out->vtotal = in->vtotal; 995 out->vscan = in->vscan; 996 out->vrefresh = in->vrefresh; 997 out->flags = in->flags; 998 out->type = in->type; 999 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1000 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1001 } 1002 1003 /** 1004 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode 1005 * @out: drm_display_mode to return to the user 1006 * @in: drm_mode_modeinfo to use 1007 * 1008 * LOCKING: 1009 * None. 1010 * 1011 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to 1012 * the caller. 1013 */ 1014 void drm_crtc_convert_umode(struct drm_display_mode *out, 1015 struct drm_mode_modeinfo *in) 1016 { 1017 out->clock = in->clock; 1018 out->hdisplay = in->hdisplay; 1019 out->hsync_start = in->hsync_start; 1020 out->hsync_end = in->hsync_end; 1021 out->htotal = in->htotal; 1022 out->hskew = in->hskew; 1023 out->vdisplay = in->vdisplay; 1024 out->vsync_start = in->vsync_start; 1025 out->vsync_end = in->vsync_end; 1026 out->vtotal = in->vtotal; 1027 out->vscan = in->vscan; 1028 out->vrefresh = in->vrefresh; 1029 out->flags = in->flags; 1030 out->type = in->type; 1031 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1032 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1033 } 1034 1035 /** 1036 * drm_mode_getresources - get graphics configuration 1037 * @inode: inode from the ioctl 1038 * @filp: file * from the ioctl 1039 * @cmd: cmd from ioctl 1040 * @arg: arg from ioctl 1041 * 1042 * LOCKING: 1043 * Takes mode config lock. 1044 * 1045 * Construct a set of configuration description structures and return 1046 * them to the user, including CRTC, connector and framebuffer configuration. 1047 * 1048 * Called by the user via ioctl. 1049 * 1050 * RETURNS: 1051 * Zero on success, errno on failure. 1052 */ 1053 int drm_mode_getresources(struct drm_device *dev, void *data, 1054 struct drm_file *file_priv) 1055 { 1056 struct drm_mode_card_res *card_res = data; 1057 struct list_head *lh; 1058 struct drm_framebuffer *fb; 1059 struct drm_connector *connector; 1060 struct drm_crtc *crtc; 1061 struct drm_encoder *encoder; 1062 int ret = 0; 1063 int connector_count = 0; 1064 int crtc_count = 0; 1065 int fb_count = 0; 1066 int encoder_count = 0; 1067 int copied = 0, i; 1068 uint32_t __user *fb_id; 1069 uint32_t __user *crtc_id; 1070 uint32_t __user *connector_id; 1071 uint32_t __user *encoder_id; 1072 struct drm_mode_group *mode_group; 1073 1074 mutex_lock(&dev->mode_config.mutex); 1075 1076 /* 1077 * For the non-control nodes we need to limit the list of resources 1078 * by IDs in the group list for this node 1079 */ 1080 list_for_each(lh, &file_priv->fbs) 1081 fb_count++; 1082 1083 mode_group = &file_priv->master->minor->mode_group; 1084 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1085 1086 list_for_each(lh, &dev->mode_config.crtc_list) 1087 crtc_count++; 1088 1089 list_for_each(lh, &dev->mode_config.connector_list) 1090 connector_count++; 1091 1092 list_for_each(lh, &dev->mode_config.encoder_list) 1093 encoder_count++; 1094 } else { 1095 1096 crtc_count = mode_group->num_crtcs; 1097 connector_count = mode_group->num_connectors; 1098 encoder_count = mode_group->num_encoders; 1099 } 1100 1101 card_res->max_height = dev->mode_config.max_height; 1102 card_res->min_height = dev->mode_config.min_height; 1103 card_res->max_width = dev->mode_config.max_width; 1104 card_res->min_width = dev->mode_config.min_width; 1105 1106 /* handle this in 4 parts */ 1107 /* FBs */ 1108 if (card_res->count_fbs >= fb_count) { 1109 copied = 0; 1110 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; 1111 list_for_each_entry(fb, &file_priv->fbs, head) { 1112 if (put_user(fb->base.id, fb_id + copied)) { 1113 ret = -EFAULT; 1114 goto out; 1115 } 1116 copied++; 1117 } 1118 } 1119 card_res->count_fbs = fb_count; 1120 1121 /* CRTCs */ 1122 if (card_res->count_crtcs >= crtc_count) { 1123 copied = 0; 1124 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; 1125 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1126 list_for_each_entry(crtc, &dev->mode_config.crtc_list, 1127 head) { 1128 DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id); 1129 if (put_user(crtc->base.id, crtc_id + copied)) { 1130 ret = -EFAULT; 1131 goto out; 1132 } 1133 copied++; 1134 } 1135 } else { 1136 for (i = 0; i < mode_group->num_crtcs; i++) { 1137 if (put_user(mode_group->id_list[i], 1138 crtc_id + copied)) { 1139 ret = -EFAULT; 1140 goto out; 1141 } 1142 copied++; 1143 } 1144 } 1145 } 1146 card_res->count_crtcs = crtc_count; 1147 1148 /* Encoders */ 1149 if (card_res->count_encoders >= encoder_count) { 1150 copied = 0; 1151 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; 1152 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1153 list_for_each_entry(encoder, 1154 &dev->mode_config.encoder_list, 1155 head) { 1156 DRM_DEBUG_KMS("ENCODER ID is %d\n", 1157 encoder->base.id); 1158 if (put_user(encoder->base.id, encoder_id + 1159 copied)) { 1160 ret = -EFAULT; 1161 goto out; 1162 } 1163 copied++; 1164 } 1165 } else { 1166 for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) { 1167 if (put_user(mode_group->id_list[i], 1168 encoder_id + copied)) { 1169 ret = -EFAULT; 1170 goto out; 1171 } 1172 copied++; 1173 } 1174 1175 } 1176 } 1177 card_res->count_encoders = encoder_count; 1178 1179 /* Connectors */ 1180 if (card_res->count_connectors >= connector_count) { 1181 copied = 0; 1182 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; 1183 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1184 list_for_each_entry(connector, 1185 &dev->mode_config.connector_list, 1186 head) { 1187 DRM_DEBUG_KMS("CONNECTOR ID is %d\n", 1188 connector->base.id); 1189 if (put_user(connector->base.id, 1190 connector_id + copied)) { 1191 ret = -EFAULT; 1192 goto out; 1193 } 1194 copied++; 1195 } 1196 } else { 1197 int start = mode_group->num_crtcs + 1198 mode_group->num_encoders; 1199 for (i = start; i < start + mode_group->num_connectors; i++) { 1200 if (put_user(mode_group->id_list[i], 1201 connector_id + copied)) { 1202 ret = -EFAULT; 1203 goto out; 1204 } 1205 copied++; 1206 } 1207 } 1208 } 1209 card_res->count_connectors = connector_count; 1210 1211 DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs, 1212 card_res->count_connectors, card_res->count_encoders); 1213 1214 out: 1215 mutex_unlock(&dev->mode_config.mutex); 1216 return ret; 1217 } 1218 1219 /** 1220 * drm_mode_getcrtc - get CRTC configuration 1221 * @inode: inode from the ioctl 1222 * @filp: file * from the ioctl 1223 * @cmd: cmd from ioctl 1224 * @arg: arg from ioctl 1225 * 1226 * LOCKING: 1227 * Caller? (FIXME) 1228 * 1229 * Construct a CRTC configuration structure to return to the user. 1230 * 1231 * Called by the user via ioctl. 1232 * 1233 * RETURNS: 1234 * Zero on success, errno on failure. 1235 */ 1236 int drm_mode_getcrtc(struct drm_device *dev, 1237 void *data, struct drm_file *file_priv) 1238 { 1239 struct drm_mode_crtc *crtc_resp = data; 1240 struct drm_crtc *crtc; 1241 struct drm_mode_object *obj; 1242 int ret = 0; 1243 1244 mutex_lock(&dev->mode_config.mutex); 1245 1246 obj = drm_mode_object_find(dev, crtc_resp->crtc_id, 1247 DRM_MODE_OBJECT_CRTC); 1248 if (!obj) { 1249 ret = -EINVAL; 1250 goto out; 1251 } 1252 crtc = obj_to_crtc(obj); 1253 1254 crtc_resp->x = crtc->x; 1255 crtc_resp->y = crtc->y; 1256 crtc_resp->gamma_size = crtc->gamma_size; 1257 if (crtc->fb) 1258 crtc_resp->fb_id = crtc->fb->base.id; 1259 else 1260 crtc_resp->fb_id = 0; 1261 1262 if (crtc->enabled) { 1263 1264 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); 1265 crtc_resp->mode_valid = 1; 1266 1267 } else { 1268 crtc_resp->mode_valid = 0; 1269 } 1270 1271 out: 1272 mutex_unlock(&dev->mode_config.mutex); 1273 return ret; 1274 } 1275 1276 /** 1277 * drm_mode_getconnector - get connector configuration 1278 * @inode: inode from the ioctl 1279 * @filp: file * from the ioctl 1280 * @cmd: cmd from ioctl 1281 * @arg: arg from ioctl 1282 * 1283 * LOCKING: 1284 * Caller? (FIXME) 1285 * 1286 * Construct a connector configuration structure to return to the user. 1287 * 1288 * Called by the user via ioctl. 1289 * 1290 * RETURNS: 1291 * Zero on success, errno on failure. 1292 */ 1293 int drm_mode_getconnector(struct drm_device *dev, void *data, 1294 struct drm_file *file_priv) 1295 { 1296 struct drm_mode_get_connector *out_resp = data; 1297 struct drm_mode_object *obj; 1298 struct drm_connector *connector; 1299 struct drm_display_mode *mode; 1300 int mode_count = 0; 1301 int props_count = 0; 1302 int encoders_count = 0; 1303 int ret = 0; 1304 int copied = 0; 1305 int i; 1306 struct drm_mode_modeinfo u_mode; 1307 struct drm_mode_modeinfo __user *mode_ptr; 1308 uint32_t __user *prop_ptr; 1309 uint64_t __user *prop_values; 1310 uint32_t __user *encoder_ptr; 1311 1312 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1313 1314 DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id); 1315 1316 mutex_lock(&dev->mode_config.mutex); 1317 1318 obj = drm_mode_object_find(dev, out_resp->connector_id, 1319 DRM_MODE_OBJECT_CONNECTOR); 1320 if (!obj) { 1321 ret = -EINVAL; 1322 goto out; 1323 } 1324 connector = obj_to_connector(obj); 1325 1326 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1327 if (connector->property_ids[i] != 0) { 1328 props_count++; 1329 } 1330 } 1331 1332 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1333 if (connector->encoder_ids[i] != 0) { 1334 encoders_count++; 1335 } 1336 } 1337 1338 if (out_resp->count_modes == 0) { 1339 connector->funcs->fill_modes(connector, 1340 dev->mode_config.max_width, 1341 dev->mode_config.max_height); 1342 } 1343 1344 /* delayed so we get modes regardless of pre-fill_modes state */ 1345 list_for_each_entry(mode, &connector->modes, head) 1346 mode_count++; 1347 1348 out_resp->connector_id = connector->base.id; 1349 out_resp->connector_type = connector->connector_type; 1350 out_resp->connector_type_id = connector->connector_type_id; 1351 out_resp->mm_width = connector->display_info.width_mm; 1352 out_resp->mm_height = connector->display_info.height_mm; 1353 out_resp->subpixel = connector->display_info.subpixel_order; 1354 out_resp->connection = connector->status; 1355 if (connector->encoder) 1356 out_resp->encoder_id = connector->encoder->base.id; 1357 else 1358 out_resp->encoder_id = 0; 1359 1360 /* 1361 * This ioctl is called twice, once to determine how much space is 1362 * needed, and the 2nd time to fill it. 1363 */ 1364 if ((out_resp->count_modes >= mode_count) && mode_count) { 1365 copied = 0; 1366 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr; 1367 list_for_each_entry(mode, &connector->modes, head) { 1368 drm_crtc_convert_to_umode(&u_mode, mode); 1369 if (copy_to_user(mode_ptr + copied, 1370 &u_mode, sizeof(u_mode))) { 1371 ret = -EFAULT; 1372 goto out; 1373 } 1374 copied++; 1375 } 1376 } 1377 out_resp->count_modes = mode_count; 1378 1379 if ((out_resp->count_props >= props_count) && props_count) { 1380 copied = 0; 1381 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr); 1382 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr); 1383 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1384 if (connector->property_ids[i] != 0) { 1385 if (put_user(connector->property_ids[i], 1386 prop_ptr + copied)) { 1387 ret = -EFAULT; 1388 goto out; 1389 } 1390 1391 if (put_user(connector->property_values[i], 1392 prop_values + copied)) { 1393 ret = -EFAULT; 1394 goto out; 1395 } 1396 copied++; 1397 } 1398 } 1399 } 1400 out_resp->count_props = props_count; 1401 1402 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 1403 copied = 0; 1404 encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr); 1405 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1406 if (connector->encoder_ids[i] != 0) { 1407 if (put_user(connector->encoder_ids[i], 1408 encoder_ptr + copied)) { 1409 ret = -EFAULT; 1410 goto out; 1411 } 1412 copied++; 1413 } 1414 } 1415 } 1416 out_resp->count_encoders = encoders_count; 1417 1418 out: 1419 mutex_unlock(&dev->mode_config.mutex); 1420 return ret; 1421 } 1422 1423 int drm_mode_getencoder(struct drm_device *dev, void *data, 1424 struct drm_file *file_priv) 1425 { 1426 struct drm_mode_get_encoder *enc_resp = data; 1427 struct drm_mode_object *obj; 1428 struct drm_encoder *encoder; 1429 int ret = 0; 1430 1431 mutex_lock(&dev->mode_config.mutex); 1432 obj = drm_mode_object_find(dev, enc_resp->encoder_id, 1433 DRM_MODE_OBJECT_ENCODER); 1434 if (!obj) { 1435 ret = -EINVAL; 1436 goto out; 1437 } 1438 encoder = obj_to_encoder(obj); 1439 1440 if (encoder->crtc) 1441 enc_resp->crtc_id = encoder->crtc->base.id; 1442 else 1443 enc_resp->crtc_id = 0; 1444 enc_resp->encoder_type = encoder->encoder_type; 1445 enc_resp->encoder_id = encoder->base.id; 1446 enc_resp->possible_crtcs = encoder->possible_crtcs; 1447 enc_resp->possible_clones = encoder->possible_clones; 1448 1449 out: 1450 mutex_unlock(&dev->mode_config.mutex); 1451 return ret; 1452 } 1453 1454 /** 1455 * drm_mode_setcrtc - set CRTC configuration 1456 * @inode: inode from the ioctl 1457 * @filp: file * from the ioctl 1458 * @cmd: cmd from ioctl 1459 * @arg: arg from ioctl 1460 * 1461 * LOCKING: 1462 * Caller? (FIXME) 1463 * 1464 * Build a new CRTC configuration based on user request. 1465 * 1466 * Called by the user via ioctl. 1467 * 1468 * RETURNS: 1469 * Zero on success, errno on failure. 1470 */ 1471 int drm_mode_setcrtc(struct drm_device *dev, void *data, 1472 struct drm_file *file_priv) 1473 { 1474 struct drm_mode_config *config = &dev->mode_config; 1475 struct drm_mode_crtc *crtc_req = data; 1476 struct drm_mode_object *obj; 1477 struct drm_crtc *crtc, *crtcfb; 1478 struct drm_connector **connector_set = NULL, *connector; 1479 struct drm_framebuffer *fb = NULL; 1480 struct drm_display_mode *mode = NULL; 1481 struct drm_mode_set set; 1482 uint32_t __user *set_connectors_ptr; 1483 int ret = 0; 1484 int i; 1485 1486 mutex_lock(&dev->mode_config.mutex); 1487 obj = drm_mode_object_find(dev, crtc_req->crtc_id, 1488 DRM_MODE_OBJECT_CRTC); 1489 if (!obj) { 1490 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); 1491 ret = -EINVAL; 1492 goto out; 1493 } 1494 crtc = obj_to_crtc(obj); 1495 1496 if (crtc_req->mode_valid) { 1497 /* If we have a mode we need a framebuffer. */ 1498 /* If we pass -1, set the mode with the currently bound fb */ 1499 if (crtc_req->fb_id == -1) { 1500 list_for_each_entry(crtcfb, 1501 &dev->mode_config.crtc_list, head) { 1502 if (crtcfb == crtc) { 1503 DRM_DEBUG_KMS("Using current fb for " 1504 "setmode\n"); 1505 fb = crtc->fb; 1506 } 1507 } 1508 } else { 1509 obj = drm_mode_object_find(dev, crtc_req->fb_id, 1510 DRM_MODE_OBJECT_FB); 1511 if (!obj) { 1512 DRM_DEBUG_KMS("Unknown FB ID%d\n", 1513 crtc_req->fb_id); 1514 ret = -EINVAL; 1515 goto out; 1516 } 1517 fb = obj_to_fb(obj); 1518 } 1519 1520 mode = drm_mode_create(dev); 1521 drm_crtc_convert_umode(mode, &crtc_req->mode); 1522 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 1523 } 1524 1525 if (crtc_req->count_connectors == 0 && mode) { 1526 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n"); 1527 ret = -EINVAL; 1528 goto out; 1529 } 1530 1531 if (crtc_req->count_connectors > 0 && (!mode || !fb)) { 1532 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n", 1533 crtc_req->count_connectors); 1534 ret = -EINVAL; 1535 goto out; 1536 } 1537 1538 if (crtc_req->count_connectors > 0) { 1539 u32 out_id; 1540 1541 /* Avoid unbounded kernel memory allocation */ 1542 if (crtc_req->count_connectors > config->num_connector) { 1543 ret = -EINVAL; 1544 goto out; 1545 } 1546 1547 connector_set = kmalloc(crtc_req->count_connectors * 1548 sizeof(struct drm_connector *), 1549 GFP_KERNEL); 1550 if (!connector_set) { 1551 ret = -ENOMEM; 1552 goto out; 1553 } 1554 1555 for (i = 0; i < crtc_req->count_connectors; i++) { 1556 set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr; 1557 if (get_user(out_id, &set_connectors_ptr[i])) { 1558 ret = -EFAULT; 1559 goto out; 1560 } 1561 1562 obj = drm_mode_object_find(dev, out_id, 1563 DRM_MODE_OBJECT_CONNECTOR); 1564 if (!obj) { 1565 DRM_DEBUG_KMS("Connector id %d unknown\n", 1566 out_id); 1567 ret = -EINVAL; 1568 goto out; 1569 } 1570 connector = obj_to_connector(obj); 1571 1572 connector_set[i] = connector; 1573 } 1574 } 1575 1576 set.crtc = crtc; 1577 set.x = crtc_req->x; 1578 set.y = crtc_req->y; 1579 set.mode = mode; 1580 set.connectors = connector_set; 1581 set.num_connectors = crtc_req->count_connectors; 1582 set.fb = fb; 1583 ret = crtc->funcs->set_config(&set); 1584 1585 out: 1586 kfree(connector_set); 1587 mutex_unlock(&dev->mode_config.mutex); 1588 return ret; 1589 } 1590 1591 int drm_mode_cursor_ioctl(struct drm_device *dev, 1592 void *data, struct drm_file *file_priv) 1593 { 1594 struct drm_mode_cursor *req = data; 1595 struct drm_mode_object *obj; 1596 struct drm_crtc *crtc; 1597 int ret = 0; 1598 1599 if (!req->flags) { 1600 DRM_ERROR("no operation set\n"); 1601 return -EINVAL; 1602 } 1603 1604 mutex_lock(&dev->mode_config.mutex); 1605 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); 1606 if (!obj) { 1607 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 1608 ret = -EINVAL; 1609 goto out; 1610 } 1611 crtc = obj_to_crtc(obj); 1612 1613 if (req->flags & DRM_MODE_CURSOR_BO) { 1614 if (!crtc->funcs->cursor_set) { 1615 DRM_ERROR("crtc does not support cursor\n"); 1616 ret = -ENXIO; 1617 goto out; 1618 } 1619 /* Turns off the cursor if handle is 0 */ 1620 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 1621 req->width, req->height); 1622 } 1623 1624 if (req->flags & DRM_MODE_CURSOR_MOVE) { 1625 if (crtc->funcs->cursor_move) { 1626 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 1627 } else { 1628 DRM_ERROR("crtc does not support cursor\n"); 1629 ret = -EFAULT; 1630 goto out; 1631 } 1632 } 1633 out: 1634 mutex_unlock(&dev->mode_config.mutex); 1635 return ret; 1636 } 1637 1638 /** 1639 * drm_mode_addfb - add an FB to the graphics configuration 1640 * @inode: inode from the ioctl 1641 * @filp: file * from the ioctl 1642 * @cmd: cmd from ioctl 1643 * @arg: arg from ioctl 1644 * 1645 * LOCKING: 1646 * Takes mode config lock. 1647 * 1648 * Add a new FB to the specified CRTC, given a user request. 1649 * 1650 * Called by the user via ioctl. 1651 * 1652 * RETURNS: 1653 * Zero on success, errno on failure. 1654 */ 1655 int drm_mode_addfb(struct drm_device *dev, 1656 void *data, struct drm_file *file_priv) 1657 { 1658 struct drm_mode_fb_cmd *r = data; 1659 struct drm_mode_config *config = &dev->mode_config; 1660 struct drm_framebuffer *fb; 1661 int ret = 0; 1662 1663 if ((config->min_width > r->width) || (r->width > config->max_width)) { 1664 DRM_ERROR("mode new framebuffer width not within limits\n"); 1665 return -EINVAL; 1666 } 1667 if ((config->min_height > r->height) || (r->height > config->max_height)) { 1668 DRM_ERROR("mode new framebuffer height not within limits\n"); 1669 return -EINVAL; 1670 } 1671 1672 mutex_lock(&dev->mode_config.mutex); 1673 1674 /* TODO check buffer is sufficently large */ 1675 /* TODO setup destructor callback */ 1676 1677 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); 1678 if (!fb) { 1679 DRM_ERROR("could not create framebuffer\n"); 1680 ret = -EINVAL; 1681 goto out; 1682 } 1683 1684 r->fb_id = fb->base.id; 1685 list_add(&fb->filp_head, &file_priv->fbs); 1686 1687 out: 1688 mutex_unlock(&dev->mode_config.mutex); 1689 return ret; 1690 } 1691 1692 /** 1693 * drm_mode_rmfb - remove an FB from the configuration 1694 * @inode: inode from the ioctl 1695 * @filp: file * from the ioctl 1696 * @cmd: cmd from ioctl 1697 * @arg: arg from ioctl 1698 * 1699 * LOCKING: 1700 * Takes mode config lock. 1701 * 1702 * Remove the FB specified by the user. 1703 * 1704 * Called by the user via ioctl. 1705 * 1706 * RETURNS: 1707 * Zero on success, errno on failure. 1708 */ 1709 int drm_mode_rmfb(struct drm_device *dev, 1710 void *data, struct drm_file *file_priv) 1711 { 1712 struct drm_mode_object *obj; 1713 struct drm_framebuffer *fb = NULL; 1714 struct drm_framebuffer *fbl = NULL; 1715 uint32_t *id = data; 1716 int ret = 0; 1717 int found = 0; 1718 1719 mutex_lock(&dev->mode_config.mutex); 1720 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); 1721 /* TODO check that we realy get a framebuffer back. */ 1722 if (!obj) { 1723 DRM_ERROR("mode invalid framebuffer id\n"); 1724 ret = -EINVAL; 1725 goto out; 1726 } 1727 fb = obj_to_fb(obj); 1728 1729 list_for_each_entry(fbl, &file_priv->fbs, filp_head) 1730 if (fb == fbl) 1731 found = 1; 1732 1733 if (!found) { 1734 DRM_ERROR("tried to remove a fb that we didn't own\n"); 1735 ret = -EINVAL; 1736 goto out; 1737 } 1738 1739 /* TODO release all crtc connected to the framebuffer */ 1740 /* TODO unhock the destructor from the buffer object */ 1741 1742 list_del(&fb->filp_head); 1743 fb->funcs->destroy(fb); 1744 1745 out: 1746 mutex_unlock(&dev->mode_config.mutex); 1747 return ret; 1748 } 1749 1750 /** 1751 * drm_mode_getfb - get FB info 1752 * @inode: inode from the ioctl 1753 * @filp: file * from the ioctl 1754 * @cmd: cmd from ioctl 1755 * @arg: arg from ioctl 1756 * 1757 * LOCKING: 1758 * Caller? (FIXME) 1759 * 1760 * Lookup the FB given its ID and return info about it. 1761 * 1762 * Called by the user via ioctl. 1763 * 1764 * RETURNS: 1765 * Zero on success, errno on failure. 1766 */ 1767 int drm_mode_getfb(struct drm_device *dev, 1768 void *data, struct drm_file *file_priv) 1769 { 1770 struct drm_mode_fb_cmd *r = data; 1771 struct drm_mode_object *obj; 1772 struct drm_framebuffer *fb; 1773 int ret = 0; 1774 1775 mutex_lock(&dev->mode_config.mutex); 1776 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 1777 if (!obj) { 1778 DRM_ERROR("invalid framebuffer id\n"); 1779 ret = -EINVAL; 1780 goto out; 1781 } 1782 fb = obj_to_fb(obj); 1783 1784 r->height = fb->height; 1785 r->width = fb->width; 1786 r->depth = fb->depth; 1787 r->bpp = fb->bits_per_pixel; 1788 r->pitch = fb->pitch; 1789 fb->funcs->create_handle(fb, file_priv, &r->handle); 1790 1791 out: 1792 mutex_unlock(&dev->mode_config.mutex); 1793 return ret; 1794 } 1795 1796 int drm_mode_dirtyfb_ioctl(struct drm_device *dev, 1797 void *data, struct drm_file *file_priv) 1798 { 1799 struct drm_clip_rect __user *clips_ptr; 1800 struct drm_clip_rect *clips = NULL; 1801 struct drm_mode_fb_dirty_cmd *r = data; 1802 struct drm_mode_object *obj; 1803 struct drm_framebuffer *fb; 1804 unsigned flags; 1805 int num_clips; 1806 int ret = 0; 1807 1808 mutex_lock(&dev->mode_config.mutex); 1809 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 1810 if (!obj) { 1811 DRM_ERROR("invalid framebuffer id\n"); 1812 ret = -EINVAL; 1813 goto out_err1; 1814 } 1815 fb = obj_to_fb(obj); 1816 1817 num_clips = r->num_clips; 1818 clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr; 1819 1820 if (!num_clips != !clips_ptr) { 1821 ret = -EINVAL; 1822 goto out_err1; 1823 } 1824 1825 flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags; 1826 1827 /* If userspace annotates copy, clips must come in pairs */ 1828 if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) { 1829 ret = -EINVAL; 1830 goto out_err1; 1831 } 1832 1833 if (num_clips && clips_ptr) { 1834 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); 1835 if (!clips) { 1836 ret = -ENOMEM; 1837 goto out_err1; 1838 } 1839 1840 ret = copy_from_user(clips, clips_ptr, 1841 num_clips * sizeof(*clips)); 1842 if (ret) 1843 goto out_err2; 1844 } 1845 1846 if (fb->funcs->dirty) { 1847 ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips); 1848 } else { 1849 ret = -ENOSYS; 1850 goto out_err2; 1851 } 1852 1853 out_err2: 1854 kfree(clips); 1855 out_err1: 1856 mutex_unlock(&dev->mode_config.mutex); 1857 return ret; 1858 } 1859 1860 1861 /** 1862 * drm_fb_release - remove and free the FBs on this file 1863 * @filp: file * from the ioctl 1864 * 1865 * LOCKING: 1866 * Takes mode config lock. 1867 * 1868 * Destroy all the FBs associated with @filp. 1869 * 1870 * Called by the user via ioctl. 1871 * 1872 * RETURNS: 1873 * Zero on success, errno on failure. 1874 */ 1875 void drm_fb_release(struct drm_file *priv) 1876 { 1877 struct drm_device *dev = priv->minor->dev; 1878 struct drm_framebuffer *fb, *tfb; 1879 1880 mutex_lock(&dev->mode_config.mutex); 1881 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { 1882 list_del(&fb->filp_head); 1883 fb->funcs->destroy(fb); 1884 } 1885 mutex_unlock(&dev->mode_config.mutex); 1886 } 1887 1888 /** 1889 * drm_mode_attachmode - add a mode to the user mode list 1890 * @dev: DRM device 1891 * @connector: connector to add the mode to 1892 * @mode: mode to add 1893 * 1894 * Add @mode to @connector's user mode list. 1895 */ 1896 static int drm_mode_attachmode(struct drm_device *dev, 1897 struct drm_connector *connector, 1898 struct drm_display_mode *mode) 1899 { 1900 int ret = 0; 1901 1902 list_add_tail(&mode->head, &connector->user_modes); 1903 return ret; 1904 } 1905 1906 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, 1907 struct drm_display_mode *mode) 1908 { 1909 struct drm_connector *connector; 1910 int ret = 0; 1911 struct drm_display_mode *dup_mode; 1912 int need_dup = 0; 1913 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1914 if (!connector->encoder) 1915 break; 1916 if (connector->encoder->crtc == crtc) { 1917 if (need_dup) 1918 dup_mode = drm_mode_duplicate(dev, mode); 1919 else 1920 dup_mode = mode; 1921 ret = drm_mode_attachmode(dev, connector, dup_mode); 1922 if (ret) 1923 return ret; 1924 need_dup = 1; 1925 } 1926 } 1927 return 0; 1928 } 1929 EXPORT_SYMBOL(drm_mode_attachmode_crtc); 1930 1931 static int drm_mode_detachmode(struct drm_device *dev, 1932 struct drm_connector *connector, 1933 struct drm_display_mode *mode) 1934 { 1935 int found = 0; 1936 int ret = 0; 1937 struct drm_display_mode *match_mode, *t; 1938 1939 list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) { 1940 if (drm_mode_equal(match_mode, mode)) { 1941 list_del(&match_mode->head); 1942 drm_mode_destroy(dev, match_mode); 1943 found = 1; 1944 break; 1945 } 1946 } 1947 1948 if (!found) 1949 ret = -EINVAL; 1950 1951 return ret; 1952 } 1953 1954 int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) 1955 { 1956 struct drm_connector *connector; 1957 1958 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1959 drm_mode_detachmode(dev, connector, mode); 1960 } 1961 return 0; 1962 } 1963 EXPORT_SYMBOL(drm_mode_detachmode_crtc); 1964 1965 /** 1966 * drm_fb_attachmode - Attach a user mode to an connector 1967 * @inode: inode from the ioctl 1968 * @filp: file * from the ioctl 1969 * @cmd: cmd from ioctl 1970 * @arg: arg from ioctl 1971 * 1972 * This attaches a user specified mode to an connector. 1973 * Called by the user via ioctl. 1974 * 1975 * RETURNS: 1976 * Zero on success, errno on failure. 1977 */ 1978 int drm_mode_attachmode_ioctl(struct drm_device *dev, 1979 void *data, struct drm_file *file_priv) 1980 { 1981 struct drm_mode_mode_cmd *mode_cmd = data; 1982 struct drm_connector *connector; 1983 struct drm_display_mode *mode; 1984 struct drm_mode_object *obj; 1985 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 1986 int ret = 0; 1987 1988 mutex_lock(&dev->mode_config.mutex); 1989 1990 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 1991 if (!obj) { 1992 ret = -EINVAL; 1993 goto out; 1994 } 1995 connector = obj_to_connector(obj); 1996 1997 mode = drm_mode_create(dev); 1998 if (!mode) { 1999 ret = -ENOMEM; 2000 goto out; 2001 } 2002 2003 drm_crtc_convert_umode(mode, umode); 2004 2005 ret = drm_mode_attachmode(dev, connector, mode); 2006 out: 2007 mutex_unlock(&dev->mode_config.mutex); 2008 return ret; 2009 } 2010 2011 2012 /** 2013 * drm_fb_detachmode - Detach a user specified mode from an connector 2014 * @inode: inode from the ioctl 2015 * @filp: file * from the ioctl 2016 * @cmd: cmd from ioctl 2017 * @arg: arg from ioctl 2018 * 2019 * Called by the user via ioctl. 2020 * 2021 * RETURNS: 2022 * Zero on success, errno on failure. 2023 */ 2024 int drm_mode_detachmode_ioctl(struct drm_device *dev, 2025 void *data, struct drm_file *file_priv) 2026 { 2027 struct drm_mode_object *obj; 2028 struct drm_mode_mode_cmd *mode_cmd = data; 2029 struct drm_connector *connector; 2030 struct drm_display_mode mode; 2031 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 2032 int ret = 0; 2033 2034 mutex_lock(&dev->mode_config.mutex); 2035 2036 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2037 if (!obj) { 2038 ret = -EINVAL; 2039 goto out; 2040 } 2041 connector = obj_to_connector(obj); 2042 2043 drm_crtc_convert_umode(&mode, umode); 2044 ret = drm_mode_detachmode(dev, connector, &mode); 2045 out: 2046 mutex_unlock(&dev->mode_config.mutex); 2047 return ret; 2048 } 2049 2050 struct drm_property *drm_property_create(struct drm_device *dev, int flags, 2051 const char *name, int num_values) 2052 { 2053 struct drm_property *property = NULL; 2054 2055 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 2056 if (!property) 2057 return NULL; 2058 2059 if (num_values) { 2060 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); 2061 if (!property->values) 2062 goto fail; 2063 } 2064 2065 drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); 2066 property->flags = flags; 2067 property->num_values = num_values; 2068 INIT_LIST_HEAD(&property->enum_blob_list); 2069 2070 if (name) 2071 strncpy(property->name, name, DRM_PROP_NAME_LEN); 2072 2073 list_add_tail(&property->head, &dev->mode_config.property_list); 2074 return property; 2075 fail: 2076 kfree(property); 2077 return NULL; 2078 } 2079 EXPORT_SYMBOL(drm_property_create); 2080 2081 int drm_property_add_enum(struct drm_property *property, int index, 2082 uint64_t value, const char *name) 2083 { 2084 struct drm_property_enum *prop_enum; 2085 2086 if (!(property->flags & DRM_MODE_PROP_ENUM)) 2087 return -EINVAL; 2088 2089 if (!list_empty(&property->enum_blob_list)) { 2090 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 2091 if (prop_enum->value == value) { 2092 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 2093 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 2094 return 0; 2095 } 2096 } 2097 } 2098 2099 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 2100 if (!prop_enum) 2101 return -ENOMEM; 2102 2103 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 2104 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 2105 prop_enum->value = value; 2106 2107 property->values[index] = value; 2108 list_add_tail(&prop_enum->head, &property->enum_blob_list); 2109 return 0; 2110 } 2111 EXPORT_SYMBOL(drm_property_add_enum); 2112 2113 void drm_property_destroy(struct drm_device *dev, struct drm_property *property) 2114 { 2115 struct drm_property_enum *prop_enum, *pt; 2116 2117 list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { 2118 list_del(&prop_enum->head); 2119 kfree(prop_enum); 2120 } 2121 2122 if (property->num_values) 2123 kfree(property->values); 2124 drm_mode_object_put(dev, &property->base); 2125 list_del(&property->head); 2126 kfree(property); 2127 } 2128 EXPORT_SYMBOL(drm_property_destroy); 2129 2130 int drm_connector_attach_property(struct drm_connector *connector, 2131 struct drm_property *property, uint64_t init_val) 2132 { 2133 int i; 2134 2135 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2136 if (connector->property_ids[i] == 0) { 2137 connector->property_ids[i] = property->base.id; 2138 connector->property_values[i] = init_val; 2139 break; 2140 } 2141 } 2142 2143 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2144 return -EINVAL; 2145 return 0; 2146 } 2147 EXPORT_SYMBOL(drm_connector_attach_property); 2148 2149 int drm_connector_property_set_value(struct drm_connector *connector, 2150 struct drm_property *property, uint64_t value) 2151 { 2152 int i; 2153 2154 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2155 if (connector->property_ids[i] == property->base.id) { 2156 connector->property_values[i] = value; 2157 break; 2158 } 2159 } 2160 2161 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2162 return -EINVAL; 2163 return 0; 2164 } 2165 EXPORT_SYMBOL(drm_connector_property_set_value); 2166 2167 int drm_connector_property_get_value(struct drm_connector *connector, 2168 struct drm_property *property, uint64_t *val) 2169 { 2170 int i; 2171 2172 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2173 if (connector->property_ids[i] == property->base.id) { 2174 *val = connector->property_values[i]; 2175 break; 2176 } 2177 } 2178 2179 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2180 return -EINVAL; 2181 return 0; 2182 } 2183 EXPORT_SYMBOL(drm_connector_property_get_value); 2184 2185 int drm_mode_getproperty_ioctl(struct drm_device *dev, 2186 void *data, struct drm_file *file_priv) 2187 { 2188 struct drm_mode_object *obj; 2189 struct drm_mode_get_property *out_resp = data; 2190 struct drm_property *property; 2191 int enum_count = 0; 2192 int blob_count = 0; 2193 int value_count = 0; 2194 int ret = 0, i; 2195 int copied; 2196 struct drm_property_enum *prop_enum; 2197 struct drm_mode_property_enum __user *enum_ptr; 2198 struct drm_property_blob *prop_blob; 2199 uint32_t *blob_id_ptr; 2200 uint64_t __user *values_ptr; 2201 uint32_t __user *blob_length_ptr; 2202 2203 mutex_lock(&dev->mode_config.mutex); 2204 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2205 if (!obj) { 2206 ret = -EINVAL; 2207 goto done; 2208 } 2209 property = obj_to_property(obj); 2210 2211 if (property->flags & DRM_MODE_PROP_ENUM) { 2212 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 2213 enum_count++; 2214 } else if (property->flags & DRM_MODE_PROP_BLOB) { 2215 list_for_each_entry(prop_blob, &property->enum_blob_list, head) 2216 blob_count++; 2217 } 2218 2219 value_count = property->num_values; 2220 2221 strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN); 2222 out_resp->name[DRM_PROP_NAME_LEN-1] = 0; 2223 out_resp->flags = property->flags; 2224 2225 if ((out_resp->count_values >= value_count) && value_count) { 2226 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr; 2227 for (i = 0; i < value_count; i++) { 2228 if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) { 2229 ret = -EFAULT; 2230 goto done; 2231 } 2232 } 2233 } 2234 out_resp->count_values = value_count; 2235 2236 if (property->flags & DRM_MODE_PROP_ENUM) { 2237 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 2238 copied = 0; 2239 enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr; 2240 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 2241 2242 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { 2243 ret = -EFAULT; 2244 goto done; 2245 } 2246 2247 if (copy_to_user(&enum_ptr[copied].name, 2248 &prop_enum->name, DRM_PROP_NAME_LEN)) { 2249 ret = -EFAULT; 2250 goto done; 2251 } 2252 copied++; 2253 } 2254 } 2255 out_resp->count_enum_blobs = enum_count; 2256 } 2257 2258 if (property->flags & DRM_MODE_PROP_BLOB) { 2259 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { 2260 copied = 0; 2261 blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr; 2262 blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr; 2263 2264 list_for_each_entry(prop_blob, &property->enum_blob_list, head) { 2265 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { 2266 ret = -EFAULT; 2267 goto done; 2268 } 2269 2270 if (put_user(prop_blob->length, blob_length_ptr + copied)) { 2271 ret = -EFAULT; 2272 goto done; 2273 } 2274 2275 copied++; 2276 } 2277 } 2278 out_resp->count_enum_blobs = blob_count; 2279 } 2280 done: 2281 mutex_unlock(&dev->mode_config.mutex); 2282 return ret; 2283 } 2284 2285 static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length, 2286 void *data) 2287 { 2288 struct drm_property_blob *blob; 2289 2290 if (!length || !data) 2291 return NULL; 2292 2293 blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 2294 if (!blob) 2295 return NULL; 2296 2297 blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); 2298 blob->length = length; 2299 2300 memcpy(blob->data, data, length); 2301 2302 drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); 2303 2304 list_add_tail(&blob->head, &dev->mode_config.property_blob_list); 2305 return blob; 2306 } 2307 2308 static void drm_property_destroy_blob(struct drm_device *dev, 2309 struct drm_property_blob *blob) 2310 { 2311 drm_mode_object_put(dev, &blob->base); 2312 list_del(&blob->head); 2313 kfree(blob); 2314 } 2315 2316 int drm_mode_getblob_ioctl(struct drm_device *dev, 2317 void *data, struct drm_file *file_priv) 2318 { 2319 struct drm_mode_object *obj; 2320 struct drm_mode_get_blob *out_resp = data; 2321 struct drm_property_blob *blob; 2322 int ret = 0; 2323 void *blob_ptr; 2324 2325 mutex_lock(&dev->mode_config.mutex); 2326 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); 2327 if (!obj) { 2328 ret = -EINVAL; 2329 goto done; 2330 } 2331 blob = obj_to_blob(obj); 2332 2333 if (out_resp->length == blob->length) { 2334 blob_ptr = (void *)(unsigned long)out_resp->data; 2335 if (copy_to_user(blob_ptr, blob->data, blob->length)){ 2336 ret = -EFAULT; 2337 goto done; 2338 } 2339 } 2340 out_resp->length = blob->length; 2341 2342 done: 2343 mutex_unlock(&dev->mode_config.mutex); 2344 return ret; 2345 } 2346 2347 int drm_mode_connector_update_edid_property(struct drm_connector *connector, 2348 struct edid *edid) 2349 { 2350 struct drm_device *dev = connector->dev; 2351 int ret = 0; 2352 2353 if (connector->edid_blob_ptr) 2354 drm_property_destroy_blob(dev, connector->edid_blob_ptr); 2355 2356 /* Delete edid, when there is none. */ 2357 if (!edid) { 2358 connector->edid_blob_ptr = NULL; 2359 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); 2360 return ret; 2361 } 2362 2363 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid); 2364 2365 ret = drm_connector_property_set_value(connector, 2366 dev->mode_config.edid_property, 2367 connector->edid_blob_ptr->base.id); 2368 2369 return ret; 2370 } 2371 EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 2372 2373 int drm_mode_connector_property_set_ioctl(struct drm_device *dev, 2374 void *data, struct drm_file *file_priv) 2375 { 2376 struct drm_mode_connector_set_property *out_resp = data; 2377 struct drm_mode_object *obj; 2378 struct drm_property *property; 2379 struct drm_connector *connector; 2380 int ret = -EINVAL; 2381 int i; 2382 2383 mutex_lock(&dev->mode_config.mutex); 2384 2385 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2386 if (!obj) { 2387 goto out; 2388 } 2389 connector = obj_to_connector(obj); 2390 2391 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2392 if (connector->property_ids[i] == out_resp->prop_id) 2393 break; 2394 } 2395 2396 if (i == DRM_CONNECTOR_MAX_PROPERTY) { 2397 goto out; 2398 } 2399 2400 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2401 if (!obj) { 2402 goto out; 2403 } 2404 property = obj_to_property(obj); 2405 2406 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 2407 goto out; 2408 2409 if (property->flags & DRM_MODE_PROP_RANGE) { 2410 if (out_resp->value < property->values[0]) 2411 goto out; 2412 2413 if (out_resp->value > property->values[1]) 2414 goto out; 2415 } else { 2416 int found = 0; 2417 for (i = 0; i < property->num_values; i++) { 2418 if (property->values[i] == out_resp->value) { 2419 found = 1; 2420 break; 2421 } 2422 } 2423 if (!found) { 2424 goto out; 2425 } 2426 } 2427 2428 /* Do DPMS ourselves */ 2429 if (property == connector->dev->mode_config.dpms_property) { 2430 if (connector->funcs->dpms) 2431 (*connector->funcs->dpms)(connector, (int) out_resp->value); 2432 ret = 0; 2433 } else if (connector->funcs->set_property) 2434 ret = connector->funcs->set_property(connector, property, out_resp->value); 2435 2436 /* store the property value if successful */ 2437 if (!ret) 2438 drm_connector_property_set_value(connector, property, out_resp->value); 2439 out: 2440 mutex_unlock(&dev->mode_config.mutex); 2441 return ret; 2442 } 2443 2444 int drm_mode_connector_attach_encoder(struct drm_connector *connector, 2445 struct drm_encoder *encoder) 2446 { 2447 int i; 2448 2449 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 2450 if (connector->encoder_ids[i] == 0) { 2451 connector->encoder_ids[i] = encoder->base.id; 2452 return 0; 2453 } 2454 } 2455 return -ENOMEM; 2456 } 2457 EXPORT_SYMBOL(drm_mode_connector_attach_encoder); 2458 2459 void drm_mode_connector_detach_encoder(struct drm_connector *connector, 2460 struct drm_encoder *encoder) 2461 { 2462 int i; 2463 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 2464 if (connector->encoder_ids[i] == encoder->base.id) { 2465 connector->encoder_ids[i] = 0; 2466 if (connector->encoder == encoder) 2467 connector->encoder = NULL; 2468 break; 2469 } 2470 } 2471 } 2472 EXPORT_SYMBOL(drm_mode_connector_detach_encoder); 2473 2474 bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 2475 int gamma_size) 2476 { 2477 crtc->gamma_size = gamma_size; 2478 2479 crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); 2480 if (!crtc->gamma_store) { 2481 crtc->gamma_size = 0; 2482 return false; 2483 } 2484 2485 return true; 2486 } 2487 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); 2488 2489 int drm_mode_gamma_set_ioctl(struct drm_device *dev, 2490 void *data, struct drm_file *file_priv) 2491 { 2492 struct drm_mode_crtc_lut *crtc_lut = data; 2493 struct drm_mode_object *obj; 2494 struct drm_crtc *crtc; 2495 void *r_base, *g_base, *b_base; 2496 int size; 2497 int ret = 0; 2498 2499 mutex_lock(&dev->mode_config.mutex); 2500 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 2501 if (!obj) { 2502 ret = -EINVAL; 2503 goto out; 2504 } 2505 crtc = obj_to_crtc(obj); 2506 2507 /* memcpy into gamma store */ 2508 if (crtc_lut->gamma_size != crtc->gamma_size) { 2509 ret = -EINVAL; 2510 goto out; 2511 } 2512 2513 size = crtc_lut->gamma_size * (sizeof(uint16_t)); 2514 r_base = crtc->gamma_store; 2515 if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) { 2516 ret = -EFAULT; 2517 goto out; 2518 } 2519 2520 g_base = r_base + size; 2521 if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) { 2522 ret = -EFAULT; 2523 goto out; 2524 } 2525 2526 b_base = g_base + size; 2527 if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) { 2528 ret = -EFAULT; 2529 goto out; 2530 } 2531 2532 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size); 2533 2534 out: 2535 mutex_unlock(&dev->mode_config.mutex); 2536 return ret; 2537 2538 } 2539 2540 int drm_mode_gamma_get_ioctl(struct drm_device *dev, 2541 void *data, struct drm_file *file_priv) 2542 { 2543 struct drm_mode_crtc_lut *crtc_lut = data; 2544 struct drm_mode_object *obj; 2545 struct drm_crtc *crtc; 2546 void *r_base, *g_base, *b_base; 2547 int size; 2548 int ret = 0; 2549 2550 mutex_lock(&dev->mode_config.mutex); 2551 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 2552 if (!obj) { 2553 ret = -EINVAL; 2554 goto out; 2555 } 2556 crtc = obj_to_crtc(obj); 2557 2558 /* memcpy into gamma store */ 2559 if (crtc_lut->gamma_size != crtc->gamma_size) { 2560 ret = -EINVAL; 2561 goto out; 2562 } 2563 2564 size = crtc_lut->gamma_size * (sizeof(uint16_t)); 2565 r_base = crtc->gamma_store; 2566 if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) { 2567 ret = -EFAULT; 2568 goto out; 2569 } 2570 2571 g_base = r_base + size; 2572 if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) { 2573 ret = -EFAULT; 2574 goto out; 2575 } 2576 2577 b_base = g_base + size; 2578 if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { 2579 ret = -EFAULT; 2580 goto out; 2581 } 2582 out: 2583 mutex_unlock(&dev->mode_config.mutex); 2584 return ret; 2585 } 2586 2587 int drm_mode_page_flip_ioctl(struct drm_device *dev, 2588 void *data, struct drm_file *file_priv) 2589 { 2590 struct drm_mode_crtc_page_flip *page_flip = data; 2591 struct drm_mode_object *obj; 2592 struct drm_crtc *crtc; 2593 struct drm_framebuffer *fb; 2594 struct drm_pending_vblank_event *e = NULL; 2595 unsigned long flags; 2596 int ret = -EINVAL; 2597 2598 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || 2599 page_flip->reserved != 0) 2600 return -EINVAL; 2601 2602 mutex_lock(&dev->mode_config.mutex); 2603 obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC); 2604 if (!obj) 2605 goto out; 2606 crtc = obj_to_crtc(obj); 2607 2608 if (crtc->funcs->page_flip == NULL) 2609 goto out; 2610 2611 obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB); 2612 if (!obj) 2613 goto out; 2614 fb = obj_to_fb(obj); 2615 2616 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 2617 ret = -ENOMEM; 2618 spin_lock_irqsave(&dev->event_lock, flags); 2619 if (file_priv->event_space < sizeof e->event) { 2620 spin_unlock_irqrestore(&dev->event_lock, flags); 2621 goto out; 2622 } 2623 file_priv->event_space -= sizeof e->event; 2624 spin_unlock_irqrestore(&dev->event_lock, flags); 2625 2626 e = kzalloc(sizeof *e, GFP_KERNEL); 2627 if (e == NULL) { 2628 spin_lock_irqsave(&dev->event_lock, flags); 2629 file_priv->event_space += sizeof e->event; 2630 spin_unlock_irqrestore(&dev->event_lock, flags); 2631 goto out; 2632 } 2633 2634 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 2635 e->event.base.length = sizeof e->event; 2636 e->event.user_data = page_flip->user_data; 2637 e->base.event = &e->event.base; 2638 e->base.file_priv = file_priv; 2639 e->base.destroy = 2640 (void (*) (struct drm_pending_event *)) kfree; 2641 } 2642 2643 ret = crtc->funcs->page_flip(crtc, fb, e); 2644 if (ret) { 2645 spin_lock_irqsave(&dev->event_lock, flags); 2646 file_priv->event_space += sizeof e->event; 2647 spin_unlock_irqrestore(&dev->event_lock, flags); 2648 kfree(e); 2649 } 2650 2651 out: 2652 mutex_unlock(&dev->mode_config.mutex); 2653 return ret; 2654 } 2655