struct ocmem_buf *ocmem_allocate_nowait(int client_id, unsigned long size) { bool can_block = false; bool can_wait = false; if (!check_id(client_id)) { pr_err("ocmem: Invalid client id: %d\n", client_id); return NULL; } if (!zone_active(client_id)) { pr_err("ocmem: Client %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return NULL; } if (size < OCMEM_MIN_ALLOC) { pr_err("ocmem: requested size %lx must be at least %x\n", size, OCMEM_MIN_ALLOC); return NULL; } if (!IS_ALIGNED(size, OCMEM_MIN_ALIGN)) { pr_err("ocmem: Invalid alignment, size must be %x aligned\n", OCMEM_MIN_ALIGN); return NULL; } return __ocmem_allocate_range(client_id, size, size, size, can_block, can_wait); }
int ocmem_shrink(int client_id, struct ocmem_buf *buffer, unsigned long len) { if (!buffer) return -EINVAL; if (len >= buffer->len) return -EINVAL; if (!zone_active(client_id)) { pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return -EINVAL; } return __ocmem_shrink(client_id, buffer, len); }
struct ocmem_notifier *ocmem_notifier_register(int client_id, struct notifier_block *nb) { int ret = 0; struct ocmem_notifier *nc_hndl = NULL; if (!check_id(client_id)) { pr_err("ocmem: Invalid Client id\n"); return NULL; } if (!zone_active(client_id)) { pr_err("ocmem: Client %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return NULL; } if (!nb) { pr_err("ocmem: Invalid Notifier Block\n"); return NULL; } mutex_lock(&nc_lock); nc_hndl = ¬ifiers[client_id]; if (nc_hndl->listeners >= notifier_threshold) { pr_err("ocmem: Max notifiers already registered\n"); mutex_unlock(&nc_lock); return NULL; } ret = atomic_notifier_chain_register(&nc_hndl->nc, nb); if (ret < 0) { mutex_unlock(&nc_lock); return NULL; } nc_hndl->listeners++; pr_info("ocmem: Notifier registered for %d\n", client_id); mutex_unlock(&nc_lock); return nc_hndl; }
int ocmem_map(int client_id, struct ocmem_buf *buffer, struct ocmem_map_list *list) { int ret = 0; struct ocmem_handle *handle = NULL; if (!check_id(client_id)) { pr_err("ocmem: Invalid client id: %d\n", client_id); return -EINVAL; } if (!zone_active(client_id)) { pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return -EINVAL; } /* Asynchronous API requires notifier registration */ if (!check_notifier(client_id)) { pr_err("ocmem: No notifier registered for client %d\n", client_id); return -EINVAL; } if (!buffer) { pr_err("ocmem: Invalid buffer\n"); return -EINVAL; } if (pre_validate_chunk_list(list) != 0) return -EINVAL; handle = buffer_to_handle(buffer); if (!handle) return -EINVAL; mutex_lock(&handle->handle_mutex); ret = process_xfer(client_id, handle, list, TO_OCMEM); mutex_unlock(&handle->handle_mutex); return ret; }
int ocmem_free(int client_id, struct ocmem_buf *buffer) { if (!check_id(client_id)) { pr_err("ocmem: Invalid client id: %d\n", client_id); return -EINVAL; } if (!zone_active(client_id)) { pr_err("ocmem: Client %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return -EINVAL; } if (!buffer) { pr_err("ocmem: Invalid buffer\n"); return -EINVAL; } return __ocmem_free(client_id, buffer); }
struct ocmem_buf *ocmem_allocate_nb(int client_id, unsigned long size) { bool can_block = true; bool can_wait = false; if (!check_id(client_id)) { pr_err("ocmem: Invalid client id: %d\n", client_id); return NULL; } /* Asynchronous API requires notifier registration */ if (!check_notifier(client_id)) { pr_err("ocmem: No notifier registered for client %d\n", client_id); return NULL; } if (!zone_active(client_id)) { pr_err("ocmem: Client %s (id: %d) not allowed to use OCMEM\n", get_name(client_id), client_id); return NULL; } if (size < OCMEM_MIN_ALLOC) { pr_err("ocmem: requested size %lx must be at least %x\n", size, OCMEM_MIN_ALLOC); return NULL; } if (!IS_ALIGNED(size, OCMEM_MIN_ALIGN)) { pr_err("ocmem: Invalid alignment, args must be %x aligned\n", OCMEM_MIN_ALIGN); return NULL; } return __ocmem_allocate_range(client_id, 0, size, size, can_block, can_wait); }