diff --git a/src/add-ons/kernel/drivers/misc/mem.c b/src/add-ons/kernel/drivers/misc/mem.c index 088f0616e1..89b8c57396 100644 --- a/src/add-ons/kernel/drivers/misc/mem.c +++ b/src/add-ons/kernel/drivers/misc/mem.c @@ -2,8 +2,6 @@ * Copyright 2007, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ - - #include #include #include @@ -21,11 +19,11 @@ static status_t mem_open(const char*, uint32, void**); static status_t mem_close(void*); static status_t mem_free(void*); -//static status_t mem_control(void*, uint32, void*, size_t); static status_t mem_read(void*, off_t, void*, size_t*); static status_t mem_write(void*, off_t, const void*, size_t*); -static area_id mem_map_target(off_t position, size_t len, uint32 protection, void **va); +static area_id mem_map_target(off_t position, size_t length, uint32 protection, + void **virtualAddress); static const char* mem_name[] = { DEVICE_NAME, @@ -86,7 +84,6 @@ mem_open(const char* name, uint32 flags, void** cookie) { // not really needed. *cookie = NULL; - return B_OK; } @@ -104,87 +101,81 @@ mem_free(void* cookie) return B_OK; } -/* -status_t -mem_control(void* cookie, uint32 op, void* arg, size_t length) -{ - return ENOSYS; -} -*/ status_t mem_read(void* cookie, off_t position, void* buffer, size_t* numBytes) { - status_t err; - void *va; + void *virtualAddress; area_id area; - - /* check perms */ - err = EPERM; - if (getuid() != 0 && geteuid() != 0) - goto err1; - err = area = mem_map_target(position, *numBytes, B_READ_AREA, &va); - if (err < 0) - goto err1; - memcpy(buffer, va, *numBytes); + + /* check permissions */ + if (getuid() != 0 && geteuid() != 0) { + *numBytes = 0; + return EPERM; + } + + area = mem_map_target(position, *numBytes, B_READ_AREA, &virtualAddress); + if (area < 0) { + *numBytes = 0; + return area; + } + + memcpy(buffer, virtualAddress, *numBytes); delete_area(area); return B_OK; -err1: - *numBytes = 0; - return err; } status_t mem_write(void* cookie, off_t position, const void* buffer, size_t* numBytes) { - status_t err; - void *va; + void *virtualAddress; area_id area; - - /* check perms */ - err = EPERM; - if (getuid() != 0 && geteuid() != 0) - goto err1; - err = area = mem_map_target(position, *numBytes, B_WRITE_AREA, &va); - if (err < 0) - goto err1; - memcpy(va, buffer, *numBytes); + + /* check permissions */ + if (getuid() != 0 && geteuid() != 0) { + *numBytes = 0; + return EPERM; + } + + area = mem_map_target(position, *numBytes, B_WRITE_AREA, &virtualAddress); + if (area < 0) { + *numBytes = 0; + return area; + } + + memcpy(virtualAddress, buffer, *numBytes); delete_area(area); return B_OK; -err1: - *numBytes = 0; - return err; } + area_id -mem_map_target(off_t position, size_t len, uint32 protection, void **va) +mem_map_target(off_t position, size_t length, uint32 protection, + void **virtualAddress) { area_id area; - void *paddr; - void *vaddr; - int offset; + void *physicalAddress; + size_t offset; size_t size; - + /* SIZE_MAX actually but 2G should be enough anyway */ - if (len > SSIZE_MAX - B_PAGE_SIZE) + if (length > SSIZE_MAX - B_PAGE_SIZE) return EINVAL; - + /* the first page address */ - paddr = (void *)(addr_t)(position & ~((off_t)B_PAGE_SIZE - 1)); + physicalAddress = (void *)(addr_t)(position & ~((off_t)B_PAGE_SIZE - 1)); + /* offset of target into it */ - offset = position - (off_t)(addr_t)paddr; + offset = position - (off_t)(addr_t)physicalAddress; + /* size of the whole mapping (page rounded) */ - size = (offset + len + B_PAGE_SIZE - 1) & ~((size_t)B_PAGE_SIZE - 1); - - area = map_physical_memory("mem_driver_temp", - paddr, size, B_ANY_KERNEL_ADDRESS, - protection, &vaddr); - + size = (offset + length + B_PAGE_SIZE - 1) & ~((size_t)B_PAGE_SIZE - 1); + area = map_physical_memory("mem_driver_temp", physicalAddress, size, + B_ANY_KERNEL_ADDRESS, protection, virtualAddress); if (area < 0) return area; - - *va = vaddr + offset; - - return EINVAL; + + *virtualAddress += offset; + return area; }