* Replaced map_mainmemory() functions with vm_get_physical_page().

* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16949 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-04-01 13:47:19 +00:00
parent 3759d22404
commit f1b350f247
4 changed files with 56 additions and 85 deletions
@@ -1,7 +1,9 @@
/* /*
** Copyright 2002/03, Thomas Kurschel. All rights reserved. * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
** Distributed under the terms of the OpenBeOS License. * Copyright 2002/03, Thomas Kurschel. All rights reserved.
*/ *
* Distributed under the terms of the MIT License.
*/
/* /*
Functions that are missing in kernel. Functions that are missing in kernel.
@@ -26,20 +28,4 @@ status_t get_iovec_memory_map(
size_t *mapped_len // actual number of bytes described by map size_t *mapped_len // actual number of bytes described by map
); );
// map main memory into virtual address space #endif // _KERNEL_EXPORT_EXT_H
status_t map_mainmemory(
addr_t physical_addr, // physical address to map
void **virtual_addr // receives corresponding virtual address
);
// unmap main memory from virtual address space
status_t unmap_mainmemory(
void *virtual_addr // virtual address to release
);
// this should be moved to SupportDefs.h
int32 atomic_exchange(vint32 *value, int32 newValue);
#endif
+15 -13
View File
@@ -1,23 +1,24 @@
/* /*
** Copyright 2002/03, Thomas Kurschel. All rights reserved. * Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Copyright 2002/03, Thomas Kurschel. All rights reserved.
*/ *
* Distributed under the terms of the MIT License.
*/
/* /*
Part of Open IDE bus manager
General SCSI emulation routines General SCSI emulation routines
*/ */
#include "ide_internal.h" #include "ide_internal.h"
#include "ide_sim.h" #include "ide_sim.h"
#include "KernelExport_ext.h"
#include <vm.h>
#include <string.h> #include <string.h>
/** emulate REQUEST SENSE */ /** Emulate REQUEST SENSE */
void void
ide_request_sense(ide_device_info *device, ide_qrequest *qrequest) ide_request_sense(ide_device_info *device, ide_qrequest *qrequest)
@@ -89,24 +90,25 @@ copy_sg_data(scsi_ccb *request, uint offset, uint allocation_length,
// copy one S/G entry at a time // copy one S/G entry at a time
for (; size > 0 && req_size > 0 && sg_cnt > 0; ++sg_list, --sg_cnt) { for (; size > 0 && req_size > 0 && sg_cnt > 0; ++sg_list, --sg_cnt) {
addr_t virtualAddress;
size_t bytes; size_t bytes;
void *virt_addr;
bytes = min(size, req_size); bytes = min(size, req_size);
bytes = min(bytes, sg_list->size); bytes = min(bytes, sg_list->size);
if (map_mainmemory((addr_t)sg_list->address, &virt_addr) != B_OK) if (vm_get_physical_page((addr_t)sg_list->address, &virtualAddress,
PHYSICAL_PAGE_CAN_WAIT) != B_OK)
return false; return false;
SHOW_FLOW(4, "buffer=%p, virt_addr=%p, bytes=%d, to_buffer=%d", SHOW_FLOW(4, "buffer=%p, virt_addr=%p, bytes=%d, to_buffer=%d",
buffer, (void *)((addr_t)virt_addr + offset), (int)bytes, to_buffer); buffer, (void *)(virtualAddress + offset), (int)bytes, to_buffer);
if (to_buffer) if (to_buffer)
memcpy(buffer, (void *)((addr_t)virt_addr + offset), bytes); memcpy(buffer, (void *)(virtualAddress + offset), bytes);
else else
memcpy((void *)((addr_t)virt_addr + offset), buffer, bytes); memcpy((void *)(virtualAddress + offset), buffer, bytes);
unmap_mainmemory(virt_addr); vm_put_physical_page(virtualAddress);
buffer = (char *)buffer + bytes; buffer = (char *)buffer + bytes;
size -= bytes; size -= bytes;
+30 -29
View File
@@ -1,11 +1,11 @@
/* /*
* Copyright 2002-04, Thomas Kurschel. All rights reserved. * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
* Copyright 2002-2004, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
/* /*
Part of Open IDE bus manager
PIO data transmission PIO data transmission
This file is more difficult then you might expect as the SCSI system This file is more difficult then you might expect as the SCSI system
@@ -37,17 +37,18 @@
*/ */
#include "ide_internal.h" #include "ide_internal.h"
#include "KernelExport_ext.h" #include "ide_sim.h"
#include <vm.h>
#include <string.h> #include <string.h>
#include "ide_sim.h"
// internal error code if scatter gather table is too short // internal error code if scatter gather table is too short
#define ERR_TOO_BIG (B_ERRORS_END + 1) #define ERR_TOO_BIG (B_ERRORS_END + 1)
/** prepare PIO transfer */ /** Prepare PIO transfer */
void void
prep_PIO_transfer(ide_device_info *device, ide_qrequest *qrequest) prep_PIO_transfer(ide_device_info *device, ide_qrequest *qrequest)
@@ -65,7 +66,7 @@ prep_PIO_transfer(ide_device_info *device, ide_qrequest *qrequest)
/** transfer virtually continuous data */ /** transfer virtually continuous data */
static inline status_t static inline status_t
transfer_PIO_virtcont(ide_device_info *device, char *virt_addr, int length, transfer_PIO_virtcont(ide_device_info *device, uint8 *virtualAddress, int length,
bool write, int *transferred) bool write, int *transferred)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
@@ -80,7 +81,7 @@ transfer_PIO_virtcont(ide_device_info *device, char *virt_addr, int length,
uint8 buffer[2]; uint8 buffer[2];
buffer[0] = device->odd_byte; buffer[0] = device->odd_byte;
buffer[1] = *virt_addr++; buffer[1] = *virtualAddress++;
controller->write_pio(cookie, (uint16 *)buffer, 1, false); controller->write_pio(cookie, (uint16 *)buffer, 1, false);
@@ -88,30 +89,30 @@ transfer_PIO_virtcont(ide_device_info *device, char *virt_addr, int length,
*transferred += 2; *transferred += 2;
} }
controller->write_pio(cookie, (uint16 *)virt_addr, length / 2, false); controller->write_pio(cookie, (uint16 *)virtualAddress, length / 2, false);
// take care if chunk size was odd, which means that 1 byte remains // take care if chunk size was odd, which means that 1 byte remains
virt_addr += length & ~1; virtualAddress += length & ~1;
*transferred += length & ~1; *transferred += length & ~1;
device->has_odd_byte = (length & 1) != 0; device->has_odd_byte = (length & 1) != 0;
if (device->has_odd_byte) if (device->has_odd_byte)
device->odd_byte = *virt_addr; device->odd_byte = *virtualAddress;
} else { } else {
// if we read one byte too much last time, push it into current chunk // if we read one byte too much last time, push it into current chunk
if (device->has_odd_byte) { if (device->has_odd_byte) {
*virt_addr++ = device->odd_byte; *virtualAddress++ = device->odd_byte;
--length; --length;
} }
SHOW_FLOW(4, "Reading PIO to %p, %d bytes", virt_addr, length); SHOW_FLOW(4, "Reading PIO to %p, %d bytes", virtualAddress, length);
controller->read_pio(cookie, (uint16 *)virt_addr, length / 2, false); controller->read_pio(cookie, (uint16 *)virtualAddress, length / 2, false);
// take care of odd chunk size; // take care of odd chunk size;
// in this case we read 1 byte to few! // in this case we read 1 byte to few!
virt_addr += length & ~1; virtualAddress += length & ~1;
*transferred += length & ~1; *transferred += length & ~1;
device->has_odd_byte = (length & 1) != 0; device->has_odd_byte = (length & 1) != 0;
@@ -123,7 +124,7 @@ transfer_PIO_virtcont(ide_device_info *device, char *virt_addr, int length,
// we'll read one byte too much // we'll read one byte too much
controller->read_pio(cookie, (uint16 *)buffer, 1, false); controller->read_pio(cookie, (uint16 *)buffer, 1, false);
*virt_addr = buffer[0]; *virtualAddress = buffer[0];
device->odd_byte = buffer[1]; device->odd_byte = buffer[1];
*transferred += 2; *transferred += 2;
@@ -137,20 +138,21 @@ transfer_PIO_virtcont(ide_device_info *device, char *virt_addr, int length,
/** transmit physically continuous data */ /** transmit physically continuous data */
static inline status_t static inline status_t
transfer_PIO_physcont(ide_device_info *device, addr_t phys_addr, transfer_PIO_physcont(ide_device_info *device, addr_t physicalAddress,
int length, bool write, int *transferred) int length, bool write, int *transferred)
{ {
// we must split up chunk into B_PAGE_SIZE blocks as we can map only // we must split up chunk into B_PAGE_SIZE blocks as we can map only
// one page into address space at once // one page into address space at once
while (length > 0) { while (length > 0) {
void *virt_addr; addr_t virtualAddress;
int page_left, cur_len; int page_left, cur_len;
status_t err; status_t err;
SHOW_FLOW(4, "Transmitting to/from physical address %x, %d bytes left", (int)phys_addr, SHOW_FLOW(4, "Transmitting to/from physical address %lx, %d bytes left",
length); physicalAddress, length);
if (map_mainmemory(phys_addr, &virt_addr) != B_OK) { if (vm_get_physical_page(physicalAddress, &virtualAddress,
PHYSICAL_PAGE_CAN_WAIT) != B_OK) {
// ouch: this should never ever happen // ouch: this should never ever happen
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
return B_ERROR; return B_ERROR;
@@ -158,7 +160,7 @@ transfer_PIO_physcont(ide_device_info *device, addr_t phys_addr,
// if chunks starts in the middle of a page, we have even less then // if chunks starts in the middle of a page, we have even less then
// a page left // a page left
page_left = B_PAGE_SIZE - phys_addr % B_PAGE_SIZE; page_left = B_PAGE_SIZE - physicalAddress % B_PAGE_SIZE;
SHOW_FLOW(4, "page_left=%d", page_left); SHOW_FLOW(4, "page_left=%d", page_left);
@@ -166,17 +168,16 @@ transfer_PIO_physcont(ide_device_info *device, addr_t phys_addr,
SHOW_FLOW(4, "cur_len=%d", cur_len); SHOW_FLOW(4, "cur_len=%d", cur_len);
err = transfer_PIO_virtcont(device, (char *)virt_addr, err = transfer_PIO_virtcont(device, (char *)virtualAddress,
cur_len, write, transferred); cur_len, write, transferred);
if (err != B_OK) {
unmap_mainmemory(virt_addr); vm_put_physical_page(virtualAddress);
if (err != B_OK)
return err; return err;
}
length -= cur_len; length -= cur_len;
phys_addr += cur_len; physicalAddress += cur_len;
unmap_mainmemory(virt_addr);
} }
return B_OK; return B_OK;
@@ -1,7 +1,9 @@
/* /*
** Copyright 2002/03, Thomas Kurschel. All rights reserved. * Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Copyright 2002/03, Thomas Kurschel. All rights reserved.
*/ *
* Distributed under the terms of the MIT License.
*/
/* /*
VM helper functions. VM helper functions.
@@ -14,7 +16,6 @@
#include "KernelExport_ext.h" #include "KernelExport_ext.h"
#include "wrapper.h" #include "wrapper.h"
#include <vm.h>
#include <string.h> #include <string.h>
@@ -118,22 +119,3 @@ get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len
return B_OK; return B_OK;
} }
/** map main memory into virtual address space */
status_t
map_mainmemory(addr_t physicalAddress, void **_virtualAddress)
{
return vm_get_physical_page(physicalAddress, (addr_t *)_virtualAddress, PHYSICAL_PAGE_CAN_WAIT);
// ToDo: check if CAN_WAIT is correct
}
/** unmap main memory from virtual address space */
status_t
unmap_mainmemory(void *virtualAddress)
{
return vm_put_physical_page((addr_t)virtualAddress);
}