* 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:
@@ -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
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user