From 6405549873a7efaa0f6fc51d67ede8a9cbf70c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 6 Nov 2007 02:26:44 +0000 Subject: [PATCH] No wonder no one noticed that the silicon_image_3112 driver was broken; I actually forgot to commit the changes I made to the ide_adapter... * the IDE bus master command/status stuff is now used via flags; it's no bitfield anymore. * Changed a few constants to upper case. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22842 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/drivers/ide_adapter.h | 54 ++++----- .../kernel/generic/ide_adapter/ide_adapter.c | 110 +++++++++--------- 2 files changed, 75 insertions(+), 89 deletions(-) diff --git a/headers/private/drivers/ide_adapter.h b/headers/private/drivers/ide_adapter.h index ac1b36dee7..12c1a0d25f 100644 --- a/headers/private/drivers/ide_adapter.h +++ b/headers/private/drivers/ide_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2002-04, Thomas Kurschel. All rights reserved. * * Distributed under the terms of the MIT License. @@ -11,7 +11,7 @@ IDE adapter library Module to simplify writing an IDE adapter driver. - + The interface is not very abstract, i.e. the actual driver is free to access any controller or channel data of this library. */ @@ -36,47 +36,33 @@ typedef struct prd_entry { ); } prd_entry; +// IDE bus master command register +#define IDE_BM_COMMAND_START_STOP 0x01 +#define IDE_BM_COMMAND_READ_FROM_DEVICE 0x08 -// command register -typedef struct ide_bm_command { - LBITFIELD8_4( - start_stop : 1, // start BM by changing from 0 to 1; - // stop BM by changing from 1 to 0 - res0_1 : 2, - from_device : 1, // true - read from device, false - write to device - res0_4 : 4 - ); -} ide_bm_command; - - -// status register -typedef struct ide_bm_status { - LBITFIELD8_7( - active : 1, // 1, if BM is active - error : 1, // 1, if error occured; write 1 to reset - interrupt : 1, // 1, if INTRQ was raised, write 1 to reset - res0_3 : 2, - device0_dma : 1, // 1, if BIOS/driver has setup DMA for device 0 - device1_dma : 1, // 1, if BIOS/driver has setup DMA for device 1 - simplex : 1 // 1, if only one channel can use DMA at a time - ); -} ide_bm_status; - +// IDE bus master status register +#define IDE_BM_STATUS_ACTIVE 0x01 +#define IDE_BM_STATUS_ERROR 0x02 +#define IDE_BM_STATUS_INTERRUPT 0x04 +#define IDE_BM_STATUS_MASTER_DMA 0x20 +#define IDE_BM_STATUS_SLAVE_DMA 0x40 +#define IDE_BM_STATUS_SIMPLEX_DMA 0x80 // offset of bus master registers enum { - ide_bm_command_reg = 0, // see ide_bm_command - ide_bm_status_reg = 2, // see ide_bm_status - ide_bm_prdt_address = 4 // offset of PRDT register; content must be dword-aligned + IDE_BM_COMMAND_REG = 0, + IDE_BM_STATUS_REG = 2, + IDE_BM_PRDT_ADDRESS = 4 + // offset of PRDT register; content must be dword-aligned }; // bit mask in class_api of PCI configuration // (for adapters that can run in compatability mode) enum { - ide_api_primary_native = 1, // primary channel is in native mode - ide_api_primary_fixed = 2, // primary channel can be switched to native mode - ide_api_secondary_native = 4, // secondary channel is in native mode - ide_api_secondary_fixed = 8 // secondary channel can be switched to native mode + IDE_API_PRIMARY_NATIVE = 1, // primary channel is in native mode + IDE_API_PRIMARY_FIXED = 2, // primary channel can be switched to native mode + IDE_API_SECONDARY_NATIVE = 4, // secondary channel is in native mode + IDE_API_SECONDARY_FIXED = 8 // secondary channel can be switched to native mode }; diff --git a/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c b/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c index d655cf2a19..2293a4ea0e 100644 --- a/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c +++ b/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c @@ -180,10 +180,9 @@ ide_adapter_inthand(void *arg) ide_adapter_channel_info *channel = (ide_adapter_channel_info *)arg; pci_device_module_info *pci = channel->pci; pci_device device = channel->device; - ide_bm_status bm_status; uint8 status; - SHOW_FLOW0( 3, "" ); + SHOW_FLOW0(3, ""); if (channel->lost) return B_UNHANDLED_INTERRUPT; @@ -192,10 +191,9 @@ ide_adapter_inthand(void *arg) if (channel->dmaing) { // in DMA mode, there is a safe test // in PIO mode, this don't work - *(uint8 *)&bm_status = pci->read_io_8(device, - channel->bus_master_base + ide_bm_status_reg); - - if (!bm_status.interrupt) + status = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_STATUS_REG); + if ((status & IDE_BM_STATUS_INTERRUPT) == 0) return B_UNHANDLED_INTERRUPT; } @@ -207,47 +205,45 @@ ide_adapter_inthand(void *arg) static status_t -ide_adapter_prepare_dma(ide_adapter_channel_info *channel, const physical_entry *sg_list, - size_t sg_list_count, bool to_device) +ide_adapter_prepare_dma(ide_adapter_channel_info *channel, + const physical_entry *sgList, size_t sgListCount, bool writeToDevice) { pci_device_module_info *pci = channel->pci; pci_device device = channel->device; - ide_bm_command command; - ide_bm_status status; + uint8 command; + uint8 status; prd_entry *prd = channel->prdt; int i; - for (i = sg_list_count - 1, prd = channel->prdt; i >= 0; --i, ++prd, ++sg_list) { - prd->address = B_HOST_TO_LENDIAN_INT32(pci->ram_address(device, sg_list->address)); + for (i = sgListCount - 1, prd = channel->prdt; i >= 0; --i, ++prd, ++sgList) { + prd->address = B_HOST_TO_LENDIAN_INT32(pci->ram_address(device, sgList->address)); // 0 means 64K - this is done automatically be discarding upper 16 bits - prd->count = B_HOST_TO_LENDIAN_INT16((uint16)sg_list->size); + prd->count = B_HOST_TO_LENDIAN_INT16((uint16)sgList->size); prd->EOT = i == 0; SHOW_FLOW( 4, "%x, %x, %d", (int)prd->address, prd->count, prd->EOT); } - pci->write_io_32(device, channel->bus_master_base + ide_bm_prdt_address, - (pci->read_io_32(device, channel->bus_master_base + ide_bm_prdt_address) & 3) + pci->write_io_32(device, channel->bus_master_base + IDE_BM_PRDT_ADDRESS, + (pci->read_io_32(device, channel->bus_master_base + IDE_BM_PRDT_ADDRESS) & 3) | (B_HOST_TO_LENDIAN_INT32(pci->ram_address(device, (void *)channel->prdt_phys)) & ~3)); // reset interrupt and error signal - *(uint8 *)&status = pci->read_io_8(device, - channel->bus_master_base + ide_bm_status_reg); - - status.interrupt = 1; - status.error = 1; - + status = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_STATUS_REG) | IDE_BM_STATUS_INTERRUPT | IDE_BM_STATUS_ERROR; pci->write_io_8(device, - channel->bus_master_base + ide_bm_status_reg, *(uint8 *)&status); + channel->bus_master_base + IDE_BM_STATUS_REG, status); // set data direction - *(uint8 *)&command = pci->read_io_8(device, - channel->bus_master_base + ide_bm_command_reg); + command = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_COMMAND_REG); + if (writeToDevice) + command &= ~IDE_BM_COMMAND_READ_FROM_DEVICE; + else + command |= IDE_BM_COMMAND_READ_FROM_DEVICE; - command.from_device = !to_device; - - pci->write_io_8(device, - channel->bus_master_base + ide_bm_command_reg, *(uint8 *)&command); + pci->write_io_8(device, channel->bus_master_base + IDE_BM_COMMAND_REG, + command); return B_OK; } @@ -258,14 +254,16 @@ ide_adapter_start_dma(ide_adapter_channel_info *channel) { pci_device_module_info *pci = channel->pci; pci_device device = channel->device; - ide_bm_command command; + uint8 command; - *(uint8 *)&command = pci->read_io_8(device, channel->bus_master_base + ide_bm_command_reg); + command = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_COMMAND_REG); - command.start_stop = 1; + command |= IDE_BM_COMMAND_START_STOP; channel->dmaing = true; - pci->write_io_8(device, channel->bus_master_base + ide_bm_command_reg, *(uint8 *)&command); + pci->write_io_8(device, channel->bus_master_base + IDE_BM_COMMAND_REG, + command); return B_OK; } @@ -276,30 +274,31 @@ ide_adapter_finish_dma(ide_adapter_channel_info *channel) { pci_device_module_info *pci = channel->pci; pci_device device = channel->device; - ide_bm_command command; - ide_bm_status status, new_status; + uint8 command; + uint8 status, newStatus; - *(uint8 *)&command = pci->read_io_8(device, channel->bus_master_base + ide_bm_command_reg); + command = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_COMMAND_REG); - command.start_stop = 0; + command &= ~IDE_BM_COMMAND_START_STOP; channel->dmaing = false; - pci->write_io_8(device, channel->bus_master_base + ide_bm_command_reg, *(uint8 *)&command); + pci->write_io_8(device, channel->bus_master_base + IDE_BM_COMMAND_REG, + command); - *(uint8 *)&status = pci->read_io_8(device, channel->bus_master_base + ide_bm_status_reg); + status = pci->read_io_8(device, channel->bus_master_base + + IDE_BM_STATUS_REG); - new_status = status; - new_status.interrupt = 1; - new_status.error = 1; + // reset interrupt/error flags + newStatus = status | IDE_BM_STATUS_INTERRUPT | IDE_BM_STATUS_ERROR; + pci->write_io_8(device, channel->bus_master_base + IDE_BM_STATUS_REG, + newStatus); - pci->write_io_8(device, channel->bus_master_base + ide_bm_status_reg, - *(uint8 *)&new_status); - - if (status.error) + if ((status & IDE_BM_STATUS_ERROR) != 0) return B_ERROR; - if (!status.interrupt) { - if (status.active) { + if ((status & IDE_BM_STATUS_INTERRUPT) == 0) { + if ((status & IDE_BM_STATUS_ACTIVE) != 0) { SHOW_ERROR0( 2, "DMA transfer aborted" ); return B_ERROR; } @@ -308,7 +307,7 @@ ide_adapter_finish_dma(ide_adapter_channel_info *channel) return B_DEV_DATA_UNDERRUN; } - if (status.active) { + if ((status & IDE_BM_STATUS_ACTIVE) != 0) { SHOW_ERROR0( 2, "DMA transfer: buffer too large" ); return B_DEV_DATA_OVERRUN; } @@ -473,7 +472,6 @@ ide_adapter_detect_channel(pci_device_module_info *pci, pci_device pci_device, device_node_handle *node, bool supports_compatibility_mode) { uint8 api; - ide_bm_status status; io_resource_handle resource_handles[3]; SHOW_FLOW0( 3, "" ); @@ -482,12 +480,12 @@ ide_adapter_detect_channel(pci_device_module_info *pci, pci_device pci_device, api = pci->read_pci_config(pci_device, PCI_class_api, 1); if (supports_compatibility_mode - && is_primary && (api & ide_api_primary_native) == 0) { + && is_primary && (api & IDE_API_PRIMARY_NATIVE) == 0) { command_block_base = 0x1f0; control_block_base = 0x3f6; intnum = 14; } else if (supports_compatibility_mode - && !is_primary && (api & ide_api_primary_native) == 0) { + && !is_primary && (api & IDE_API_PRIMARY_NATIVE) == 0) { command_block_base = 0x170; control_block_base = 0x376; intnum = 15; @@ -509,9 +507,10 @@ ide_adapter_detect_channel(pci_device_module_info *pci, pci_device pci_device, if (supports_compatibility_mode) { // read status of primary(!) channel to detect simplex - *(uint8 *)&status = pci->read_io_8(pci_device, bus_master_base + ide_bm_status_reg); + uint8 status = pci->read_io_8(pci_device, bus_master_base + + IDE_BM_STATUS_REG); - if (status.simplex && !is_primary) { + if (status & IDE_BM_STATUS_SIMPLEX_DMA && !is_primary) { // in simplex mode, channels cannot operate independantly of each other; // we simply disable bus mastering of second channel to satisfy that; // better were to use a controller lock, but this had to be done in the IDE @@ -588,9 +587,10 @@ ide_adapter_uninit_controller(ide_adapter_controller_info *controller) static void -ide_adapter_controller_removed(device_node_handle node, ide_adapter_controller_info *controller) +ide_adapter_controller_removed(device_node_handle node, + ide_adapter_controller_info *controller) { - SHOW_FLOW0( 3, "" ); + SHOW_FLOW0(3, ""); if (controller != NULL) // disable access instantly; unit_device takes care of unregistering ioports