Changeset 0b63dc2 in mainline for uspace/drv/fb/kfb/port.c
- Timestamp:
- 2019-12-07T20:26:28Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- df1a019
- Parents:
- 71cbe5c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/fb/kfb/port.c
r71cbe5c r0b63dc2 1 1 /* 2 * Copyright (c) 2019 Jiri Svoboda 2 3 * Copyright (c) 2006 Jakub Vana 3 4 * Copyright (c) 2006 Ondrej Palkovsky … … 38 39 39 40 #include <abi/fb/visuals.h> 41 #include <adt/list.h> 42 #include <align.h> 43 #include <as.h> 44 #include <ddev_srv.h> 45 #include <ddi.h> 46 #include <ddf/log.h> 47 #include <errno.h> 48 #include <gfx/bitmap.h> 49 #include <gfx/color.h> 50 #include <gfx/coord.h> 51 #include <io/mode.h> 52 #include <io/pixelmap.h> 53 #include <ipcgfx/server.h> 54 #include <mem.h> 55 #include <pixconv.h> 40 56 #include <stddef.h> 41 57 #include <stdint.h> 42 #include <errno.h>43 44 58 #include <stdlib.h> 45 #include <mem.h>46 #include <as.h>47 #include <align.h>48 49 59 #include <sysinfo.h> 50 #include <ddi.h>51 52 #include <adt/list.h>53 54 #include <io/mode.h>55 #include <io/pixelmap.h>56 #include <io/chargrid.h>57 58 #include <pixconv.h>59 60 #include <graph.h>61 60 62 61 #include "kfb.h" 63 62 #include "port.h" 64 63 65 #define FB_POS( x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)64 #define FB_POS(fb, x, y) ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes) 66 65 67 66 typedef struct { 67 ddf_fun_t *fun; 68 68 69 sysarg_t paddr; 69 70 sysarg_t width; … … 80 81 size_t size; 81 82 uint8_t *addr; 83 84 /** Current drawing color */ 85 pixel_t color; 82 86 } kfb_t; 83 87 84 static kfb_t kfb; 85 86 static vslmode_list_element_t pixel_mode; 87 88 static errno_t kfb_claim(visualizer_t *vs) 89 { 90 return physmem_map(kfb.paddr + kfb.offset, 91 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH, 92 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr); 93 } 94 95 static errno_t kfb_yield(visualizer_t *vs) 96 { 88 typedef struct { 89 kfb_t *kfb; 90 gfx_bitmap_alloc_t alloc; 91 gfx_rect_t rect; 92 bool myalloc; 93 } kfb_bitmap_t; 94 95 static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *); 96 97 static errno_t kfb_gc_set_color(void *, gfx_color_t *); 98 static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *); 99 static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *, 100 gfx_bitmap_alloc_t *, void **); 101 static errno_t kfb_gc_bitmap_destroy(void *); 102 static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *); 103 static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *); 104 105 static ddev_ops_t kfb_ddev_ops = { 106 .get_gc = kfb_ddev_get_gc 107 }; 108 109 static gfx_context_ops_t kfb_gc_ops = { 110 .set_color = kfb_gc_set_color, 111 .fill_rect = kfb_gc_fill_rect, 112 .bitmap_create = kfb_gc_bitmap_create, 113 .bitmap_destroy = kfb_gc_bitmap_destroy, 114 .bitmap_render = kfb_gc_bitmap_render, 115 .bitmap_get_alloc = kfb_gc_bitmap_get_alloc 116 }; 117 118 static errno_t kfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3) 119 { 120 kfb_t *kfb = (kfb_t *) arg; 121 122 *arg2 = ddf_fun_get_handle(kfb->fun); 123 *arg3 = 42; 124 return EOK; 125 } 126 127 /** Set color on KFB. 128 * 129 * Set drawing color on KFB GC. 130 * 131 * @param arg KFB 132 * @param color Color 133 * 134 * @return EOK on success or an error code 135 */ 136 static errno_t kfb_gc_set_color(void *arg, gfx_color_t *color) 137 { 138 kfb_t *kfb = (kfb_t *) arg; 139 uint16_t r, g, b; 140 141 gfx_color_get_rgb_i16(color, &r, &g, &b); 142 kfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8); 143 return EOK; 144 } 145 146 /** Fill rectangle on KFB. 147 * 148 * @param arg KFB 149 * @param rect Rectangle 150 * 151 * @return EOK on success or an error code 152 */ 153 static errno_t kfb_gc_fill_rect(void *arg, gfx_rect_t *rect) 154 { 155 kfb_t *kfb = (kfb_t *) arg; 156 gfx_coord_t x, y; 157 158 // XXX We should handle p0.x > p1.x and p0.y > p1.y 159 160 for (y = rect->p0.y; y < rect->p1.y; y++) { 161 for (x = rect->p0.x; x < rect->p1.x; x++) { 162 kfb->pixel2visual(kfb->addr + FB_POS(kfb, x, y), 163 kfb->color); 164 } 165 } 166 167 return EOK; 168 } 169 170 /** Create bitmap in KFB GC. 171 * 172 * @param arg KFB 173 * @param params Bitmap params 174 * @param alloc Bitmap allocation info or @c NULL 175 * @param rbm Place to store pointer to new bitmap 176 * @return EOK on success or an error code 177 */ 178 errno_t kfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params, 179 gfx_bitmap_alloc_t *alloc, void **rbm) 180 { 181 kfb_t *kfb = (kfb_t *) arg; 182 kfb_bitmap_t *kfbbm = NULL; 183 gfx_coord2_t dim; 97 184 errno_t rc; 98 185 99 if (vs->mode_set) { 100 vs->ops.handle_damage = NULL; 101 } 102 103 rc = physmem_unmap(kfb.addr); 104 if (rc != EOK) 105 return rc; 106 107 kfb.addr = NULL; 108 return EOK; 109 } 110 111 static errno_t kfb_handle_damage_pixels(visualizer_t *vs, 112 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height, 113 sysarg_t x_offset, sysarg_t y_offset) 114 { 115 pixelmap_t *map = &vs->cells; 116 117 if (x_offset == 0 && y_offset == 0) { 118 /* Faster damage routine ignoring offsets. */ 119 for (sysarg_t y = y0; y < height + y0; ++y) { 120 pixel_t *pixel = pixelmap_pixel_at(map, x0, y); 121 for (sysarg_t x = x0; x < width + x0; ++x) { 122 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++); 123 } 186 kfbbm = calloc(1, sizeof(kfb_bitmap_t)); 187 if (kfbbm == NULL) 188 return ENOMEM; 189 190 gfx_coord2_subtract(¶ms->rect.p1, ¶ms->rect.p0, &dim); 191 kfbbm->rect = params->rect; 192 193 if (alloc == NULL) { 194 kfbbm->alloc.pitch = dim.x * sizeof(uint32_t); 195 kfbbm->alloc.off0 = 0; 196 kfbbm->alloc.pixels = malloc(kfbbm->alloc.pitch * dim.y); 197 kfbbm->myalloc = true; 198 199 if (kfbbm->alloc.pixels == NULL) { 200 rc = ENOMEM; 201 goto error; 124 202 } 125 203 } else { 126 for (sysarg_t y = y0; y < height + y0; ++y) { 127 for (sysarg_t x = x0; x < width + x0; ++x) { 128 kfb.pixel2visual(kfb.addr + FB_POS(x, y), 129 *pixelmap_pixel_at(map, 130 (x + x_offset) % map->width, 131 (y + y_offset) % map->height)); 132 } 204 kfbbm->alloc = *alloc; 205 } 206 207 kfbbm->kfb = kfb; 208 *rbm = (void *)kfbbm; 209 return EOK; 210 error: 211 if (rbm != NULL) 212 free(kfbbm); 213 return rc; 214 } 215 216 /** Destroy bitmap in KFB GC. 217 * 218 * @param bm Bitmap 219 * @return EOK on success or an error code 220 */ 221 static errno_t kfb_gc_bitmap_destroy(void *bm) 222 { 223 kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm; 224 if (kfbbm->myalloc) 225 free(kfbbm->alloc.pixels); 226 free(kfbbm); 227 return EOK; 228 } 229 230 /** Render bitmap in KFB GC. 231 * 232 * @param bm Bitmap 233 * @param srect0 Source rectangle or @c NULL 234 * @param offs0 Offset or @c NULL 235 * @return EOK on success or an error code 236 */ 237 static errno_t kfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0, 238 gfx_coord2_t *offs0) 239 { 240 kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm; 241 kfb_t *kfb = kfbbm->kfb; 242 gfx_rect_t srect; 243 gfx_rect_t drect; 244 gfx_coord2_t offs; 245 gfx_coord2_t bmdim; 246 gfx_coord2_t dim; 247 gfx_coord_t x, y; 248 pixelmap_t pbm; 249 pixel_t color; 250 251 if (srect0 != NULL) 252 srect = *srect0; 253 else 254 srect = kfbbm->rect; 255 256 if (offs0 != NULL) { 257 offs = *offs0; 258 } else { 259 offs.x = 0; 260 offs.y = 0; 261 } 262 263 /* Destination rectangle */ 264 gfx_rect_translate(&offs, &srect, &drect); 265 gfx_coord2_subtract(&drect.p1, &drect.p0, &dim); 266 gfx_coord2_subtract(&kfbbm->rect.p1, &kfbbm->rect.p0, &bmdim); 267 268 pbm.width = bmdim.x; 269 pbm.height = bmdim.y; 270 pbm.data = kfbbm->alloc.pixels; 271 272 for (y = srect.p0.y; y < srect.p1.y; y++) { 273 for (x = srect.p0.x; x < srect.p1.x; x++) { 274 color = pixelmap_get_pixel(&pbm, x, y); 275 kfb->pixel2visual(kfb->addr + 276 FB_POS(kfb, x, y), color); 133 277 } 134 278 } … … 137 281 } 138 282 139 static errno_t kfb_change_mode(visualizer_t *vs, vslmode_t new_mode) 140 { 141 vs->ops.handle_damage = kfb_handle_damage_pixels; 142 return EOK; 143 } 144 145 static errno_t kfb_suspend(visualizer_t *vs) 146 { 147 return EOK; 148 } 149 150 static errno_t kfb_wakeup(visualizer_t *vs) 151 { 152 return EOK; 153 } 154 155 static visualizer_ops_t kfb_ops = { 156 .claim = kfb_claim, 157 .yield = kfb_yield, 158 .change_mode = kfb_change_mode, 159 .handle_damage = NULL, 160 .suspend = kfb_suspend, 161 .wakeup = kfb_wakeup 162 }; 163 164 static void graph_vsl_connection(ipc_call_t *icall, void *arg) 165 { 166 visualizer_t *vsl; 283 /** Get allocation info for bitmap in KFB GC. 284 * 285 * @param bm Bitmap 286 * @param alloc Place to store allocation info 287 * @return EOK on success or an error code 288 */ 289 static errno_t kfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc) 290 { 291 kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm; 292 *alloc = kfbbm->alloc; 293 return EOK; 294 } 295 296 #include <stdio.h> 297 static void kfb_client_conn(ipc_call_t *icall, void *arg) 298 { 299 kfb_t *kfb; 300 ddev_srv_t srv; 301 sysarg_t gc_id; 302 gfx_context_t *gc; 167 303 errno_t rc; 168 304 169 vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg); 170 graph_visualizer_connection(vsl, icall, NULL); 171 172 if (kfb.addr != NULL) { 173 rc = physmem_unmap(kfb.addr); 305 kfb = (kfb_t *) ddf_fun_data_get((ddf_fun_t *) arg); 306 307 printf("kfb_client_conn arg2=%lu arg3=%lu arg4=%lu\n", 308 ipc_get_arg2(icall), ipc_get_arg3(icall), ipc_get_arg4(icall)); 309 gc_id = ipc_get_arg3(icall); 310 311 if (gc_id == 0) { 312 /* Set up protocol structure */ 313 ddev_srv_initialize(&srv); 314 srv.ops = &kfb_ddev_ops; 315 srv.arg = kfb; 316 317 /* Handle connection */ 318 ddev_conn(icall, &srv); 319 } else { 320 assert(gc_id == 42); 321 322 rc = physmem_map(kfb->paddr + kfb->offset, 323 ALIGN_UP(kfb->size, PAGE_SIZE) >> PAGE_WIDTH, 324 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb->addr); 325 if (rc != EOK) 326 goto error; 327 328 rc = gfx_context_new(&kfb_gc_ops, kfb, &gc); 329 if (rc != EOK) 330 goto error; 331 332 /* GC connection */ 333 gc_conn(icall, gc); 334 335 rc = physmem_unmap(kfb->addr); 174 336 if (rc == EOK) 175 kfb.addr = NULL; 176 } 337 kfb->addr = NULL; 338 } 339 340 return; 341 error: 342 if (kfb->addr != NULL) { 343 if (physmem_unmap(kfb->addr) == EOK) 344 kfb->addr = NULL; 345 } 346 347 async_answer_0(icall, rc); 177 348 } 178 349 179 350 errno_t port_init(ddf_dev_t *dev) 180 351 { 352 ddf_fun_t *fun = NULL; 353 kfb_t *kfb = NULL; 354 errno_t rc; 355 356 fun = ddf_fun_create(dev, fun_exposed, "kfb"); 357 if (fun == NULL) { 358 rc = ENOMEM; 359 goto error; 360 } 361 362 ddf_fun_set_conn_handler(fun, &kfb_client_conn); 363 364 kfb = ddf_fun_data_alloc(fun, sizeof(kfb_t)); 365 if (kfb == NULL) { 366 rc = ENOMEM; 367 goto error; 368 } 369 181 370 sysarg_t present; 182 errno_trc = sysinfo_get_value("fb", &present);371 rc = sysinfo_get_value("fb", &present); 183 372 if (rc != EOK) 184 373 present = false; 185 374 186 if (!present) 187 return ENOENT; 375 if (!present) { 376 ddf_fun_destroy(fun); 377 rc = ENOENT; 378 goto error; 379 } 188 380 189 381 sysarg_t kind; … … 192 384 kind = (sysarg_t) -1; 193 385 194 if (kind != 1) 195 return EINVAL; 386 if (kind != 1) { 387 rc = EINVAL; 388 goto error; 389 } 196 390 197 391 sysarg_t paddr; 198 392 rc = sysinfo_get_value("fb.address.physical", &paddr); 199 393 if (rc != EOK) 200 return rc;394 goto error; 201 395 202 396 sysarg_t offset; … … 208 402 rc = sysinfo_get_value("fb.width", &width); 209 403 if (rc != EOK) 210 return rc;404 goto error; 211 405 212 406 sysarg_t height; 213 407 rc = sysinfo_get_value("fb.height", &height); 214 408 if (rc != EOK) 215 return rc;409 goto error; 216 410 217 411 sysarg_t scanline; 218 412 rc = sysinfo_get_value("fb.scanline", &scanline); 219 413 if (rc != EOK) 220 return rc;414 goto error; 221 415 222 416 sysarg_t visual; 223 417 rc = sysinfo_get_value("fb.visual", &visual); 224 418 if (rc != EOK) 225 return rc; 226 227 kfb.width = width; 228 kfb.height = height; 229 kfb.paddr = paddr; 230 kfb.offset = offset; 231 kfb.scanline = scanline; 232 kfb.visual = visual; 419 goto error; 420 421 kfb->fun = fun; 422 423 kfb->width = width; 424 kfb->height = height; 425 kfb->paddr = paddr; 426 kfb->offset = offset; 427 kfb->scanline = scanline; 428 kfb->visual = visual; 233 429 234 430 switch (visual) { 235 431 case VISUAL_INDIRECT_8: 236 kfb .pixel2visual = pixel2bgr_323;237 kfb .visual2pixel = bgr_323_2pixel;238 kfb .visual_mask = visual_mask_323;239 kfb .pixel_bytes = 1;432 kfb->pixel2visual = pixel2bgr_323; 433 kfb->visual2pixel = bgr_323_2pixel; 434 kfb->visual_mask = visual_mask_323; 435 kfb->pixel_bytes = 1; 240 436 break; 241 437 case VISUAL_RGB_5_5_5_LE: 242 kfb .pixel2visual = pixel2rgb_555_le;243 kfb .visual2pixel = rgb_555_le_2pixel;244 kfb .visual_mask = visual_mask_555;245 kfb .pixel_bytes = 2;438 kfb->pixel2visual = pixel2rgb_555_le; 439 kfb->visual2pixel = rgb_555_le_2pixel; 440 kfb->visual_mask = visual_mask_555; 441 kfb->pixel_bytes = 2; 246 442 break; 247 443 case VISUAL_RGB_5_5_5_BE: 248 kfb .pixel2visual = pixel2rgb_555_be;249 kfb .visual2pixel = rgb_555_be_2pixel;250 kfb .visual_mask = visual_mask_555;251 kfb .pixel_bytes = 2;444 kfb->pixel2visual = pixel2rgb_555_be; 445 kfb->visual2pixel = rgb_555_be_2pixel; 446 kfb->visual_mask = visual_mask_555; 447 kfb->pixel_bytes = 2; 252 448 break; 253 449 case VISUAL_RGB_5_6_5_LE: 254 kfb .pixel2visual = pixel2rgb_565_le;255 kfb .visual2pixel = rgb_565_le_2pixel;256 kfb .visual_mask = visual_mask_565;257 kfb .pixel_bytes = 2;450 kfb->pixel2visual = pixel2rgb_565_le; 451 kfb->visual2pixel = rgb_565_le_2pixel; 452 kfb->visual_mask = visual_mask_565; 453 kfb->pixel_bytes = 2; 258 454 break; 259 455 case VISUAL_RGB_5_6_5_BE: 260 kfb .pixel2visual = pixel2rgb_565_be;261 kfb .visual2pixel = rgb_565_be_2pixel;262 kfb .visual_mask = visual_mask_565;263 kfb .pixel_bytes = 2;456 kfb->pixel2visual = pixel2rgb_565_be; 457 kfb->visual2pixel = rgb_565_be_2pixel; 458 kfb->visual_mask = visual_mask_565; 459 kfb->pixel_bytes = 2; 264 460 break; 265 461 case VISUAL_RGB_8_8_8: 266 kfb .pixel2visual = pixel2rgb_888;267 kfb .visual2pixel = rgb_888_2pixel;268 kfb .visual_mask = visual_mask_888;269 kfb .pixel_bytes = 3;462 kfb->pixel2visual = pixel2rgb_888; 463 kfb->visual2pixel = rgb_888_2pixel; 464 kfb->visual_mask = visual_mask_888; 465 kfb->pixel_bytes = 3; 270 466 break; 271 467 case VISUAL_BGR_8_8_8: 272 kfb .pixel2visual = pixel2bgr_888;273 kfb .visual2pixel = bgr_888_2pixel;274 kfb .visual_mask = visual_mask_888;275 kfb .pixel_bytes = 3;468 kfb->pixel2visual = pixel2bgr_888; 469 kfb->visual2pixel = bgr_888_2pixel; 470 kfb->visual_mask = visual_mask_888; 471 kfb->pixel_bytes = 3; 276 472 break; 277 473 case VISUAL_RGB_8_8_8_0: 278 kfb .pixel2visual = pixel2rgb_8880;279 kfb .visual2pixel = rgb_8880_2pixel;280 kfb .visual_mask = visual_mask_8880;281 kfb .pixel_bytes = 4;474 kfb->pixel2visual = pixel2rgb_8880; 475 kfb->visual2pixel = rgb_8880_2pixel; 476 kfb->visual_mask = visual_mask_8880; 477 kfb->pixel_bytes = 4; 282 478 break; 283 479 case VISUAL_RGB_0_8_8_8: 284 kfb .pixel2visual = pixel2rgb_0888;285 kfb .visual2pixel = rgb_0888_2pixel;286 kfb .visual_mask = visual_mask_0888;287 kfb .pixel_bytes = 4;480 kfb->pixel2visual = pixel2rgb_0888; 481 kfb->visual2pixel = rgb_0888_2pixel; 482 kfb->visual_mask = visual_mask_0888; 483 kfb->pixel_bytes = 4; 288 484 break; 289 485 case VISUAL_BGR_0_8_8_8: 290 kfb .pixel2visual = pixel2bgr_0888;291 kfb .visual2pixel = bgr_0888_2pixel;292 kfb .visual_mask = visual_mask_0888;293 kfb .pixel_bytes = 4;486 kfb->pixel2visual = pixel2bgr_0888; 487 kfb->visual2pixel = bgr_0888_2pixel; 488 kfb->visual_mask = visual_mask_0888; 489 kfb->pixel_bytes = 4; 294 490 break; 295 491 case VISUAL_BGR_8_8_8_0: 296 kfb .pixel2visual = pixel2bgr_8880;297 kfb .visual2pixel = bgr_8880_2pixel;298 kfb .visual_mask = visual_mask_8880;299 kfb .pixel_bytes = 4;492 kfb->pixel2visual = pixel2bgr_8880; 493 kfb->visual2pixel = bgr_8880_2pixel; 494 kfb->visual_mask = visual_mask_8880; 495 kfb->pixel_bytes = 4; 300 496 break; 301 497 default: … … 303 499 } 304 500 305 kfb.size = scanline * height; 306 kfb.addr = AS_AREA_ANY; 307 308 ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0"); 309 if (fun_vs == NULL) { 310 as_area_destroy(kfb.addr); 311 return ENOMEM; 312 } 313 ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection); 314 315 visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t)); 316 if (vs == NULL) { 317 as_area_destroy(kfb.addr); 318 return ENOMEM; 319 } 320 graph_init_visualizer(vs); 321 322 pixel_mode.mode.index = 0; 323 pixel_mode.mode.version = 0; 324 pixel_mode.mode.refresh_rate = 0; 325 pixel_mode.mode.screen_aspect.width = width; 326 pixel_mode.mode.screen_aspect.height = height; 327 pixel_mode.mode.screen_width = width; 328 pixel_mode.mode.screen_height = height; 329 pixel_mode.mode.cell_aspect.width = 1; 330 pixel_mode.mode.cell_aspect.height = 1; 331 pixel_mode.mode.cell_visual.pixel_visual = visual; 332 333 link_initialize(&pixel_mode.link); 334 list_append(&pixel_mode.link, &vs->modes); 335 336 vs->def_mode_idx = 0; 337 338 vs->ops = kfb_ops; 339 vs->dev_ctx = NULL; 340 341 rc = ddf_fun_bind(fun_vs); 501 kfb->size = scanline * height; 502 kfb->addr = AS_AREA_ANY; 503 504 rc = ddf_fun_bind(fun); 505 if (rc != EOK) 506 goto error; 507 508 rc = ddf_fun_add_to_category(fun, "display-device"); 342 509 if (rc != EOK) { 343 list_remove(&pixel_mode.link); 344 ddf_fun_destroy(fun_vs); 345 as_area_destroy(kfb.addr); 346 return rc; 347 } 348 349 vs->reg_svc_handle = ddf_fun_get_handle(fun_vs); 350 rc = ddf_fun_add_to_category(fun_vs, "visualizer"); 351 if (rc != EOK) { 352 list_remove(&pixel_mode.link); 353 ddf_fun_unbind(fun_vs); 354 ddf_fun_destroy(fun_vs); 355 as_area_destroy(kfb.addr); 356 return rc; 357 } 358 359 return EOK; 510 ddf_fun_unbind(fun); 511 goto error; 512 } 513 514 return EOK; 515 error: 516 if (fun != NULL) 517 ddf_fun_destroy(fun); 518 return rc; 360 519 } 361 520
Note:
See TracChangeset
for help on using the changeset viewer.