mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
SCSI: Respect DMA_HIGH_ADDRESS, if specified.
Related to #19191 and others.
This commit is contained in:
parent
b88d29aa2c
commit
1b05bf1a7e
@ -217,6 +217,9 @@ scsi_init_bus(device_node *node, void **cookie)
|
||||
if (pnp->get_attr_uint32(node, B_DMA_MAX_SEGMENT_COUNT,
|
||||
&bus->dma_params.max_sg_blocks, true) != B_OK)
|
||||
bus->dma_params.max_sg_blocks = ~0;
|
||||
if (pnp->get_attr_uint64(node, B_DMA_HIGH_ADDRESS,
|
||||
&bus->dma_params.high_address, true) != B_OK)
|
||||
bus->dma_params.high_address = ~0;
|
||||
|
||||
// do some sanity check:
|
||||
bus->dma_params.max_sg_block_size &= ~bus->dma_params.alignment;
|
||||
|
@ -39,10 +39,10 @@ is_sg_list_dma_safe(scsi_ccb *request)
|
||||
scsi_bus_info *bus = request->bus;
|
||||
const physical_entry *sg_list = request->sg_list;
|
||||
uint32 sg_count = request->sg_count;
|
||||
uint32 dma_boundary = bus->dma_params.dma_boundary;
|
||||
uint32 alignment = bus->dma_params.alignment;
|
||||
uint32 max_sg_block_size = bus->dma_params.max_sg_block_size;
|
||||
uint32 cur_idx;
|
||||
const uint32 dma_boundary = bus->dma_params.dma_boundary;
|
||||
const uint32 alignment = bus->dma_params.alignment;
|
||||
const uint32 max_sg_block_size = bus->dma_params.max_sg_block_size;
|
||||
const uint64 high_address = bus->dma_params.high_address;
|
||||
|
||||
// not too many S/G list entries
|
||||
if (sg_count > bus->dma_params.max_sg_blocks) {
|
||||
@ -54,8 +54,8 @@ is_sg_list_dma_safe(scsi_ccb *request)
|
||||
if (dma_boundary == ~(uint32)0 && alignment == 0 && max_sg_block_size == 0)
|
||||
return true;
|
||||
|
||||
// argh - controller is a bit picky, so make sure he likes us
|
||||
for (cur_idx = sg_count; cur_idx >= 1; --cur_idx, ++sg_list) {
|
||||
// argh - controller is a bit picky, so make sure it likes us
|
||||
for (uint32 cur_idx = sg_count; cur_idx >= 1; --cur_idx, ++sg_list) {
|
||||
phys_addr_t max_len;
|
||||
|
||||
// calculate space upto next dma boundary crossing and
|
||||
@ -81,6 +81,12 @@ is_sg_list_dma_safe(scsi_ccb *request)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((sg_list->address + sg_list->size) > high_address) {
|
||||
SHOW_FLOW(0, "S/G-entry above high address @%" B_PRIxPHYSADDR,
|
||||
sg_list->address + sg_list->size);
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify entry size
|
||||
if (sg_list->size > max_sg_block_size) {
|
||||
SHOW_FLOW(0, "S/G-entry is too long (%" B_PRIuPHYSADDR "/%" B_PRIu32
|
||||
|
@ -79,6 +79,7 @@ typedef struct dma_params {
|
||||
uint32 dma_boundary;
|
||||
uint32 max_sg_block_size;
|
||||
uint32 max_sg_blocks;
|
||||
uint64 high_address;
|
||||
} dma_params;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user