From 14d5277c14ed8f635d68e7a186c7770017cfe4f2 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 19 Apr 2009 23:02:54 +0000 Subject: [PATCH] Remove dead code of ATA bus_manager. Note that the new ATA bus_manager now has it's own target named ata and doesn't reuse the ide name. Because of that we can also add it to the build by default. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30271 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/Jamfile | 2 +- src/add-ons/kernel/bus_managers/ata/Jamfile | 17 - .../bus_managers/ata/KernelExport_ext.h | 31 - src/add-ons/kernel/bus_managers/ata/ata.c | 1153 ----------------- .../kernel/bus_managers/ata/ata_request.c | 166 --- .../kernel/bus_managers/ata/ata_request.h | 35 - .../kernel/bus_managers/ata/ata_tracing.cpp | 61 - .../kernel/bus_managers/ata/ata_tracing.h | 32 - src/add-ons/kernel/bus_managers/ata/atapi.c | 544 -------- .../kernel/bus_managers/ata/channels.c | 109 -- src/add-ons/kernel/bus_managers/ata/devices.c | 189 --- src/add-ons/kernel/bus_managers/ata/dma.c | 141 -- .../kernel/bus_managers/ata/emulation.c | 77 -- src/add-ons/kernel/bus_managers/ata/ide.c | 21 - .../kernel/bus_managers/ata/ide_cmds.h | 64 - .../bus_managers/ata/ide_device_infoblock.h | 195 --- .../kernel/bus_managers/ata/ide_internal.h | 283 ---- src/add-ons/kernel/bus_managers/ata/ide_sim.c | 517 -------- src/add-ons/kernel/bus_managers/ata/ide_sim.h | 21 - src/add-ons/kernel/bus_managers/ata/pio.c | 370 ------ .../kernel/bus_managers/ata/scsi2ata.c | 575 -------- src/add-ons/kernel/bus_managers/ata/sync.c | 346 ----- .../kernel/bus_managers/ata/virtual_memory.c | 121 -- src/add-ons/kernel/bus_managers/ata/wrapper.h | 90 -- 24 files changed, 1 insertion(+), 5159 deletions(-) delete mode 100644 src/add-ons/kernel/bus_managers/ata/KernelExport_ext.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/ata.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/ata_request.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/ata_request.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/ata_tracing.cpp delete mode 100644 src/add-ons/kernel/bus_managers/ata/ata_tracing.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/atapi.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/channels.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/devices.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/dma.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/emulation.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide_cmds.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide_device_infoblock.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide_internal.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide_sim.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/ide_sim.h delete mode 100644 src/add-ons/kernel/bus_managers/ata/pio.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/scsi2ata.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/sync.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/virtual_memory.c delete mode 100644 src/add-ons/kernel/bus_managers/ata/wrapper.h diff --git a/src/add-ons/kernel/bus_managers/Jamfile b/src/add-ons/kernel/bus_managers/Jamfile index 739e1cfee1..319c6317a4 100644 --- a/src/add-ons/kernel/bus_managers/Jamfile +++ b/src/add-ons/kernel/bus_managers/Jamfile @@ -4,7 +4,7 @@ SubInclude HAIKU_TOP src add-ons kernel bus_managers acpi ; SubInclude HAIKU_TOP src add-ons kernel bus_managers agp_gart ; SubInclude HAIKU_TOP src add-ons kernel bus_managers config_manager ; SubInclude HAIKU_TOP src add-ons kernel bus_managers firewire ; -#SubInclude HAIKU_TOP src add-ons kernel bus_managers ata ; +SubInclude HAIKU_TOP src add-ons kernel bus_managers ata ; SubInclude HAIKU_TOP src add-ons kernel bus_managers ide ; SubInclude HAIKU_TOP src add-ons kernel bus_managers isa ; SubInclude HAIKU_TOP src add-ons kernel bus_managers pci ; diff --git a/src/add-ons/kernel/bus_managers/ata/Jamfile b/src/add-ons/kernel/bus_managers/ata/Jamfile index b6025d2b04..005400108b 100644 --- a/src/add-ons/kernel/bus_managers/ata/Jamfile +++ b/src/add-ons/kernel/bus_managers/ata/Jamfile @@ -3,23 +3,6 @@ SubDir HAIKU_TOP src add-ons kernel bus_managers ata ; UsePrivateHeaders drivers ; UsePrivateKernelHeaders ; -KernelAddon ide : - ata.c - ata_tracing.cpp - ata_request.c - atapi.c - channels.c - devices.c - dma.c - emulation.c - ide.c - ide_sim.c - pio.c - scsi2ata.c - sync.c - virtual_memory.c - ; - KernelAddon ata : ATAChannel.cpp ATADevice.cpp diff --git a/src/add-ons/kernel/bus_managers/ata/KernelExport_ext.h b/src/add-ons/kernel/bus_managers/ata/KernelExport_ext.h deleted file mode 100644 index e40037edbb..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/KernelExport_ext.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2004-2006, Haiku, Inc. All RightsReserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - Functions that are missing in kernel. -*/ - -#ifndef _KERNEL_EXPORT_EXT_H -#define _KERNEL_EXPORT_EXT_H - -#include -#include - - -// get memory map of iovec -status_t get_iovec_memory_map( - iovec *vec, // iovec to analyze - size_t vec_count, // number of entries in vec - size_t vec_offset, // number of bytes to skip at beginning of vec - size_t len, // number of bytes to analyze - physical_entry *map, // resulting memory map - size_t max_entries, // max number of entries in map - size_t *num_entries, // actual number of map entries used - size_t *mapped_len // actual number of bytes described by map -); - -#endif // _KERNEL_EXPORT_EXT_H diff --git a/src/add-ons/kernel/bus_managers/ata/ata.c b/src/add-ons/kernel/bus_managers/ata/ata.c deleted file mode 100644 index ce8589c918..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ata.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* -** Copyright 2002/03, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - -/* - Part of Open IDE bus manager - - ATA command protocol -*/ - - -#include "ide_internal.h" - -#include "ide_sim.h" -#include "ide_cmds.h" -#include "ata_tracing.h" - -#define TRACE dprintf -#define FLOW dprintf - - -static void ata_exec_dma_transfer(ata_request *request); -static void ata_exec_pio_transfer(ata_request *request); -status_t ata_wait_idle(ide_bus_info *bus); -status_t ata_read_status(ide_device_info *device, uint8 *status); - - -void -ata_select_device(ide_bus_info *bus, int device) -{ - ide_task_file tf; - - T2(bus, device, "ata_select_device"); - -// FLOW("ata_select_device device %d\n", device); - - tf.chs.head = 0; - tf.chs.mode = ide_mode_lba; - tf.chs.device = device ? 1 : 0; - - bus->controller->write_command_block_regs(bus->channel_cookie, &tf, ide_mask_device_head); - bus->controller->get_altstatus(bus->channel_cookie); // flush posted writes - spin(1); // wait 400 nsec - - // for debugging only - bus->controller->read_command_block_regs(bus->channel_cookie, &tf, ide_mask_device_head); - if (tf.chs.device != device) { - T2(bus, device, "ata_select_device failed, device not selected. head 0x%x, mode 0x%x, device %d", tf.chs.head, tf.chs.mode, tf.chs.device); - TRACE("ata_select_device result: device %d not selected! head 0x%x, mode 0x%x, device %d\n", device, tf.chs.head, tf.chs.mode, tf.chs.device); - } -} - - -void -ata_select(ide_device_info *device) -{ - T(device, "ata_select"); - - ASSERT(device->is_device1 == device->tf.chs.device); - ata_select_device(device->bus, device->is_device1); -} - - -/* Detect if the device is present - * This is unrelyable for some controllers and - * may report false posives. - */ -bool -ata_is_device_present(ide_bus_info *bus, int device) -{ - ide_task_file tf; - bool present; - - T2(bus, device, "ata_is_device_present ?"); - - ata_select_device(bus, device); - - tf.lba.sector_count = 0xaa; - tf.lba.lba_0_7 = 0x55; - bus->controller->write_command_block_regs(bus->channel_cookie, &tf, - ide_mask_sector_count | ide_mask_LBA_low); - bus->controller->get_altstatus(bus->channel_cookie); // flush posted writes - spin(1); - - bus->controller->read_command_block_regs(bus->channel_cookie, &tf, - ide_mask_sector_count | ide_mask_LBA_low); - - present = tf.lba.sector_count == 0xaa && tf.lba.lba_0_7 == 0x55; - - T2(bus, device, "ata_is_device_present present=%d", present); - - return present; -} - - -/** busy-wait for device - * set - bits of status register that must be set - * cleared - bits of status register that must be cleared - * flags - 0 or ATA_CHECK_ERROR_BIT abort if error bit is set - * timeout - waiting timeout - */ -status_t -ata_wait(ide_bus_info *bus, uint8 set, uint8 cleared, - ata_flags flags, bigtime_t timeout) -{ - bigtime_t startTime = system_time(); - bigtime_t elapsedTime = 0; - uint8 status; - - bus->controller->get_altstatus(bus->channel_cookie); // flush posted writes - spin(1); // device needs 400ns to set status - - for (;;) { - status = bus->controller->get_altstatus(bus->channel_cookie); - - if ((flags & ATA_CHECK_ERROR_BIT) && (status & ide_status_err) != 0) - return B_ERROR; - - if ((status & set) == set && (status & cleared) == 0) { - return B_OK; - } - - elapsedTime = system_time() - startTime; - - if (elapsedTime > timeout) - return B_TIMED_OUT; - - // The device may be ready almost immediatelly. If it isn't, - // poll often during the first 20ms, otherwise poll lazyly. - if (elapsedTime < 500) - spin(1); - else if (elapsedTime < 20000) - snooze(1000); - else - snooze(50000); - } -} - - -// busy-wait for data request going high -status_t -ata_wait_for_drq(ide_bus_info *bus) -{ - return ata_wait(bus, ide_status_drq, 0, ATA_CHECK_ERROR_BIT, 10000000); -} - - -// busy-wait for data request going low -status_t -ata_wait_for_drqdown(ide_bus_info *bus) -{ - return ata_wait(bus, 0, ide_status_drq, ATA_CHECK_ERROR_BIT, 1000000); -} - - -// busy-wait for device ready -status_t -ata_wait_for_drdy(ide_bus_info *bus) -{ - return ata_wait(bus, ide_status_drdy, ide_status_bsy, 0, 5000000); -} - - -// wait 20ms for device to report idle (busy and drq clear) -status_t -ata_wait_idle(ide_bus_info *bus) -{ - return ata_wait(bus, 0, ide_status_bsy | ide_status_drq, 0, 20000); -} - - -status_t -ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags, bigtime_t timeout) -{ - ide_bus_info *bus = device->bus; - - ASSERT((device->tf_param_mask & ide_mask_command) == 0); -// ASSERT(bus->state == ata_state_busy); // XXX fix this - - ASSERT((flags & ATA_DMA_TRANSFER) == 0); // XXX only pio for now - -/* - FLOW("ata_send_command: %d:%d, request %p, ccb %p, tf %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", - device->target_id, device->is_device1, - request, request ? request->ccb : NULL, - device->tf.raw.r[0], device->tf.raw.r[1], device->tf.raw.r[2], - device->tf.raw.r[3], device->tf.raw.r[4], device->tf.raw.r[5], - device->tf.raw.r[6], device->tf.raw.r[7], device->tf.raw.r[8], - device->tf.raw.r[9], device->tf.raw.r[10], device->tf.raw.r[11]); -*/ - - // disable Interrupts for PIO transfers - if ((flags & ATA_DMA_TRANSFER) == 0) { - if (bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien) != B_OK) - goto err; - } - - ata_select(device); - - if (ata_wait_idle(bus) != B_OK) { - // resetting the device here will discard current configuration, - // it's better when the SCSI bus manager requests an external reset. - TRACE("ata_send_command: device selection timeout\n"); - ata_request_set_status(request, SCSI_SEL_TIMEOUT); - return B_ERROR; - } - - if ((flags & ATA_DRDY_REQUIRED) && (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) { - TRACE("ata_send_command: drdy not set\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return B_ERROR; - } - - // write parameters - if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, device->tf_param_mask) != B_OK) - goto err; - -// FLOW("Writing command 0x%02x\n", (int)device->tf.write.command); - - IDE_LOCK(bus); - - if (flags & ATA_DMA_TRANSFER) { - // enable interrupt - if (bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3) != B_OK) - goto err_clearint; - } - - // start the command - if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_command) != B_OK) - goto err_clearint; - -// ASSERT(bus->state == ata_state_busy); XXX fix this - - bus->state = (flags & ATA_DMA_TRANSFER) ? ata_state_dma : ata_state_pio; - request->timeout = timeout; - - IDE_UNLOCK(bus); - - return B_OK; - - -err_clearint: - bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien); - -err: - ata_request_set_status(request, SCSI_HBA_ERR); - IDE_UNLOCK(bus); - return B_ERROR; -} - - -/** check result of ATA command - * drdy_required - true if drdy must be set by device - * error_mask - bits to be checked in error register - * is_write - true, if command was a write command - */ - -status_t -ata_finish_command(ide_device_info *device, ata_request *request, ata_flags flags, uint8 errorMask) -{ - ide_bus_info *bus = device->bus; - status_t result; - uint8 error; - - if (flags & ATA_WAIT_FINISH) { - // wait for the device to finish current command (device no longer busy) - result = ata_wait(bus, 0, ide_status_bsy, 0, request->timeout); - if (result != B_OK) { - TRACE("ata_finish_command: timeout\n"); - ata_request_set_status(request, SCSI_CMD_TIMEOUT); - return result; - } - } - - // read status, this also acknowledges pending interrupts - result = device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &device->tf, ide_mask_status | ide_mask_error); - if (result != B_OK) { - TRACE("ata_finish_command: status register read failed\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return result; - } - - if (device->tf.read.status & ide_status_bsy) { - TRACE("ata_finish_command: failed! device still busy\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return B_ERROR; - } - - if ((flags & ATA_DRDY_REQUIRED) && (device->tf.read.status & ide_status_drdy) == 0) { - TRACE("ata_finish_command: failed! drdy not set\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return B_ERROR; - } - - if ((device->tf.read.status & ide_status_err) == 0) - return B_OK; - - result = device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &device->tf, ide_mask_error); - if (result != B_OK) { - TRACE("ata_finish_command: error register read failed\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return result; - } - - TRACE("ata_finish_command: command failed ERR bit is set\n"); - - // check only relevant error bits - error = device->tf.read.error & errorMask; - result = B_ERROR; - - if (error & ide_error_icrc) { - ata_request_set_sense(request, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC); - return B_ERROR; - } - - if (flags & ATA_IS_WRITE) { - if (error & ide_error_wp) { - ata_request_set_sense(request, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED); - return B_ERROR; - } - } else { - if (error & ide_error_unc) { - ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR); - return B_ERROR; - } - } - - if (error & ide_error_mc) { - // XXX proper sense key? - ata_request_set_sense(request, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED); - return B_ERROR; - } - - if (error & ide_error_idnf) { - // XXX strange error code, don't really know what it means - ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR); - return B_ERROR; - } - - if (error & ide_error_mcr) { - // XXX proper sense key? - ata_request_set_sense(request, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED); - return B_ERROR; - } - - if (error & ide_error_nm) { - ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM); - return B_ERROR; - } - - if (error & ide_error_abrt) { - ata_request_set_sense(request, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE); - return B_ERROR; - } - - // either there was no error bit set or it was masked out - ata_request_set_sense(request, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); - return B_ERROR; -} - - -status_t -ata_read_status(ide_device_info *device, uint8 *status) -{ - status_t result = device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &device->tf, ide_mask_status); - if (status) - *status = device->tf.read.status; - return result; -} - - -status_t -ata_reset_bus(ide_bus_info *bus, bool *_devicePresent0, uint32 *_sigDev0, bool *_devicePresent1, uint32 *_sigDev1) -{ - ide_controller_interface *controller = bus->controller; - ide_channel_cookie channel = bus->channel_cookie; - bool devicePresent0; - bool devicePresent1; - ide_task_file tf; - status_t status; - - dprintf("ATA: reset_bus %p\n", bus); - - devicePresent0 = ata_is_device_present(bus, 0); - devicePresent1 = ata_is_device_present(bus, 1); - - dprintf("ATA: reset_bus: device 0: %s present\n", devicePresent0 ? "might be" : "is not"); - dprintf("ATA: reset_bus: device 1: %s present\n", devicePresent1 ? "might be" : "is not"); - - // select device 0 - ata_select_device(bus, 0); - - // disable interrupts and assert SRST for at least 5 usec - if (controller->write_device_control(channel, ide_devctrl_bit3 | ide_devctrl_nien | ide_devctrl_srst) != B_OK) - goto error; - controller->get_altstatus(channel); // flush posted writes - spin(20); - - // clear SRST and wait for at least 2 ms but (we wait 150ms like everyone else does) - if (controller->write_device_control(channel, ide_devctrl_bit3 | ide_devctrl_nien) != B_OK) - goto error; - controller->get_altstatus(channel); // flush posted writes - snooze(150000); - - if (devicePresent0) { - - ata_select_device(bus, 0); -// dprintf("altstatus device 0: %x\n", controller->get_altstatus(channel)); - - // wait up to 31 seconds for busy to clear - status = ata_wait(bus, 0, ide_status_bsy, 0, 31000000); - if (status != B_OK) { - dprintf("ATA: reset_bus: timeout\n"); - goto error; - } - - if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count | - ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high | ide_mask_error) != B_OK) - goto error; - - if (tf.read.error != 0x01 && tf.read.error != 0x81) - dprintf("ATA: device 0 failed, error code is 0x%02x\n", tf.read.error); - - if (tf.read.error >= 0x80) - dprintf("ATA: device 0 indicates that device 1 failed, error code is 0x%02x\n", tf.read.error); - - if (_sigDev0) { - *_sigDev0 = tf.lba.sector_count; - *_sigDev0 |= ((uint32)tf.lba.lba_0_7) << 8; - *_sigDev0 |= ((uint32)tf.lba.lba_8_15) << 16; - *_sigDev0 |= ((uint32)tf.lba.lba_16_23) << 24; - } - } - - if (devicePresent1) { - - ata_select_device(bus, 1); -// dprintf("altstatus device 1: %x\n", controller->get_altstatus(channel)); - - // wait up to 31 seconds for busy to clear - status = ata_wait(bus, 0, ide_status_bsy, 0, 31000000); - if (status != B_OK) { - dprintf("ATA: reset_bus: timeout\n"); - goto error; - } - - if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count | - ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high | ide_mask_error) != B_OK) - goto error; - - if (tf.read.error != 0x01) - dprintf("ATA: device 1 failed, error code is 0x%02x\n", tf.read.error); - - if (_sigDev1) { - *_sigDev1 = tf.lba.sector_count; - *_sigDev1 |= ((uint32)tf.lba.lba_0_7) << 8; - *_sigDev1 |= ((uint32)tf.lba.lba_8_15) << 16; - *_sigDev1 |= ((uint32)tf.lba.lba_16_23) << 24; - } - } - - if (_devicePresent0) - *_devicePresent0 = devicePresent0; - if (_devicePresent1) - *_devicePresent1 = devicePresent1; - - dprintf("ATA: reset_bus done\n"); - return B_OK; - -error: - dprintf("ATA: reset_bus failed\n"); - return B_ERROR; -} - - -status_t -ata_reset_device(ide_device_info *device, bool *_devicePresent) -{ - // XXX first try to reset the single device here - - dprintf("ATA: ata_reset_device %p calling ata_reset_bus\n", device); - return ata_reset_bus(device->bus, - device->is_device1 ? NULL : _devicePresent, NULL, - device->is_device1 ? _devicePresent : NULL, NULL); -} - - -/** verify that device is ready for further PIO transmission */ - -static bool -check_rw_status(ide_device_info *device, bool drqStatus) -{ -/* - ide_bus_info *bus = device->bus; - int status; - - status = bus->controller->get_altstatus(bus->channel_cookie); - - if ((status & ide_status_bsy) != 0) { - device->subsys_status = SCSI_SEQUENCE_FAIL; - return false; - } - - if (drqStatus != ((status & ide_status_drq) != 0)) { - device->subsys_status = SCSI_SEQUENCE_FAIL; - return false; - } -*/ - return true; -} - - -#if 0 -/** DPC called at - * - begin of each PIO read/write block - * - end of PUI write transmission - */ - -void -ata_dpc_PIO(ata_request *request) -{ - ide_device_info *device = request->device; - uint32 timeout = request->ccb->timeout > 0 ? - request->ccb->timeout * 1000000 : IDE_STD_TIMEOUT; - - SHOW_FLOW0(3, ""); - - if (check_rw_error(device, request) - || !check_rw_status(device, request->is_write ? device->left_blocks > 0 : true)) - { - // failure reported by device - SHOW_FLOW0( 3, "command finished unsuccessfully" ); - - finish_checksense(request); - return; - } - - if (request->is_write) { - if (device->left_blocks == 0) { - // this was the end-of-transmission IRQ - SHOW_FLOW0(3, "write access finished"); - if (!wait_for_drqdown(device)) { - SHOW_ERROR0(3, "device wants to transmit data though command is finished"); - goto finish; - } - goto finish; - } - - // wait until device requests data - SHOW_FLOW0(3, "Waiting for device ready to transmit"); - if (!wait_for_drq(device)) { - SHOW_FLOW0(3, "device not ready for data transmission - abort"); - goto finish; - } - - // start async waiting for next block/end of command - // we should start that when block is transmitted, but with bad - // luck the IRQ fires exactly between transmission and start of waiting, - // so we better start waiting too early; as we are in service thread, - // a DPC initiated by IRQ cannot overtake us, so there is no need to block - // IRQs during sent - start_waiting_nolock(device->bus, timeout, ata_state_async_waiting); - - // having a too short data buffer shouldn't happen here - // anyway - we are prepared - SHOW_FLOW0(3, "Writing one block"); - if (write_PIO_block(request, 512) == B_ERROR) - goto finish_cancel_timeout; - - --device->left_blocks; - } else { - if (device->left_blocks > 1) { - // start async waiting for next command (see above) - start_waiting_nolock(device->bus, timeout, ata_state_async_waiting); - } - - // see write - SHOW_FLOW0( 3, "Reading one block" ); - if (read_PIO_block(request, 512) == B_ERROR) - goto finish_cancel_timeout; - - --device->left_blocks; - - if (device->left_blocks == 0) { - // at end of transmission, wait for data ccb going low - SHOW_FLOW0( 3, "Waiting for device to finish transmission" ); - - if (!wait_for_drqdown(device)) - SHOW_FLOW0( 3, "Device continues data transmission - abort command" ); - - // we don't cancel timeout as no timeout is started during last block - goto finish; - } - } - - return; - -finish_cancel_timeout: - cancel_irq_timeout(device->bus); - -finish: - finish_checksense(request); -} - -#endif -/** DPC called when IRQ was fired at end of DMA transmission */ - -void -ata_dpc_DMA(ata_request *request) -{ -/* - ide_device_info *device = request->device; - bool dma_success, dev_err; - - dma_success = finish_dma(device); - dev_err = check_rw_error(device, request); - - if (dma_success && !dev_err) { - // reset error count if DMA worked - device->DMA_failures = 0; - request->ccb->data_resid = 0; - finish_checksense(request); - } else { - SHOW_ERROR0( 2, "Error in DMA transmission" ); - - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); - - if (++device->DMA_failures >= MAX_DMA_FAILURES) { - SHOW_ERROR0( 2, "Disabled DMA because of too many errors" ); - device->DMA_enabled = false; - } - - // reset queue in case queuing is active - finish_reset_queue(request); - } -*/ -} - - -// list of LBA48 opcodes -static const uint8 cmd_48[2][2] = { - { IDE_CMD_READ_SECTORS_EXT, IDE_CMD_WRITE_SECTORS_EXT }, - { IDE_CMD_READ_DMA_EXT, IDE_CMD_WRITE_DMA_EXT } -}; - - -// list of normal LBA opcodes -static const uint8 cmd_28[2][2] = { - { IDE_CMD_READ_SECTORS, IDE_CMD_WRITE_SECTORS }, - { IDE_CMD_READ_DMA, IDE_CMD_WRITE_DMA } -}; - - -/** create IDE read/write command */ - -static bool -create_rw_taskfile(ide_device_info *device, ata_request *request, - uint64 pos, size_t length, bool write) -{ - SHOW_FLOW0( 3, "" ); - - // XXX disable any writes -/* if( write ) - goto err;*/ - - if (device->use_LBA) { - if (device->use_48bits && (pos + length > 0xfffffff || length > 0x100)) { - // use LBA48 only if necessary - SHOW_FLOW0( 3, "using LBA48" ); - - if (length > 0xffff) - goto err; - - // non-queued LBA48 - device->tf_param_mask = ide_mask_sector_count_48 - | ide_mask_LBA_low_48 - | ide_mask_LBA_mid_48 - | ide_mask_LBA_high_48; - - device->tf.lba48.sector_count_0_7 = length & 0xff; - device->tf.lba48.sector_count_8_15 = (length >> 8) & 0xff; - device->tf.lba48.lba_0_7 = pos & 0xff; - device->tf.lba48.lba_8_15 = (pos >> 8) & 0xff; - device->tf.lba48.lba_16_23 = (pos >> 16) & 0xff; - device->tf.lba48.lba_24_31 = (pos >> 24) & 0xff; - device->tf.lba48.lba_32_39 = (pos >> 32) & 0xff; - device->tf.lba48.lba_40_47 = (pos >> 40) & 0xff; - device->tf.lba48.command = cmd_48[request->uses_dma][write]; - return true; - } else { - // normal LBA - SHOW_FLOW0(3, "using LBA"); - - if (length > 0x100) - goto err; - - // non-queued LBA - SHOW_FLOW0( 3, "creating normal DMA/PIO command" ); - device->tf_param_mask = ide_mask_sector_count - | ide_mask_LBA_low - | ide_mask_LBA_mid - | ide_mask_LBA_high - | ide_mask_device_head; - - device->tf.lba.sector_count = length & 0xff; - device->tf.lba.lba_0_7 = pos & 0xff; - device->tf.lba.lba_8_15 = (pos >> 8) & 0xff; - device->tf.lba.lba_16_23 = (pos >> 16) & 0xff; - device->tf.lba.lba_24_27 = (pos >> 24) & 0xf; - device->tf.lba.command = cmd_28[request->uses_dma][write]; - return true; - } - } else { - // CHS mode - // (probably, noone would notice if we'd dropped support) - uint32 track_size, cylinder_offset, cylinder; - ide_device_infoblock *infoblock = &device->infoblock; - - if (length > 0x100) - goto err; - - device->tf.chs.mode = ide_mode_chs; - - device->tf_param_mask = ide_mask_sector_count - | ide_mask_sector_number - | ide_mask_cylinder_low - | ide_mask_cylinder_high - | ide_mask_device_head; - - device->tf.chs.sector_count = length & 0xff; - - track_size = infoblock->current_heads * infoblock->current_sectors; - - if (track_size == 0) { - ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED); - return false; - } - - cylinder = pos / track_size; - - device->tf.chs.cylinder_0_7 = cylinder & 0xff; - device->tf.chs.cylinder_8_15 = (cylinder >> 8) & 0xff; - - cylinder_offset = pos - cylinder * track_size; - - device->tf.chs.sector_number = (cylinder_offset % infoblock->current_sectors + 1) & 0xff; - device->tf.chs.head = cylinder_offset / infoblock->current_sectors; - - device->tf.chs.command = cmd_28[request->uses_dma][write]; - return true; - } - - return true; - -err: - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); - return false; -} - - -/** execute read/write command - * pos - first block - * length - number of blocks - */ - -void -ata_exec_read_write(ide_device_info *device, ata_request *request, - uint64 address, size_t sectorCount, bool write) -{ - ide_bus_info *bus = device->bus; - ata_flags flags = 0; - bigtime_t timeout; - - // make a copy first as settings may get changed by user during execution - request->is_write = write; - request->uses_dma = device->DMA_enabled; - - if (request->uses_dma) { - if (!prepare_dma(device, request)) { - // fall back to PIO on error - request->uses_dma = false; - } - } - - if (!request->uses_dma) { - prep_PIO_transfer(device, request); - device->left_blocks = sectorCount; - } - - // compose command - if (!create_rw_taskfile(device, request, address, sectorCount, write)) - goto error; - - // if no timeout is specified, use standard - timeout = request->ccb->timeout > 0 ? request->ccb->timeout * 1000000 : IDE_STD_TIMEOUT; - - if (!device->is_atapi) - flags |= ATA_DRDY_REQUIRED; - if (request->uses_dma) - flags |= ATA_DMA_TRANSFER; - if (ata_send_command(device, request, flags, timeout) != B_OK) - goto error; - - // this could be executed in a DPC to improve performance - if (request->uses_dma) { - ata_exec_dma_transfer(request); - } else { - ata_exec_pio_transfer(request); - } - return; - -error: - if (request->uses_dma) - abort_dma(device, request); - ata_request_finish(request, false); -} - - -static void -ata_exec_dma_transfer(ata_request *request) -{ - ASSERT(0); -} - -static void -ata_exec_pio_transfer(ata_request *request) -{ - ide_device_info *device = request->device; - ide_bus_info *bus = device->bus; - bigtime_t timeout = request->ccb->timeout > 0 ? - request->ccb->timeout * 1000000 : IDE_STD_TIMEOUT; - -// FLOW("ata_exec_pio_transfer: length %d, left_blocks %d, left_sg_elem %d, cur_sg_ofs %d\n", -// request->ccb->data_length, device->left_blocks, device->left_sg_elem, device->cur_sg_ofs); - - - while (device->left_blocks > 0) { - - if (ata_wait(bus, ide_status_drq, ide_status_bsy, 0, timeout) != B_OK) { - TRACE("ata_exec_pio_transfer: wait failed\n"); - goto error; - } - - if (request->is_write) { -// FLOW("writing 1 block\n"); - if (write_PIO_block(request, 512) != B_OK) - goto transfer_error; - } else { -// FLOW("reading 1 block\n"); - if (read_PIO_block(request, 512) != B_OK) - goto transfer_error; - } - device->left_blocks--; - - // wait 1 pio cycle - if (device->left_blocks) - bus->controller->get_altstatus(bus->channel_cookie); - -// FLOW("%d blocks left\n", device->left_blocks); - } - - if (ata_wait_for_drqdown(bus) != B_OK) { - TRACE("ata_exec_pio_transfer: ata_wait_for_drqdown failed\n"); - goto error; - } - - ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt); - ata_request_finish(request, false /* resubmit */); - return; - -error: - TRACE("ata_exec_pio_transfer: error\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - ata_request_finish(request, false /* resubmit */); - return; - -transfer_error: - TRACE("ata_exec_pio_transfer: transfer error\n"); - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - ata_request_finish(request, false /* resubmit */); -} - - -/** check for errors reported by read/write command - * return: true, if an error occured - */ - -bool -check_rw_error(ide_device_info *device, ata_request *request) -{ -#if 0 - ide_bus_info *bus = device->bus; - uint8 status; - - status = bus->controller->get_altstatus(bus->channel_cookie); - - if ((status & ide_status_err) != 0) { - uint8 error; - - if (bus->controller->read_command_block_regs(bus->channel_cookie, - &device->tf, ide_mask_error) != B_OK) { - device->subsys_status = SCSI_HBA_ERR; - return true; - } - - error = device->tf.read.error; - - if ((error & ide_error_icrc) != 0) { - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC); - return true; - } - - if (request->is_write) { - if ((error & ide_error_wp) != 0) { - set_sense(device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED); - return true; - } - } else { - if ((error & ide_error_unc) != 0) { - set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR); - return true; - } - } - - if ((error & ide_error_mc) != 0) { - set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED); - return true; - } - - if ((error & ide_error_idnf) != 0) { - // ID not found - invalid CHS mapping (was: seek error?) - set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR); - return true; - } - - if ((error & ide_error_mcr) != 0) { - // XXX proper sense key? - // for TUR this case is not defined !? - set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED); - return true; - } - - if ((error & ide_error_nm) != 0) { - set_sense(device, SCSIS_KEY_NOT_READY, SCSIS_ASC_NO_MEDIUM); - return true; - } - - if ((error & ide_error_abrt) != 0) { - set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE); - return true; - } - - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); - return true; - } -#endif - return false; -} - - -/** execute SET FEATURE command - * set subcommand in task file before calling this - */ - -static bool -device_set_feature(ide_device_info *device, int feature) -{ - ata_request request; - ata_request_init(&request, device); - - TRACE("device_set_feature: feature %d\n", feature); - - device->tf_param_mask = ide_mask_features; - - device->tf.write.features = feature; - device->tf.write.command = IDE_CMD_SET_FEATURES; - - if (ata_send_command(device, &request, ATA_DRDY_REQUIRED, 1000000) != B_OK) - return false; - - if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt) != B_OK) - return false; - - return true; -} - - -static bool -configure_rmsn(ide_device_info *device) -{ - ide_bus_info *bus = device->bus; - ata_request request; - int i; - - if (!device->infoblock.RMSN_supported - || device->infoblock._127_RMSN_support != 1) - return true; - - if (!device_set_feature(device, IDE_CMD_SET_FEATURES_ENABLE_MSN)) - return false; - - bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, - ide_mask_LBA_mid | ide_mask_LBA_high); - - ata_request_init(&request, device); - - for (i = 0; i < 5; ++i) { - // don't use TUR as it checks not ide_error_mcr | ide_error_mc | ide_error_wp - // but: we don't check wp as well - - device->tf_param_mask = 0; - device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS; - - if (!ata_send_command(device, &request, ATA_DRDY_REQUIRED, 15000000)) - continue; - - if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, - ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc) == B_OK - || ((request.senseAsc << 8) | request.senseAscq) == SCSIS_ASC_NO_MEDIUM) - return true; - - ata_request_clear_sense(&request); - } - - return false; -} - - -static bool -disable_command_queueing(ide_device_info *device) -{ - if (!device->infoblock.DMA_QUEUED_supported) - return true; - - if (device->infoblock.RELEASE_irq_supported - && !device_set_feature( device, IDE_CMD_SET_FEATURES_DISABLE_REL_INT)) - dprintf("Cannot disable release irq\n"); - - if (device->infoblock.SERVICE_irq_supported - && !device_set_feature(device, IDE_CMD_SET_FEATURES_DISABLE_SERV_INT)) - dprintf("Cannot disable service irq\n"); - - return true; -} - - - -status_t -configure_ata_device(ide_device_info *device) -{ - ide_device_infoblock *infoblock = &device->infoblock; - uint32 chs_capacity; - - TRACE("configure_ata_device\n"); - - device->is_atapi = false; - device->exec_io = ata_exec_io; - device->last_lun = 0; - - // warning: ata == 0 means "this is ata"... - if (infoblock->_0.ata.ATA != 0) { - // CF has either magic header or CFA bit set - // we merge it to "CFA bit set" for easier (later) testing - if (*(uint16 *)infoblock == 0x848a) - infoblock->CFA_supported = true; - else - return B_ERROR; - } - - if (!infoblock->_54_58_valid) { - // normally, current_xxx contains active CHS mapping, - // but if BIOS didn't call INITIALIZE DEVICE PARAMETERS - // the default mapping is used - infoblock->current_sectors = infoblock->sectors; - infoblock->current_cylinders = infoblock->cylinders; - infoblock->current_heads = infoblock->heads; - } - - // just in case capacity_xxx isn't initialized - calculate it manually - // (seems that this information is really redundant; hopefully) - chs_capacity = infoblock->current_sectors * infoblock->current_cylinders * - infoblock->current_heads; - - infoblock->capacity_low = chs_capacity & 0xff; - infoblock->capacity_high = chs_capacity >> 8; - - // checking LBA_supported flag should be sufficient, but it seems - // that checking LBA_total_sectors is a good idea - device->use_LBA = infoblock->LBA_supported && infoblock->LBA_total_sectors != 0; - - if (device->use_LBA) { - device->total_sectors = infoblock->LBA_total_sectors; - device->tf.lba.mode = ide_mode_lba; - } else { - device->total_sectors = chs_capacity; - device->tf.chs.mode = ide_mode_chs; - } - - device->use_48bits = infoblock->_48_bit_addresses_supported; - - if (device->use_48bits) - device->total_sectors = infoblock->LBA48_total_sectors; - - if (!configure_dma(device) - || !disable_command_queueing(device) - || !configure_rmsn(device)) - return B_ERROR; - - return B_OK; -} - - -status_t -ata_identify_device(ide_device_info *device, bool isAtapi) -{ - ata_request request; - ide_bus_info *bus = device->bus; - - TRACE("ata_identify_device: bus %p, device %d, isAtapi %d\n", device->bus, device->is_device1, isAtapi); - - ata_request_init(&request, device); - - ata_select(device); - - device->tf_param_mask = 0; - device->tf.write.command = isAtapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE : IDE_CMD_IDENTIFY_DEVICE; - - if (ata_send_command(device, &request, isAtapi ? 0 : ATA_DRDY_REQUIRED, 20000000) != B_OK) { - TRACE("ata_identify_device: send_command failed\n"); - return B_ERROR; - } - - if (ata_wait(bus, ide_status_drq, ide_status_bsy, 0, isAtapi ? 20000000 : 500000) != B_OK) { - TRACE("ata_identify_device: wait failed\n"); - return B_ERROR; - } - - // get the infoblock - bus->controller->read_pio(bus->channel_cookie, (uint16 *)&device->infoblock, - sizeof(device->infoblock) / sizeof(uint16), false); - - if (ata_wait_for_drqdown(bus) != B_OK) { - TRACE("ata_identify_device: ata_wait_for_drqdown failed\n"); - return B_ERROR; - } - - if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ( isAtapi ? 0 : ATA_DRDY_REQUIRED), ide_error_abrt) != B_OK) - return B_ERROR; - - TRACE("ata_identify_device: success\n"); - return B_OK; -} diff --git a/src/add-ons/kernel/bus_managers/ata/ata_request.c b/src/add-ons/kernel/bus_managers/ata/ata_request.c deleted file mode 100644 index 6ea7bdc6a4..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ata_request.c +++ /dev/null @@ -1,166 +0,0 @@ - -#include "ata_request.h" -#include "ide_internal.h" -#include "scsi_cmds.h" -#include - -#define TRACE dprintf - - -void -ata_request_init(ata_request *request, struct ide_device_info *device) -{ - memset(request, 0, sizeof(*request)); - request->device = device; -} - - -/*! Start the request, but don't clear sense to allow - retrieving the previous sense data. -*/ -void -ata_request_start(ata_request **_request, struct ide_device_info *device, - struct scsi_ccb *ccb) -{ - ata_request *request; - - IDE_LOCK(device->bus); - if (device->bus->state != ata_state_idle) { - request = NULL; - } else { - ASSERT(device->requestFree != NULL); - ASSERT(device->requestActive == NULL); - ASSERT(device->bus->active_device == NULL); - - device->bus->state = ata_state_busy; - device->bus->active_device = device; - - request = device->requestFree; - device->requestActive = request; - device->requestFree = NULL; - } - IDE_UNLOCK(device->bus); - - *_request = request; - - if (!request) - return; // bus was busy - - ASSERT(request->device == device); - - request->ccb = ccb; -/* - already set - request->is_write = 0; - request->uses_dma = 0; - request->packet_irq = 0; -*/ - - // XXX the following always triggers. Why? - // ASSERT(request->ccb->subsys_status == SCSI_REQ_INPROG); - - // pretend success - request->ccb->subsys_status = SCSI_REQ_CMP; - - // device_status always remains set to SCSI_STATUS_GOOD - // except when ata_request_set_checkcondition() is called. - request->ccb->device_status = SCSI_STATUS_GOOD; -} - - -void -ata_request_clear_sense(ata_request *request) -{ - request->senseKey = 0; - request->senseAsc = 0; - request->senseAscq = 0; -} - - -void -ata_request_set_status(ata_request *request, uint8 status) -{ - ASSERT(status != SCSI_REQ_CMP); - if (request && request->ccb) - request->ccb->subsys_status = status; -} - - -void -ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq) -{ - if (request) { - request->senseKey = key; - request->senseAsc = asc_acq >> 8; - request->senseAscq = asc_acq & 0xff; - } -} - - -void -ata_request_finish(ata_request *request, bool resubmit) -{ - scsi_ccb *ccb = request->ccb; - - ASSERT(ccb); - - if (ccb->subsys_status != SCSI_REQ_CMP || request->senseKey) { - TRACE("ata_request_finish: request %p, subsys_status 0x%02x, senseKey " - "%02x\n", request, ccb->subsys_status, request->senseKey); - } - - // when the request completed and has set sense - // data, report this to the scsi stack by setting - // CHECK CONDITION status - if (ccb->subsys_status == SCSI_REQ_CMP && request->senseKey != 0) { - - TRACE("ata_request_finish - setting check condition\n"); - - request->ccb->subsys_status = SCSI_REQ_CMP_ERR; - request->ccb->device_status = SCSI_STATUS_CHECK_CONDITION; - - // copy sense data if caller requested it - if ((request->ccb->flags & SCSI_DIS_AUTOSENSE) == 0) { - scsi_sense sense; - int sense_len; - - TRACE("ata_request_finish - copying autosense data\n"); - - // we cannot copy sense directly as sense buffer may be too small - scsi_set_sense(&sense, request); - - ASSERT(sizeof(request->ccb->sense) == SCSI_MAX_SENSE_SIZE); - - sense_len = min(sizeof(request->ccb->sense), sizeof(sense)); - - memcpy(request->ccb->sense, &sense, sense_len); - request->ccb->sense_resid = SCSI_MAX_SENSE_SIZE - sense_len; - request->ccb->subsys_status |= SCSI_AUTOSNS_VALID; - - // device sense gets reset once it's read - ata_request_clear_sense(request); - - ASSERT(request->ccb->subsys_status - == (SCSI_REQ_CMP_ERR | SCSI_AUTOSNS_VALID)); - ASSERT(request->ccb->device_status == SCSI_STATUS_CHECK_CONDITION); - } - } - - IDE_LOCK(request->device->bus); - ASSERT(request->device->bus->state != ata_state_idle); - ASSERT(request->device->bus->active_device == request->device); - ASSERT(request->device->requestActive == request); - ASSERT(request->device->requestFree == NULL); - request->device->bus->state = ata_state_idle; - request->device->bus->active_device = NULL; - request->device->requestActive = NULL; - request->device->requestFree = request; - IDE_UNLOCK(request->device->bus); - - ACQUIRE_BEN(&request->device->bus->status_report_ben); - if (resubmit) - scsi->resubmit(ccb); - else - scsi->finished(ccb, 1); - RELEASE_BEN(&request->device->bus->status_report_ben); -} diff --git a/src/add-ons/kernel/bus_managers/ata/ata_request.h b/src/add-ons/kernel/bus_managers/ata/ata_request.h deleted file mode 100644 index 653ebc9112..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ata_request.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2008 Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _ATA_REQUEST_H -#define _ATA_REQUEST_H - -#include - -typedef struct ata_request { - - struct ide_device_info * device; - struct scsi_ccb * ccb; // basic scsi request - uint8 is_write : 1; // true for write request - uint8 uses_dma : 1; // true if using dma - uint8 packet_irq : 1; // true if waiting for command packet irq - - uint8 senseKey; - uint8 senseAsc; - uint8 senseAscq; - - bigtime_t timeout; -} ata_request; - -struct scsi_ccb; -struct ide_device_info; - -void ata_request_init(ata_request *request, struct ide_device_info *device); -void ata_request_start(ata_request **_request, struct ide_device_info *device, struct scsi_ccb *ccb); -void ata_request_clear_sense(ata_request *request); -void ata_request_set_status(ata_request *request, uint8 status); -void ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq); -void ata_request_finish(ata_request *request, bool resubmit); - -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/ata_tracing.cpp b/src/add-ons/kernel/bus_managers/ata/ata_tracing.cpp deleted file mode 100644 index e5f1b57f0f..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ata_tracing.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2008, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#include -#include - -#include "ata_tracing.h" -#include "ide_internal.h" - -#if ATA_TRACING - -class ATATraceEntry : public AbstractTraceEntry { - public: - ATATraceEntry(int bus, int device, const char *info) - : fBus(bus) - , fDevice(device) - , fInfo(alloc_tracing_buffer_strcpy(info, 666, false)) - { - Initialized(); - } - - void AddDump(TraceOutput& out) - { - out.Print("ata %d:%d %s", fBus, fDevice, fInfo); - } - - int fBus; - int fDevice; - char *fInfo; -}; - - -extern "C" void -__ata_trace_device(ide_device_info *dev, const char *fmt, ...) -{ - char info[120]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(info, sizeof(info), fmt, ap); - va_end(ap); - - new(std::nothrow) ATATraceEntry(dev->bus->path_id, dev->is_device1, info); -} - - -extern "C" void -__ata_trace_bus_device(ide_bus_info *bus, int dev, const char *fmt, ...) -{ - char info[120]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(info, sizeof(info), fmt, ap); - va_end(ap); - - new(std::nothrow) ATATraceEntry(bus->path_id, dev, info); -} - -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/ata_tracing.h b/src/add-ons/kernel/bus_managers/ata/ata_tracing.h deleted file mode 100644 index 148baba189..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ata_tracing.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2008, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#include "tracing_config.h" - -#if ATA_TRACING - - struct ide_bus_info; - struct ide_device_info; - -#ifdef __cplusplus - extern "C" { -#endif - - void __ata_trace_device(struct ide_device_info *dev, const char *fmt, ...); - void __ata_trace_bus_device(struct ide_bus_info *bus, int dev, const char *fmt, ...); - -#ifdef __cplusplus - } -#endif - - #define T(dev, args...) __ata_trace_device(dev, args) - #define T2(bus, dev, args...) __ata_trace_bus_device(bus, dev, args) - -#else - - #define T(x...) - #define T2(x...) - -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/atapi.c b/src/add-ons/kernel/bus_managers/ata/atapi.c deleted file mode 100644 index 7040f0be77..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/atapi.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright 2004-2007, Haiku, Inc. All RightsReserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - Part of Open IDE bus manager - - ATAPI command protocol -*/ - -#include "ide_internal.h" - -#include - -#include "ide_cmds.h" -#include "ide_sim.h" - -#include - - -// used for MODE SENSE/SELECT 6 emulation; maximum size is 255 + header, -// so this is a safe bet -#define IDE_ATAPI_BUFFER_SIZE 512 - -#define TRACE dprintf -#define FLOW dprintf - - -/*! - Set sense according to error reported by device - return: true - device reported error -*/ -static bool -check_packet_error(ide_device_info *device, ata_request *request) -{ - ide_bus_info *bus = device->bus; - int status; - - status = bus->controller->get_altstatus(bus->channel_cookie); - - if ((status & (ide_status_err | ide_status_df)) != 0) { - int error; - - SHOW_FLOW(3, "packet error, status=%02x", status); - - if (bus->controller->read_command_block_regs(bus->channel_cookie, - &device->tf, ide_mask_error) != B_OK) { - ata_request_set_status(request, SCSI_HBA_ERR); - return true; - } - - // the upper 4 bits contain sense key - // we don't want to clutter syslog with "not ready" and UA messages, - // so use FLOW messages for them - error = device->tf.read.error; - if ((error >> 4) == SCSIS_KEY_NOT_READY - || (error >> 4) == SCSIS_KEY_UNIT_ATTENTION) - SHOW_FLOW(3, "error=%x", error); - else - SHOW_ERROR(3, "error=%x", error); - - // ATAPI says that: - // "ABRT shall be set to one if the requested command has been command - // aborted because the command code or a command parameter is invalid. - // ABRT may be set to one if the device is not able to complete the - // action requested by the command." - // Effectively, it can be set if "something goes wrong", including - // if the medium got changed. Therefore, we currently ignore the bit - // and rely on auto-sense information - /* - if ((error & ide_error_abrt) != 0) { - // if command got aborted, there's no point in reading sense - set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE); - return false; - } - */ - - // tell SCSI layer that sense must be requested - // (we don't take care of auto-sense ourselve) - - // XXX broken! - -/* device->subsys_status = SCSI_REQ_CMP_ERR; - request->ccb->device_status = SCSI_STATUS_CHECK_CONDITION; - // reset pending emulated sense - its overwritten by a real one - device->combined_sense = 0; -*/ - return true; - } - - return false; -} - - -/*! IRQ handler of packet transfer (executed as DPC) */ -void -packet_dpc(ata_request *request) -{ -#if 0 - ide_device_info *device = request->device; - ide_bus_info *bus = device->bus; - int status; - uint32 timeout = request->ccb->timeout > 0 ? - request->ccb->timeout * 1000000 : IDE_STD_TIMEOUT; - - SHOW_FLOW0(3, ""); - - bus->controller->read_command_block_regs(bus->channel_cookie, - &device->tf, ide_mask_error | ide_mask_ireason); - - status = bus->controller->get_altstatus(bus->channel_cookie); - - if (request->packet_irq) { - // device requests packet - request->packet_irq = false; - - if (!device->tf.packet_res.cmd_or_data - || device->tf.packet_res.input_or_output - || (status & ide_status_drq) == 0) { - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - goto err; - } - - start_waiting_nolock(device->bus, timeout, ide_state_async_waiting); - - // send packet - if (bus->controller->write_pio(bus->channel_cookie, - (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16), - true) != B_OK) { - SHOW_ERROR0( 1, "Error sending command packet" ); - - ata_request_set_status(request, SCSI_HBA_ERR); - goto err_cancel_timer; - } - - return; - } - - if (request->uses_dma) { - // DMA transmission finished - bool dma_err, dev_err; - - // don't check drq - if there is some data left, we cannot handle - // it anyway - // XXX does the device throw remaining data away on DMA overflow? - SHOW_FLOW0(3, "DMA done"); - - dma_err = !finish_dma(device); - dev_err = check_packet_error(device, request); - - // what to do if both the DMA controller and the device reports an error? - // let's assume that the DMA controller got problems because there was a - // device error, so we ignore the dma error and use the device error instead - if (dev_err) { - finish_checksense(request); - return; - } - - // device is happy, let's see what the controller says - if (!dma_err) { - // if DMA works, reset error counter so we don't disable - // DMA only because it didn't work once in a while - device->DMA_failures = 0; - // this is a lie, but there is no way to find out - // how much has been transmitted - request->ccb->data_resid = 0; - finish_checksense(request); - } else { - // DMA transmission went wrong - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); - - if (++device->DMA_failures >= MAX_DMA_FAILURES) { - SHOW_ERROR0(1, "Disabling DMA because of too many errors"); - - device->DMA_enabled = false; - } - - finish_checksense(request); - } - - return; - } - - // PIO mode - if ((status & ide_status_drq) != 0) { - // device wants to transmit data - int length; - status_t err; - - SHOW_FLOW0(3, "data transmission"); - - if (device->tf.packet_res.cmd_or_data) { - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - goto err; - } - - // check whether transmission direction matches - if ((device->tf.packet_res.input_or_output ^ request->is_write) == 0) { - SHOW_ERROR0(2, "data transmission in wrong way!?"); - - // TODO: hm, either the device is broken or the caller has specified - // the wrong direction - what is the proper handling? - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); - - // reset device to make it alive - // TODO: the device will abort next command with a reset condition - // perhaps we should hide that by reading sense? - SHOW_FLOW0(3, "Reset"); -// reset_device(device, request); - - finish_checksense(request); - return; - } - - // ask device how much data it wants to transmit - bus->controller->read_command_block_regs(bus->channel_cookie, - &device->tf, ide_mask_byte_count); - - length = device->tf.packet_res.byte_count_0_7 - | ((int)device->tf.packet_res.byte_count_8_15 << 8); - - SHOW_FLOW(3, "device transmittes %d bytes", length); - - // start waiting before starting transmission, else we - // could start waiting too late; - // don't mind getting overtaken by IRQ handler - as it will - // issue a DPC for the thread context we are in, we are save - start_waiting_nolock(device->bus, timeout, ide_state_async_waiting); - - if (device->tf.packet_res.input_or_output) - err = read_PIO_block(request, length); - else - err = write_PIO_block(request, length); - - // only report "real" errors; - // discarding data (ERR_TOO_BIG) can happen but is OK - if (err == B_ERROR) { - SHOW_ERROR0(2, "Error during PIO transmission"); - - ata_request_set_status(request, SCSI_HBA_ERR); - goto err_cancel_timer; - } - - SHOW_FLOW0(3, "7"); - return; - } else { - // device has done job and doesn't want to transmit data anymore - // -> finish ccb - SHOW_FLOW0(3, "no data"); - - check_packet_error(device, request); - - SHOW_FLOW(3, "finished: %d of %d left", - (int)request->ccb->data_resid, - (int)request->ccb->data_length); - - finish_checksense(request); - return; - } - - return; - -err_cancel_timer: - cancel_irq_timeout(device->bus); -err: - finish_checksense(request); -#endif -} - - -/*! Create taskfile for ATAPI packet */ -static bool -create_packet_taskfile(ide_device_info *device, ata_request *request, - bool write) -{ - scsi_ccb *ccb = request->ccb; - - SHOW_FLOW(3, "DMA enabled=%d, uses_dma=%d, scsi_cmd=%x", - device->DMA_enabled, request->uses_dma, device->packet[0]); - - device->tf_param_mask = ide_mask_features | ide_mask_byte_count; - - device->tf.packet.dma = request->uses_dma; - device->tf.packet.ovl = 0; - device->tf.packet.byte_count_0_7 = ccb->data_length & 0xff; - device->tf.packet.byte_count_8_15 = ccb->data_length >> 8; - device->tf.packet.command = IDE_CMD_PACKET; - - return true; -} - - -/*! Send ATAPI packet */ -void -send_packet(ide_device_info *device, ata_request *request, bool write) -{ -#if 0 - ide_bus_info *bus = device->bus; - bool packet_irq = device->atapi.packet_irq; - uint8 scsi_cmd = device->packet[0]; - - SHOW_FLOW( 3, "request=%p, command=%x", request, scsi_cmd ); - - /*{ - unsigned int i; - - for( i = 0; i < sizeof( device->packet ); ++i ) - dprintf( "%x ", device->packet[i] ); - }*/ - - SHOW_FLOW(3, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x (len=%d)", - device->packet[0], device->packet[1], device->packet[2], - device->packet[3], device->packet[4], device->packet[5], - device->packet[6], device->packet[7], device->packet[8], - device->packet[9], device->packet[10], device->packet[11], - request->ccb->cdb_length); - - //snooze( 1000000 ); - - request->is_write = write; - // if needed, mark first IRQ as being packet ccb IRQ - request->packet_irq = packet_irq; - - // only READ/WRITE commands can use DMA - // (the device may support it always, but IDE controllers don't - // report how much data is transmitted, and this information is - // crucial for the SCSI protocol) - // special offer: let READ_CD commands use DMA too - request->uses_dma = device->DMA_enabled - && (scsi_cmd == SCSI_OP_READ_6 || scsi_cmd == SCSI_OP_WRITE_6 - || scsi_cmd == SCSI_OP_READ_10 || scsi_cmd == SCSI_OP_WRITE_10 - || scsi_cmd == SCSI_OP_READ_12 || scsi_cmd == SCSI_OP_WRITE_12 - || scsi_cmd == SCSI_OP_READ_CD); - - // try preparing DMA, if that fails, fall back to PIO - if (request->uses_dma) { - SHOW_FLOW0(3, "0"); - if (!prepare_dma( device, request)) - request->uses_dma = false; - - SHOW_FLOW(3, "0->%d", request->uses_dma); - } - - SHOW_FLOW0(3, "1"); - - if (!request->uses_dma) - prep_PIO_transfer(device, request); - - SHOW_FLOW0(3, "2"); - - if (!create_packet_taskfile(device, request, write)) - goto err_setup; - - SHOW_FLOW0(3, "3"); - - if (!send_command(device, request, DRDY_NOT_REQUIRED, - device->atapi.packet_irq_timeout, - device->atapi.packet_irq ? ide_state_async_waiting : ide_state_accessing)) - goto err_setup; - - SHOW_FLOW0(3, "4"); - - if (packet_irq) { - // device asks for packet via IRQ; - // timeout and stuff is already set by send_command - return; - } - - SHOW_FLOW0(3, "5"); - - // wait for device to get ready for packet transmission - if (!ide_wait(device, ide_status_drq, ide_status_bsy, false, 100000)) - goto err_setup; - - SHOW_FLOW0(3, "6"); - - // make sure device really asks for command packet - bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, - ide_mask_ireason); - - if (!device->tf.packet_res.cmd_or_data - || device->tf.packet_res.input_or_output) { - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - goto err_setup; - } - - SHOW_FLOW0(3, "7"); - - // some old drives need a delay before submitting the packet - spin(10); - - // locking is evil here: as soon as the packet is transmitted, the device - // may raise an IRQ (which actually happens if the device reports an Check - // Condition error). Thus, we have to lock out the IRQ handler _before_ we - // start packet transmission, which forbids all kind of interrupts for some - // time; to reduce this period, blocking is done just before last dword is - // sent (avoid sending 16 bits as controller may transmit 32 bit chunks) - - // write packet - if (bus->controller->write_pio(bus->channel_cookie, - (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16) - 2, - true) != B_OK) { - goto err_packet; - } - - IDE_LOCK(bus); - - if (bus->controller->write_pio(bus->channel_cookie, - (uint16 *)device->packet + sizeof(device->packet) / sizeof(uint16) - 2, - 2, true) != B_OK) { - goto err_packet2; - } - - if (request->uses_dma) { - SHOW_FLOW0( 3, "ready for DMA" ); - - // S/G table must already be setup - we hold the bus lock, so - // we really have to hurry up - start_dma_wait(device, request); - } else { - uint32 timeout = request->ccb->timeout > 0 ? - request->ccb->timeout * 1000000 : IDE_STD_TIMEOUT; - - start_waiting(bus, timeout, ide_state_async_waiting); - } - - SHOW_FLOW0(3, "8"); - return; - -err_packet2: - IDE_UNLOCK(bus); - -err_packet: - data_request_set_status(request, SCSI_HBA_ERR); - -err_setup: - if (request->uses_dma) - abort_dma(device, request); - - finish_checksense(request); -#endif -} - - -/*! Execute SCSI I/O for atapi devices */ -void -atapi_exec_io(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - - TRACE("atapi_exec_io\n"); - - if (ccb->cdb[0] == SCSI_OP_REQUEST_SENSE) { - // No initial clear sense, as this request is used - // by the scsi stack to request the sense data of - // the previous command. - scsi_request_sense(device, request); - ata_request_finish(request, false /* no resubmit */); - return; - } - - ata_request_clear_sense(request); - - FLOW("command not implemented\n"); - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - ata_request_finish(request, false /* no resubmit */); - - -/* - scsi_ccb *ccb = request->ccb; - - SHOW_FLOW(3, "command=%x", request->ccb->cdb[0]); - - // ATAPI command packets are 12 bytes long; - // if the command is shorter, remaining bytes must be padded with zeros - memset(device->packet, 0, sizeof(device->packet)); - memcpy(device->packet, ccb->cdb, ccb->cdb_length); - - if (ccb->cdb[0] == SCSI_OP_REQUEST_SENSE && device->combined_sense) { - // we have a pending emulated sense - return it on REQUEST SENSE - ide_request_sense(device, request); - finish_checksense(request); - } else { - // reset all error codes for new ccb - start_request(device, request); - - // now we have an IDE packet - send_packet(device, request, - (ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_OUT); - } -*/ -} - - -/*! Prepare device info for ATAPI device */ -status_t -configure_atapi_device(ide_device_info *device) -{ - ide_device_infoblock *infoblock = &device->infoblock; - - dprintf("configure_atapi_device\n"); - - device->is_atapi = true; - device->exec_io = atapi_exec_io; - - if (infoblock->_0.atapi.ATAPI != 2) - return B_ERROR; - - switch(infoblock->_0.atapi.drq_speed) { - case 0: - case 2: - device->atapi.packet_irq = false; - break; - case 1: - device->atapi.packet_irq = true; - device->atapi.packet_irq_timeout = IDE_STD_TIMEOUT; - break; - default: - return B_ERROR; - } - - SHOW_FLOW(3, "drq speed: %d", infoblock->_0.atapi.drq_speed); - - /*if( infoblock->_0.atapi.packet_size != 0 ) - return false;*/ - - device->device_type = infoblock->_0.atapi.type; - device->last_lun = infoblock->last_lun; - - SHOW_FLOW(3, "device_type=%d, last_lun=%d", - device->device_type, device->last_lun); - - // don't use task file to select LUN but command packet - // (SCSI bus manager sets LUN there automatically) - device->tf.packet.lun = 0; - - if (!configure_dma(device)) - return B_ERROR; - - return B_OK; -} diff --git a/src/add-ons/kernel/bus_managers/ata/channels.c b/src/add-ons/kernel/bus_managers/ata/channels.c deleted file mode 100644 index 1c5437a2fb..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/channels.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/* - Manager of IDE controllers - - Whenever a new IDE channel is reported, a new SIM is - registered at the SCSI bus manager. -*/ - -#include "ide_internal.h" -#include "ide_sim.h" - -#include -#include - -#define TRACE dprintf - - -/*! Called when an IDE channel was registered by a controller driver */ -static status_t -ide_channel_added(device_node *parent) -{ - const char *controller_name = NULL; - uint32 channel_id; - - TRACE("ide_channel_added, parent is %p\n", parent); - - if (pnp->get_attr_string(parent, IDE_CONTROLLER_CONTROLLER_NAME_ITEM, - &controller_name, true) != B_OK) { - dprintf("ide: ignored controller - controller name missing\n"); - goto err; - } - - channel_id = pnp->create_id(IDE_CHANNEL_ID_GENERATOR); - - if (channel_id < 0) { - dprintf("Cannot register IDE controller %s - out of IDs", controller_name); - goto err; - } - - { - device_attr attrs[] = - { - { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, { string: SCSI_FOR_SIM_MODULE_NAME }}, - - { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, - { string: controller_name }}, - // maximum number of blocks per transmission: - // - ATAPI uses packets, i.e. normal SCSI limits apply - // but I'm not sure about controller restrictions - // - ATA allows up to 256 blocks - // - some broken disk's firmware (read: IBM DTTA drives) - // don't like 256 blocks in command queuing mode - // -> use 255 blocks as a least common nominator - // (this is still 127.5K for HDs and 510K for CDs, - // which should be sufficient) - // Note: to fix specific drive bugs, use ide_sim_get_restrictions() - // in ide_sim.c! - { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: 255 }}, - { IDE_CHANNEL_ID_ITEM, B_UINT32_TYPE, { ui32: channel_id }}, -// { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: IDE_CHANNEL_ID_GENERATOR }}, -// { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: channel_id }}, - - { NULL } - }; - - return pnp->register_node(parent, IDE_SIM_MODULE_NAME, attrs, NULL, - NULL); - } - -err: - return B_NO_MEMORY; -} - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - - default: - return B_ERROR; - } -} - - -ide_for_controller_interface ide_for_controller_module = { - { - { - IDE_FOR_CONTROLLER_MODULE_NAME, - 0, - &std_ops - }, - - NULL, // supported devices - ide_channel_added, - NULL, - NULL, - NULL - }, - - ide_irq_handler -}; diff --git a/src/add-ons/kernel/bus_managers/ata/devices.c b/src/add-ons/kernel/bus_managers/ata/devices.c deleted file mode 100644 index 80aa2b7807..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/devices.c +++ /dev/null @@ -1,189 +0,0 @@ -/* -** Copyright 2007, Marcus Overhagen. All rights reserved. -** Copyright 2002/03, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the Haiku License. -*/ - -/* - Part of Open IDE bus manager - - Device manager - - As the IDE bus manager is an SCSI to IDE translater, it - has to know a bit more about connected devices then a standard - SIM. This file contains device detection and classification. -*/ - -#include "ide_internal.h" -#include "ide_sim.h" -#include "ide_cmds.h" - -#include -#include -#include - -#define TRACE(x...) dprintf("IDE: " x) - - -static void setup_device_links(ide_bus_info *bus, ide_device_info *device); -static void cleanup_device_links(ide_device_info *device); - - -/** create device info */ -ide_device_info * -create_device(ide_bus_info *bus, bool is_device1) -{ - ide_device_info *device; - - TRACE("create_device: bus %p, device-number %d\n", bus, is_device1); - - device = (ide_device_info *)malloc(sizeof(*device)); - if (device == NULL) - return NULL; - - memset(device, 0, sizeof(*device)); - - device->is_device1 = is_device1; - device->target_id = is_device1; - - setup_device_links(bus, device); - - device->DMA_failures = 0; - device->num_failed_send = 0; - - device->total_sectors = 0; - - device->requestActive = NULL; - device->requestFree = (ata_request *)malloc(sizeof(ata_request)); - ata_request_init(device->requestFree, device); - - // disable interrupts - bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien); - - // make sure LBA bit is set, and initialize device selection flag - device->tf.chs.head = 0; - device->tf.chs.mode = ide_mode_lba; - device->tf.chs.device = is_device1; - bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_device_head); - - return device; -} - - -/** destroy device info */ -void -destroy_device(ide_device_info *device) -{ - TRACE("destroy_device: device %p\n", device); - - // paranoia - device->exec_io = NULL; - - if (device->requestActive) - dprintf("destroy_device: Warning request still active\n"); - free(device->requestFree); - - - cleanup_device_links(device); - - free(device); -} - - -/** setup links between the devices on one bus */ -static void -setup_device_links(ide_bus_info *bus, ide_device_info *device) -{ - TRACE("setup_device_links: bus %p, device %p\n", bus, device); - - device->bus = bus; - bus->devices[device->is_device1] = device; -} - - -/** cleanup links devices on one bus when is deleted */ -static void -cleanup_device_links(ide_device_info *device) -{ - ide_bus_info *bus = device->bus; - - TRACE("cleanup_device_links: device %p\n", device); - - bus->devices[device->is_device1] = NULL; -} - -#if B_HOST_IS_LENDIAN - -#define B_BENDIAN_TO_HOST_MULTI(v, n) do { \ - size_t __swap16_multi_n = (n); \ - uint16 *__swap16_multi_v = (v); \ - \ - while( __swap16_multi_n ) { \ - *__swap16_multi_v = B_SWAP_INT16(*__swap16_multi_v); \ - __swap16_multi_v++; \ - __swap16_multi_n--; \ - } \ -} while (0) - -#else - -#define B_BENDIAN_TO_HOST_MULTI(v, n) - -#endif - - -/** prepare infoblock for further use, i.e. fix endianess */ - -static void -fix_infoblock_endian(ide_device_info *device) -{ - ide_device_infoblock *infoblock = &device->infoblock; - - B_BENDIAN_TO_HOST_MULTI((uint16 *)infoblock->serial_number, - sizeof(infoblock->serial_number) / 2); - - B_BENDIAN_TO_HOST_MULTI( (uint16 *)infoblock->firmware_version, - sizeof(infoblock->firmware_version) / 2); - - B_BENDIAN_TO_HOST_MULTI( (uint16 *)infoblock->model_number, - sizeof(infoblock->model_number) / 2); - - infoblock->LBA_total_sectors = B_LENDIAN_TO_HOST_INT32(infoblock->LBA_total_sectors); - infoblock->LBA48_total_sectors = B_LENDIAN_TO_HOST_INT64(infoblock->LBA48_total_sectors); -} - - -/** scan one device */ -status_t -scan_device(ide_device_info *device, bool isAtapi) -{ - status_t result; - dprintf("ATA: scan_device\n"); - -retry: - result = ata_identify_device(device, isAtapi); - if (result != B_OK && !isAtapi) { - dprintf("ATA: scan_device: possibly ATAPI, retrying identify\n"); - isAtapi = true; - goto retry; - } - if (result != B_OK) { - dprintf("ATA: couldn't read infoblock for device %p\n", device); - return B_ERROR; - } - - fix_infoblock_endian(device); - return B_OK; -} - - -status_t -configure_device(ide_device_info *device, bool isAtapi) -{ - dprintf("ATA: configure_device\n"); - - if (isAtapi) - return configure_atapi_device(device); - else - return configure_ata_device(device); -} diff --git a/src/add-ons/kernel/bus_managers/ata/dma.c b/src/add-ons/kernel/bus_managers/ata/dma.c deleted file mode 100644 index b249655a29..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/dma.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2004-2007, Haiku, Inc. All RightsReserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -//! DMA helper functions - - -#include "ide_internal.h" - - -#define CHECK_DEV_DMA_MODE(infoblock, elem, mode, this_mode, num_modes ) \ - if( infoblock->elem ) { \ - mode = this_mode; \ - ++num_modes; \ - } - - -int -get_device_dma_mode(ide_device_info *device) -{ - ide_device_infoblock *infoblock = &device->infoblock; - - int num_modes, mode; - - mode = 0; - num_modes = 0; - - if (!infoblock->DMA_supported) - return -1; - - CHECK_DEV_DMA_MODE(infoblock, MDMA0_selected, mode, 0, num_modes); - CHECK_DEV_DMA_MODE(infoblock, MDMA1_selected, mode, 1, num_modes); - CHECK_DEV_DMA_MODE(infoblock, MDMA2_selected, mode, 2, num_modes); - - if (infoblock->_88_valid) { - CHECK_DEV_DMA_MODE(infoblock, UDMA0_selected, mode, 0x10, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA1_selected, mode, 0x11, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA2_selected, mode, 0x12, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA3_selected, mode, 0x13, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA4_selected, mode, 0x14, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA5_selected, mode, 0x15, num_modes); - CHECK_DEV_DMA_MODE(infoblock, UDMA6_selected, mode, 0x16, num_modes); - } - - if (num_modes != 1) - return -1; - - SHOW_FLOW(3, "%x", mode); - - return mode; -} - - -bool -configure_dma(ide_device_info *device) -{ - device->DMA_enabled = device->DMA_supported = device->bus->can_DMA - && get_device_dma_mode(device) != -1; - - dprintf("XXX DISABLING DMA\n"); - device->DMA_enabled = false; - - return true; -} - - -/*! Abort DMA transmission - must be called _before_ start_dma_wait -*/ -void -abort_dma(ide_device_info *device, ata_request *request) -{ - ide_bus_info *bus = device->bus; - - SHOW_FLOW0(0, ""); - - bus->controller->finish_dma(bus->channel_cookie); -} - - -/*! Prepare DMA transmission - on return, DMA engine waits for device to transmit data - warning: doesn't set sense data on error -*/ -bool -prepare_dma(ide_device_info *device, ata_request *request) -{ - ide_bus_info *bus = device->bus; - scsi_ccb *ccb = request->ccb; - status_t res; - - res = bus->controller->prepare_dma(bus->channel_cookie, ccb->sg_list, - ccb->sg_count, request->is_write); - if (res != B_OK) - return false; - - return true; -} - - -/*! Start waiting for DMA to be finished */ -void -start_dma_wait(ide_device_info *device, ata_request *request) -{ -#if 0 - ide_bus_info *bus = device->bus; - - bus->controller->start_dma(bus->channel_cookie); - - start_waiting(bus, request->ccb->timeout > 0 ? - request->ccb->timeout : IDE_STD_TIMEOUT, ide_state_async_waiting); -#endif -} - - -/*! Start waiting for DMA to be finished with bus lock not hold */ -void -start_dma_wait_no_lock(ide_device_info *device, ata_request *request) -{ - ide_bus_info *bus = device->bus; - - IDE_LOCK(bus); - start_dma_wait(device, request); -} - - -/*! Finish dma transmission after device has fired IRQ */ -bool -finish_dma(ide_device_info *device) -{ - ide_bus_info *bus = device->bus; - status_t dma_res; - - dma_res = bus->controller->finish_dma(bus->channel_cookie); - - return dma_res == B_OK || dma_res == B_DEV_DATA_OVERRUN; -} - diff --git a/src/add-ons/kernel/bus_managers/ata/emulation.c b/src/add-ons/kernel/bus_managers/ata/emulation.c deleted file mode 100644 index f734b74fbc..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/emulation.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -//! General SCSI emulation routines - - -#include "ide_internal.h" -#include "ide_sim.h" - -#include -#include - - -/*! Copy data between ccb data and buffer - ccb - ccb to copy data from/to - offset - offset of data in ccb - allocation_length- limit of ccb's data buffer according to CDB - buffer - data to copy data from/to - size - number of bytes to copy - to_buffer - true: copy from ccb to buffer - false: copy from buffer to ccb - return: true, if data of ccb was large enough -*/ -bool -copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, - void *buffer, int size, bool toBuffer) -{ - const physical_entry *sgList = ccb->sg_list; - int sgCount = ccb->sg_count; - int requestSize; - - SHOW_FLOW(3, "offset=%u, req_size_limit=%d, size=%d, sg_list=%p, sg_cnt=%d, %s buffer", - offset, allocationLength, size, sgList, sgCount, toBuffer ? "to" : "from"); - - // skip unused S/G entries - while (sgCount > 0 && offset >= sgList->size) { - offset -= sgList->size; - ++sgList; - --sgCount; - } - - if (sgCount == 0) - return 0; - - // remaining bytes we are allowed to copy from/to ccb - requestSize = min(allocationLength, ccb->data_length) - offset; - - // copy one S/G entry at a time - for (; size > 0 && requestSize > 0 && sgCount > 0; ++sgList, --sgCount) { - size_t bytes; - - bytes = min(size, requestSize); - bytes = min(bytes, sgList->size); - - SHOW_FLOW(4, "buffer=%p, virt_addr=%p, bytes=%d, to_buffer=%d", - buffer, (void *)((addr_t)sgList->address + offset), (int)bytes, - toBuffer); - - if (toBuffer) { - vm_memcpy_from_physical(buffer, (addr_t)sgList->address + offset, - bytes, false); - } else { - vm_memcpy_to_physical((addr_t)sgList->address + offset, buffer, - bytes, false); - } - - buffer = (char *)buffer + bytes; - size -= bytes; - offset = 0; - } - - return size == 0; -} diff --git a/src/add-ons/kernel/bus_managers/ata/ide.c b/src/add-ons/kernel/bus_managers/ata/ide.c deleted file mode 100644 index e60f1bf175..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/*! Contains interface used by IDE controller driver. */ - -#include "ide_internal.h" -#include "ide_sim.h" - - -device_manager_info *pnp; - - -#if !_BUILDING_kernel && !BOOT -module_info *modules[] = { - (module_info *)&ide_for_controller_module, - (module_info *)&ide_sim_module, - NULL -}; -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/ide_cmds.h b/src/add-ons/kernel/bus_managers/ata/ide_cmds.h deleted file mode 100644 index 32fea1fadf..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide_cmds.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -** Copyright 2002/03, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - -/* - Part of Open IDE bus manager - - OP-Codes of IDE commands -*/ - -#ifndef __IDE_CMDS_H__ -#define __IDE_CMDS_H__ - - -#define IDE_CMD_WRITE_DMA 0xca -#define IDE_CMD_WRITE_DMA_QUEUED 0xcc -#define IDE_CMD_WRITE_MULTIPLE 0xc5 -#define IDE_CMD_WRITE_SECTORS 0x30 - -#define IDE_CMD_READ_DMA 0xc8 -#define IDE_CMD_READ_DMA_QUEUED 0xc7 -#define IDE_CMD_READ_MULTIPLE 0xc4 -#define IDE_CMD_READ_SECTORS 0x20 - -#define IDE_CMD_WRITE_DMA_EXT 0x35 -#define IDE_CMD_WRITE_DMA_QUEUED_EXT 0x36 -#define IDE_CMD_WRITE_MULTIPLE_EXT 0x39 -#define IDE_CMD_WRITE_SECTORS_EXT 0x34 - -#define IDE_CMD_READ_DMA_EXT 0x25 -#define IDE_CMD_READ_DMA_QUEUED_EXT 0x26 -#define IDE_CMD_READ_MULTIPLE_EXT 0x29 -#define IDE_CMD_READ_SECTORS_EXT 0x24 - -#define IDE_CMD_PACKET 0xa0 -#define IDE_CMD_DEVICE_RESET 0x08 - -#define IDE_CMD_SERVICE 0xa2 -#define IDE_CMD_NOP 0 - -#define IDE_CMD_NOP_NOP 0 -#define IDE_CMD_NOP_NOP_AUTOPOLL 1 - - -#define IDE_CMD_GET_MEDIA_STATUS 0xda - -#define IDE_CMD_FLUSH_CACHE 0xe7 -#define IDE_CMD_FLUSH_CACHE_EXT 0xea - -#define IDE_CMD_MEDIA_EJECT 0xed - -#define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xa1 -#define IDE_CMD_IDENTIFY_DEVICE 0xec - -#define IDE_CMD_SET_FEATURES 0xef -#define IDE_CMD_SET_FEATURES_ENABLE_REL_INT 0x5d -#define IDE_CMD_SET_FEATURES_ENABLE_SERV_INT 0x5e -#define IDE_CMD_SET_FEATURES_DISABLE_REL_INT 0xdd -#define IDE_CMD_SET_FEATURES_DISABLE_SERV_INT 0xde -#define IDE_CMD_SET_FEATURES_ENABLE_MSN 0x95 - - -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/ide_device_infoblock.h b/src/add-ons/kernel/bus_managers/ata/ide_device_infoblock.h deleted file mode 100644 index 17d10f6c97..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide_device_infoblock.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2004-2006, Haiku, Inc. All RightsReserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ -#ifndef _IDE_DEVICE_INFOBLOCK_H_ -#define _IDE_DEVICE_INFOBLOCK_H_ - -/* - Definition of response to IDE_CMD_IDENTIFY_DEVICE or - IDE_CMD_IDENTIFY_PACKET_DEVICE - - When a new entry is inserted, add its offset in hex - and its index in decimal as a remark. Without that, you - have a rough time when you messed up the offsets. -*/ - - -#include - - -#define IDE_GET_INFO_BLOCK 0x2710 -#define IDE_GET_STATUS 0x2711 - - -// must be 512 bytes!!! -typedef struct tagdevice_infoblock { - union { // 0 general configuration - struct { - LBITFIELD8 ( - _0_res1 : 1, - _0_ret1 : 1, - response_incomplete : 1, - _0_ret2 : 3, - removable_controller_or_media : 1, - removable_media : 1, - _0_ret3 : 7, - ATA : 1 // 0 - is ATA! - ); - } ata; - struct { - LBITFIELD8 ( - packet_size : 2, // 0 - 12 bytes, 1 - 16 bytes - response_incomplete : 1, - _0_res2 : 2, - drq_speed : 2, // 0 - 3ms, 1 - IRQ, 2 - 50µs - removable_media : 1, - type : 5, - _0_res13 : 1, - ATAPI : 2 // 2 - is ATAPI - ); - } atapi; - } _0; - uint16 cylinders; // 2 - uint16 dummy1; // 4 - uint16 heads; // 6 - uint16 dummy2[2]; // 8 - uint16 sectors; // 0c - uint16 dummy3[3]; // 0e - char serial_number[20]; // 14 - uint16 dummy4[3]; // 28 - char firmware_version[8]; // 2e - char model_number[40]; // 36 - uint16 dummy5[2]; // 5e - LBITFIELD5 ( // 62 (49) capabilities - _49_ret1 : 8, - DMA_supported : 1, - LBA_supported : 1, - IORDY_can_disable : 1, - IORDY_supported : 1 - ); - - uint16 dummy6[1]; // 64 - LBITFIELD2 ( // 66 (51) obsolete: PIO modes? - _51_obs1 : 8, - PIO_mode : 8 - ); - uint16 dummy7[1]; // 68 - - LBITFIELD3 ( // 6a (53) validity - _54_58_valid : 1, - _64_70_valid : 1, - _88_valid : 1 - ); - uint16 current_cylinders; // 6c (54) - uint16 current_heads; // 6e - uint16 current_sectors; // 70 - - uint16 capacity_low; // 72 (57) ALIGNMENT SPLIT - don't merge - uint16 capacity_high; - - uint16 dummy8[1]; - - uint32 LBA_total_sectors; // 78 (60) - uint16 dummy9[1]; // 7c - - LBITFIELD7 ( // 7e (63) MDMA modes - MDMA0_supported : 1, - MDMA1_supported : 1, - MDMA2_supported : 1, - _63_res1 : 5, - MDMA0_selected : 1, - MDMA1_selected : 1, - MDMA2_selected : 1 - ); - uint16 dummy10[11]; // 80 - - LBITFIELD2 ( // 96 (75) - queue_depth : 5, - _75_res1 : 9 - ); - uint16 dummy11[6]; // 98 - - LBITFIELD16 ( // a4 (82) supported_command_set - SMART_supported : 1, - security_mode_supported : 1, - removable_media_supported : 1, - PM_supported : 1, - _81_fixed : 1, // must be 0 - write_cache_supported : 1, - look_ahead_supported : 1, - RELEASE_irq_supported : 1, - - SERVICE_irq_supported : 1, - DEVICE_RESET_supported : 1, - HPA_supported : 1, - _81_obs1 : 1, - WRITE_BUFFER_supported : 1, - READ_BUFFER_supported : 1, - NOP_supported : 1, - _81_obs2 : 1 - ); - LBITFIELD15 ( // a6 (83) supported_command_sets - DOWNLOAD_MICROCODE_supported : 1, - DMA_QUEUED_supported : 1, - CFA_supported : 1, - APM_supported : 1, - RMSN_supported : 1, - power_up_in_stand_by_supported : 1, - SET_FEATURES_on_power_up_required : 1, - reserved_boot_area_supported : 1, - SET_MAX_security_supported : 1, - auto_acustic_managemene_supported : 1, - _48_bit_addresses_supported : 1, - device_conf_overlay_supported : 1, - FLUSH_CACHE_supported : 1, - FLUSH_CACHE_EXT_supported : 1, - _83_fixed : 2 // must be 1 - ); - - uint16 dummy12[4]; // a8 (84) - LBITFIELD15 ( // b0 (88) UDMA modes - UDMA0_supported : 1, - UDMA1_supported : 1, - UDMA2_supported : 1, - UDMA3_supported : 1, - UDMA4_supported : 1, - UDMA5_supported : 1, - UDMA6_supported : 1, // !guessed - _88_res1 : 1, - UDMA0_selected : 1, - UDMA1_selected : 1, - UDMA2_selected : 1, - UDMA3_selected : 1, - UDMA4_selected : 1, - UDMA5_selected : 1, - UDMA6_selected : 1 - ); - - uint16 dummy89[11]; // b2 (89) - uint64 LBA48_total_sectors; // c8 (100) - uint16 dummy102[22]; // cc (104) - - LBITFIELD2 ( // fc (126) - last_lun : 2, - _126_res2 : 14 - ); - LBITFIELD4 ( // fe (127) RMSN support - _127_RMSN_support : 2,// 0 = not supported, 1 = supported, 3, 4 = reserved - _127_res2 : 6, - device_write_protect: 2, - _127_res9 : 6 - ); - uint16 dummy14[128]; // 100 (128) -} ide_device_infoblock; - -typedef struct ide_status { - uint8 _reserved; - uint8 dma_status; - uint8 pio_mode; - uint8 dma_mode; -} ide_status; - -#endif /* _IDE_DEVICE_INFOBLOCK_H_ */ diff --git a/src/add-ons/kernel/bus_managers/ata/ide_internal.h b/src/add-ons/kernel/bus_managers/ata/ide_internal.h deleted file mode 100644 index 0601da510e..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide_internal.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef __IDE_INTERNAL_H__ -#define __IDE_INTERNAL_H__ - -#include -#include -#include - -#include - -#include "ide_device_infoblock.h" -#include "ata_request.h" - -#define debug_level_error 2 -#define debug_level_info 1 -#define debug_level_flow 0 - -#define DEBUG_MSG_PREFIX "IDE -- " - -#include "wrapper.h" - - -#define IDE_STD_TIMEOUT 10000000 -#define IDE_RELEASE_TIMEOUT 10000000 - -// number of timeouts before we disable DMA automatically -#define MAX_DMA_FAILURES 3 - -// name of pnp generator of channel ids -#define IDE_CHANNEL_ID_GENERATOR "ide/channel_id" -// node item containing channel id (uint32) -#define IDE_CHANNEL_ID_ITEM "ide/channel_id" -// SIM interface -#define IDE_SIM_MODULE_NAME "bus_managers/ide/sim/driver_v1" - - -extern device_manager_info *pnp; -extern scsi_for_sim_interface *scsi; - -typedef struct ide_bus_info ide_bus_info; - - -// structure for device time-outs -typedef struct ide_device_timer_info { - timer te; - struct ide_device_info *device; -} ide_device_timer_info; - -// structure for bus time-outs -typedef struct ide_bus_timer_info { - timer te; - struct ide_bus_info *bus; -} ide_bus_timer_info; - - -typedef struct ide_device_info { - struct ide_bus_info *bus; - - uint8 use_LBA : 1; // true for LBA, false for CHS - uint8 use_48bits : 1; // true for LBA48 - uint8 is_atapi : 1; // true for ATAPI, false for ATA - uint8 DMA_supported : 1; // DMA supported - uint8 DMA_enabled : 1; // DMA enabled - uint8 is_device1 : 1; // true for slave, false for master - - uint8 last_lun; // last LUN - - uint8 DMA_failures; // DMA failures in a row - uint8 num_failed_send; // number of consequetive send problems - - struct ata_request * requestActive; - struct ata_request * requestFree; - - // entry for scsi's exec_io request - void (*exec_io)( struct ide_device_info *device, struct ata_request *request ); - - int target_id; // target id (currently, same as is_device1) - - ide_reg_mask tf_param_mask; // flag of valid bytes in task file - ide_task_file tf; // task file - - // ata from here on - uint64 total_sectors; // size in sectors - - // atapi from here on - uint8 packet[12]; // atapi command packet - - struct { - uint8 packet_irq : 1; // true, if command packet irq required - bigtime_t packet_irq_timeout; // timeout for it - } atapi; - - uint8 device_type; // atapi device type - - // pio from here on - int left_sg_elem; // remaining sg elements - const physical_entry *cur_sg_elem; // active sg element - int cur_sg_ofs; // offset in active sg element - - int left_blocks; // remaining blocks - - bool has_odd_byte; // remaining odd byte - int odd_byte; // content off odd byte - - ide_device_infoblock infoblock; // infoblock of device -} ide_device_info; - - -// state of ide bus -typedef enum { - ata_state_idle, // not is using it - ata_state_busy, // got bus but no command issued yet - ata_state_pio, // bus is executing a PIO command - ata_state_dma // bus is executing a DMA command -} ata_bus_state; - - -typedef enum { - ATA_DRDY_REQUIRED = 0x01, - ATA_IS_WRITE = 0x02, -// ATA_PIO_TRANSFER = 0x04, - ATA_DMA_TRANSFER = 0x08, - ATA_CHECK_ERROR_BIT = 0x10, - ATA_WAIT_FINISH = 0x20 -} ata_flags; - - -struct ide_bus_info { - // controller - ide_controller_interface *controller; - void *channel_cookie; - - // lock, used for changes of bus state - spinlock lock; - cpu_status prev_irq_state; - - ata_bus_state state; // current state of bus - - mutex status_report_ben; // to lock when you report XPT about bus state - // i.e. during requeue, resubmit or finished - - bool disconnected; // true, if controller is lost - - scsi_bus scsi_cookie; // cookie for scsi bus - - ide_bus_timer_info timer; // timeout - scsi_dpc_cookie irq_dpc; - - ide_device_info *active_device; - ide_device_info *devices[2]; - - uchar path_id; - - device_node *node; // our pnp node - - // restrictions, read from controller node - uint8 max_devices; - uint8 can_DMA; - uint8 can_CQ; - - char name[32]; -}; - - -// call this before you change bus state -#define IDE_LOCK( bus ) { \ - cpu_status prev_irq_state = disable_interrupts(); \ - acquire_spinlock( &bus->lock ); \ - bus->prev_irq_state = prev_irq_state; \ -} - -// call this after you changed bus state -#define IDE_UNLOCK( bus ) { \ - cpu_status prev_irq_state = bus->prev_irq_state; \ - release_spinlock( &bus->lock ); \ - restore_interrupts( prev_irq_state ); \ -} - - -// ata.c - -void ata_select_device(ide_bus_info *bus, int device); -void ata_select(ide_device_info *device); -bool ata_is_device_present(ide_bus_info *bus, int device); -status_t ata_wait(ide_bus_info *bus, uint8 set, uint8 not_set, ata_flags flags, bigtime_t timeout); -status_t ata_wait_for_drq(ide_bus_info *bus); -status_t ata_wait_for_drqdown(ide_bus_info *bus); -status_t ata_wait_for_drdy(ide_bus_info *bus); -status_t ata_pio_wait_drdy(ide_device_info *device); -status_t ata_reset_bus(ide_bus_info *bus, bool *_devicePresent0, uint32 *_sigDev0, bool *_devicePresent1, uint32 *_sigDev1); -status_t ata_reset_device(ide_device_info *device, bool *_devicePresent); -status_t ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags, bigtime_t timeout); -status_t ata_finish_command(ide_device_info *device, ata_request *request, ata_flags flags, uint8 errorMask); - - -bool check_rw_error(ide_device_info *device, ata_request *request); -bool check_output(ide_device_info *device, bool drdy_required, int error_mask, bool is_write); - -void ata_exec_read_write(ide_device_info *device, ata_request *request, uint64 address, size_t sectorCount, bool write); - -void ata_dpc_DMA(ata_request *request); -void ata_dpc_PIO(ata_request *request); - -void ata_exec_io(ide_device_info *device, ata_request *request); - -status_t ata_identify_device(ide_device_info *device, bool isAtapi); - -status_t configure_ata_device(ide_device_info *device); - -// atapi.c -status_t configure_atapi_device(ide_device_info *device); -void send_packet(ide_device_info *device, ata_request *request, bool write); -void packet_dpc(ata_request *request); -void atapi_exec_io(ide_device_info *device, ata_request *request); - - -// basic_prot.c - -// timeout in seconds - -// channel_mgr.c - -extern ide_for_controller_interface ide_for_controller_module; - - -// device_mgr.c - -status_t scan_device(ide_device_info *device, bool isAtapi); -void destroy_device(ide_device_info *device); -ide_device_info *create_device(ide_bus_info *bus, bool is_device1); - -status_t configure_device(ide_device_info *device, bool isAtapi); - -// dma.c - -bool prepare_dma(ide_device_info *device, ata_request *request); -void start_dma(ide_device_info *device, ata_request *request); -void start_dma_wait(ide_device_info *device, ata_request *request); -void start_dma_wait_no_lock(ide_device_info *device, ata_request *request); -bool finish_dma(ide_device_info *device); -void abort_dma(ide_device_info *device, ata_request *request); - -bool configure_dma(ide_device_info *device); -int get_device_dma_mode(ide_device_info *device); - - -// emulation.c - -bool copy_sg_data(scsi_ccb *request, uint offset, uint req_size_limit, - void *buffer, int size, bool to_buffer); -void ide_request_sense(ide_device_info *device, ata_request *request); - - -// pio.c - -void prep_PIO_transfer(ide_device_info *device, ata_request *request); -status_t read_PIO_block(ata_request *request, int length); -status_t write_PIO_block(ata_request *request, int length); - -// scsi - -struct scsi_sense; - -void scsi_set_sense(struct scsi_sense *sense, const ata_request *request); -void scsi_request_sense(ide_device_info *device, ata_request *request); - - - -// sync.c - -// timeout in seconds (according to CAM) - -void ide_dpc(void *arg); -void access_finished(ide_bus_info *bus, ide_device_info *device); - -status_t ide_irq_handler(ide_bus_info *bus, uint8 status); -status_t ide_timeout(timer *arg); - - -#endif /* __IDE_INTERNAL_H__ */ diff --git a/src/add-ons/kernel/bus_managers/ata/ide_sim.c b/src/add-ons/kernel/bus_managers/ata/ide_sim.c deleted file mode 100644 index afbc5943e3..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - Interface between ide bus manager and scsi bus manager. - - The IDE bus manager has a bit unusual structure as it - consists of a single level only. In fact it is no bus manager - in terms of the PnP structure at all but a driver that maps - one SCSI bus onto one IDE controller. - - This structure does not allow us to publish IDE devices - as they can be accessed via the SCSI bus node only. Therefore - we do a full bus scan every time the IDE bus node is loaded. - The drawback is that a bus rescan must be done indirectly via a - SCSI bus scan. -*/ - -#include "ide_internal.h" -#include "ide_sim.h" - -#include -#include - -#include -#include -#include - -//#define FLOW dprintf -#define FLOW(x...) -#define TRACE dprintf -//#define TRACE(x...) - -scsi_for_sim_interface *scsi; - - - -static void -sim_scsi_io(ide_bus_info *bus, scsi_ccb *ccb) -{ - ide_device_info *device; - ata_request *request; - - FLOW("sim_scsi_iobus %p, %d:%d\n", bus, ccb->target_id, ccb->target_lun); - - if (bus->disconnected) - goto err_disconnected; - - // make sure, device is valid - // I've read that there are ATAPI devices with more then one LUN, - // but it seems that most (all?) devices ignore LUN, so we have - // to restrict to LUN 0 to avoid mirror devices - if (ccb->target_id >= 2) - goto err_inv_device; - - device = bus->devices[ccb->target_id]; - if (device == NULL) - goto err_inv_device; - - if (ccb->target_lun > device->last_lun) - goto err_inv_device; - - ata_request_start(&request, device, ccb); - - if (request) { - FLOW("calling exec_io: %p, %d:%d\n", bus, ccb->target_id, ccb->target_lun); - device->exec_io(device, request); - return; - } - - TRACE("Bus busy %d:%d\n", ccb->target_id, ccb->target_lun); - ACQUIRE_BEN(&bus->status_report_ben); - scsi->requeue(ccb, true); - RELEASE_BEN(&bus->status_report_ben); - return; - - -err_inv_device: - FLOW("Invalid device %d:%d\n", ccb->target_id, ccb->target_lun); - ccb->subsys_status = SCSI_SEL_TIMEOUT; - ACQUIRE_BEN(&bus->status_report_ben); - scsi->finished(ccb, 1); - RELEASE_BEN(&bus->status_report_ben); - return; - - -err_disconnected: - TRACE("No controller anymore %d:%d\n", ccb->target_id, ccb->target_lun); - ccb->subsys_status = SCSI_NO_HBA; - ACQUIRE_BEN(&bus->status_report_ben); - scsi->finished(ccb, 1); - RELEASE_BEN(&bus->status_report_ben); - return; -} - - -static uchar -sim_path_inquiry(ide_bus_info *bus, scsi_path_inquiry *info) -{ - const char *controller_name; - - FLOW("sim_path_inquiry, bus %p\n", bus); - - if (bus->disconnected) - return SCSI_NO_HBA; - - info->hba_inquiry = SCSI_PI_TAG_ABLE | SCSI_PI_WIDE_16; - - info->hba_misc = 0; - - memset(info->vuhba_flags, 0, sizeof(info->vuhba_flags)); - // we don't need any of the private data - info->sim_priv = 0; - - // there is no initiator for IDE, but SCSI needs it for scanning - info->initiator_id = 2; - // we only support 1 request at a time - info->hba_queue_size = 1; - - strncpy(info->sim_vid, "Haiku", SCSI_SIM_ID); - - if (pnp->get_attr_string(bus->node, SCSI_DESCRIPTION_CONTROLLER_NAME, - &controller_name, true) == B_OK) { - strlcpy(info->hba_vid, controller_name, SCSI_HBA_ID); - } else - strlcpy(info->hba_vid, "", SCSI_HBA_ID); - - strlcpy(info->controller_family, "IDE", SCSI_FAM_ID); - strlcpy(info->controller_type, "IDE", SCSI_TYPE_ID); - - SHOW_FLOW0(4, "done"); - - return SCSI_REQ_CMP; -} - - -static void -scan_bus(ide_bus_info *bus) -{ - uint32 deviceSignature[2]; - bool devicePresent[2]; - ide_device_info *device; - status_t status; - bool isAtapi; - int i; - - TRACE("ATA: scan_bus: bus %p\n", bus); - - if (bus->disconnected) - return; - - // XXX fix me - IDE_LOCK(bus); - ASSERT(bus->state == ata_state_idle); - bus->state = ata_state_busy; - IDE_UNLOCK(bus); - - for (i = 0; i < bus->max_devices; ++i) { - if (bus->devices[i]) - destroy_device(bus->devices[i]); - } - - status = ata_reset_bus(bus, &devicePresent[0], &deviceSignature[0], &devicePresent[1], &deviceSignature[1]); - - for (i = 0; i < bus->max_devices; ++i) { - if (!devicePresent[i]) - continue; - - dprintf("ATA: scan_bus: bus %p, creating device %d, signature is 0x%08lx\n", - bus, i, deviceSignature[i]); - - isAtapi = deviceSignature[i] == 0xeb140101; - device = create_device(bus, i /* isDevice1 */); - - if (scan_device(device, isAtapi) != B_OK) { - dprintf("ATA: scan_bus: bus %p, scanning failed, destroying device %d\n", bus, i); - destroy_device(device); - continue; - } - if (configure_device(device, isAtapi) != B_OK) { - dprintf("ATA: scan_bus: bus %p, configure failed, destroying device %d\n", bus, i); - destroy_device(device); - } - } - - // XXX fix me - IDE_LOCK(bus); - ASSERT(bus->state != ata_state_idle); - bus->state = ata_state_idle; - IDE_UNLOCK(bus); - - TRACE("ATA: scan_bus: bus %p finished\n", bus); -} - - -static void -sim_set_scsi_bus(ide_bus_info *bus, scsi_bus scsi) -{ - bus->scsi_cookie = scsi; - - // detect devices - scan_bus(bus); -} - - -static uchar -sim_rescan_bus(ide_bus_info *bus) -{ - TRACE("ATA: sim_rescan_bus - not implemented\n"); - return SCSI_REQ_CMP; -} - - -static uchar -sim_abort(ide_bus_info *bus, scsi_ccb *ccb_to_abort) -{ - // we cannot abort specific commands, so just ignore - if (bus->disconnected) - return SCSI_NO_HBA; - - return SCSI_REQ_CMP; -} - - -static uchar -sim_term_io(ide_bus_info *bus, scsi_ccb *ccb_to_abort) -{ - // we cannot terminate commands, so just ignore - if (bus->disconnected) - return SCSI_NO_HBA; - - return SCSI_REQ_CMP; -} - - -static uchar -sim_reset_bus(ide_bus_info *bus) -{ - // no, we don't do that - if (bus->disconnected) - return SCSI_NO_HBA; - - TRACE("ATA: sim_reset_bus - not implemented\n"); - return SCSI_REQ_INVALID; -} - - -static uchar -sim_reset_device(ide_bus_info *bus, uchar target_id, uchar target_lun) -{ - // xxx to do - if (bus->disconnected) - return SCSI_NO_HBA; - - return SCSI_REQ_INVALID; -} - - -static status_t -ide_sim_init_bus(device_node *node, void **cookie) -{ - device_node *parent; - ide_bus_info *bus; - bool dmaDisabled = false; - status_t status; - - FLOW("ide_sim_init_bus, node %p\n", node); - - // first prepare the info structure - bus = (ide_bus_info *)malloc(sizeof(*bus)); - if (bus == NULL) - return B_NO_MEMORY; - - memset(bus, 0, sizeof(*bus)); - bus->node = node; - bus->lock = 0; - bus->disconnected = false; - - { - int32 channel_id = -1; - - pnp->get_attr_uint32(node, IDE_CHANNEL_ID_ITEM, (uint32 *)&channel_id, true); - - sprintf(bus->name, "ide_bus %d", (int)channel_id); - } - - bus->timer.bus = bus; - - if ((status = scsi->alloc_dpc(&bus->irq_dpc)) < B_OK) - goto err1; - - bus->state = ata_state_idle; - bus->active_device = NULL; - - bus->devices[0] = NULL; - bus->devices[1] = NULL; - - status = INIT_BEN(&bus->status_report_ben, "ide_status_report"); - if (status < B_OK) - goto err4; - - { - // check if safemode settings disable DMA - void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); - if (settings != NULL) { - dmaDisabled = get_driver_boolean_parameter(settings, B_SAFEMODE_DISABLE_IDE_DMA, - false, false); - unload_driver_settings(settings); - } - } - - // read restrictions of controller - - if (pnp->get_attr_uint8(node, IDE_CONTROLLER_MAX_DEVICES_ITEM, - &bus->max_devices, true) != B_OK) { - // per default, 2 devices are supported per node - bus->max_devices = 2; - } - - bus->max_devices = min(bus->max_devices, 2); - - if (dmaDisabled - || pnp->get_attr_uint8(node, IDE_CONTROLLER_CAN_DMA_ITEM, &bus->can_DMA, true) != B_OK) { - // per default, no dma support - bus->can_DMA = false; - } - - SHOW_FLOW(2, "can_dma: %d", bus->can_DMA); - - parent = pnp->get_parent_node(node); - - status = pnp->get_driver(parent, (driver_module_info **)&bus->controller, - (void **)&bus->channel_cookie); - - pnp->put_node(parent); - if (status != B_OK) - goto err5; - - *cookie = bus; - return B_OK; - -err5: - DELETE_BEN(&bus->status_report_ben); -err4: - scsi->free_dpc(bus->irq_dpc); -err1: - free(bus); - - return status; -} - - -static void -ide_sim_uninit_bus(ide_bus_info *bus) -{ - FLOW("ide_sim_uninit_bus: bus %p\n", bus); - - DELETE_BEN(&bus->status_report_ben); - scsi->free_dpc(bus->irq_dpc); - - free(bus); -} - - -static void -ide_sim_bus_removed(ide_bus_info *bus) -{ - FLOW("ide_sim_bus_removed\n"); - - if (bus == NULL) - // driver not loaded - no manual intervention needed - return; - - // XPT must not issue further commands - scsi->block_bus(bus->scsi_cookie); - // make sure, we refuse all new commands - bus->disconnected = true; - - // abort all running commands with SCSI_NO_HBA - // XXX -} - - -static void -ide_sim_get_restrictions(ide_bus_info *bus, uchar target_id, - bool *is_atapi, bool *no_autosense, uint32 *max_blocks) -{ - ide_device_info *device = bus->devices[target_id]; - - FLOW("ide_sim_get_restrictions\n"); - - // we declare even ATA devices as ATAPI so we have to emulate fewer - // commands - *is_atapi = true; - - // we emulate autosense for ATA devices - *no_autosense = false; - - if (device != NULL && device->is_atapi) { - // we don't support native autosense for ATAPI devices - *no_autosense = true; - } - - *max_blocks = 255; - - if (device->is_atapi) { - if (strncmp(device->infoblock.model_number, "IOMEGA ZIP 100 ATAPI", - strlen("IOMEGA ZIP 100 ATAPI")) == 0 - || strncmp( device->infoblock.model_number, "IOMEGA Clik!", - strlen( "IOMEGA Clik!")) == 0) { - SHOW_ERROR0(2, "Found buggy ZIP/Clik! drive - restricting transmission size"); - *max_blocks = 64; - } - } -} - - -static status_t -ide_sim_ioctl(ide_bus_info *bus, uint8 targetID, uint32 op, void *buffer, size_t length) -{ - ide_device_info *device = bus->devices[targetID]; - - // We currently only support IDE_GET_INFO_BLOCK - switch (op) { - case IDE_GET_INFO_BLOCK: - // we already have the info block, just copy it - memcpy(buffer, &device->infoblock, - min(sizeof(device->infoblock), length)); - return B_OK; - - case IDE_GET_STATUS: - { - // TODO: have our own structure and fill it with some useful stuff - ide_status status; - if (device->DMA_enabled) - status.dma_status = 1; - else if (device->DMA_supported) { - if (device->DMA_failures > 0) - status.dma_status = 6; - else if (device->bus->can_DMA) - status.dma_status = 2; - else - status.dma_status = 4; - } else - status.dma_status = 2; - - status.pio_mode = 0; - status.dma_mode = get_device_dma_mode(device); - - memcpy(buffer, &status, min(sizeof(status), length)); - return B_OK; - } - } - - return B_BAD_VALUE; -} - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - - default: - return B_ERROR; - } -} - - -module_dependency module_dependencies[] = { - { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&scsi }, - { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp }, - {} -}; - - -scsi_sim_interface ide_sim_module = { - { - { - IDE_SIM_MODULE_NAME, - 0, - std_ops, - }, - - NULL, // supported devices - NULL, // register node - (status_t (*)(device_node *, void **)) ide_sim_init_bus, - (void (*)(void *)) ide_sim_uninit_bus, - NULL, // register child devices - NULL, // rescan - (void (*)(void *)) ide_sim_bus_removed, - NULL, // suspend - NULL // resume - }, - - (void (*)(scsi_sim_cookie, scsi_bus)) sim_set_scsi_bus, - (void (*)(scsi_sim_cookie, scsi_ccb *)) sim_scsi_io, - (uchar (*)(scsi_sim_cookie, scsi_ccb *)) sim_abort, - (uchar (*)(scsi_sim_cookie, uchar, uchar)) sim_reset_device, - (uchar (*)(scsi_sim_cookie, scsi_ccb *)) sim_term_io, - - (uchar (*)(scsi_sim_cookie, scsi_path_inquiry *))sim_path_inquiry, - (uchar (*)(scsi_sim_cookie)) sim_rescan_bus, - (uchar (*)(scsi_sim_cookie)) sim_reset_bus, - - (void (*)(scsi_sim_cookie, uchar, - bool*, bool *, uint32 *)) ide_sim_get_restrictions, - - (status_t (*)(scsi_sim_cookie, uint8, uint32, void *, size_t))ide_sim_ioctl, -}; diff --git a/src/add-ons/kernel/bus_managers/ata/ide_sim.h b/src/add-ons/kernel/bus_managers/ata/ide_sim.h deleted file mode 100644 index 00faae56e7..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -** Copyright 2002/03, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - -/* - Part of Open IDE bus manager - - Interface between ide and scsi bus manager -*/ - - -#ifndef __IDE_SIM_H__ -#define __IDE_SIM_H__ - -#include "scsi_cmds.h" - -extern scsi_for_sim_interface *scsi; -extern scsi_sim_interface ide_sim_module; - -#endif diff --git a/src/add-ons/kernel/bus_managers/ata/pio.c b/src/add-ons/kernel/bus_managers/ata/pio.c deleted file mode 100644 index ff2d975a60..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/pio.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright 2004-2007, Haiku, Inc. All RightsReserved. - * Copyright 2002-2004, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - PIO data transmission - - This file is more difficult then you might expect as the SCSI system - uses physical addresses everywhere which have to be mapped into - virtual address space during transmission. Additionally, during ATAPI - commands we may have to transmit more data then exist because the - data len specified by the command doesn't need to be the same as - of the data buffer provided. - - The handling of S/G entries of odd size may look superfluous as the - SCSI bus manager can take care of that. In general, this would be possible - as most controllers need even alignment for DMA as well, but some can - handle _any_ S/G list and it wouldn't be sensitive to enforce stricter - alignement just for some rare PIO transmissions. - - Little hint for the meaning of "transferred": this is the number of bytes - sent over the bus. For read-transmissions, this may be one more then copied - into the buffer (the extra byte read is stored in device->odd_byte), for - write-transmissions, this may be one less (the waiting byte is pending in - device->odd_byte). - - In terms of error handling: we don't bother checking transmission of every - single byte via read/write_pio(). At least at the end of the request, when - the status bits are verified, we will see that something has gone wrong. - - TBD: S/G entries may have odd start address. For non-Intel architecture - we either have to copy data to an aligned buffer or have to modify - PIO-handling in controller drivers. -*/ - -#include "ide_internal.h" -#include "ide_sim.h" - -#include -#include - -#include - -#define FLOW dprintf - -// internal error code if scatter gather table is too short -#define ERR_TOO_BIG (B_ERRORS_END + 1) - - -/*! Prepare PIO transfer */ -void -prep_PIO_transfer(ide_device_info *device, ata_request *request) -{ - SHOW_FLOW0(4, ""); - - device->left_sg_elem = request->ccb->sg_count; - device->cur_sg_elem = request->ccb->sg_list; - device->cur_sg_ofs = 0; - device->has_odd_byte = false; - request->ccb->data_resid = request->ccb->data_length; -} - - -/*! Transfer virtually continuous data */ -static inline status_t -transfer_PIO_virtcont(ide_device_info *device, uint8 *virtualAddress, - int length, bool write, int *transferred) -{ - ide_bus_info *bus = device->bus; - ide_controller_interface *controller = bus->controller; - void * channel_cookie = bus->channel_cookie; - - if (write) { - // if there is a byte left from last chunk, transmit it together - // with the first byte of the current chunk (IDE requires 16 bits - // to be transmitted at once) - if (device->has_odd_byte) { - uint8 buffer[2]; - - buffer[0] = device->odd_byte; - buffer[1] = *virtualAddress++; - - controller->write_pio(channel_cookie, (uint16 *)buffer, 1, false); - - --length; - *transferred += 2; - } - - controller->write_pio(channel_cookie, (uint16 *)virtualAddress, - length / 2, false); - - // take care if chunk size was odd, which means that 1 byte remains - virtualAddress += length & ~1; - *transferred += length & ~1; - - device->has_odd_byte = (length & 1) != 0; - - if (device->has_odd_byte) - device->odd_byte = *virtualAddress; - } else { - // if we read one byte too much last time, push it into current chunk - if (device->has_odd_byte) { - *virtualAddress++ = device->odd_byte; - --length; - } - - SHOW_FLOW(4, "Reading PIO to %p, %d bytes", virtualAddress, length); - - controller->read_pio(channel_cookie, (uint16 *)virtualAddress, - length / 2, false); - - // take care of odd chunk size; - // in this case we read 1 byte to few! - virtualAddress += length & ~1; - *transferred += length & ~1; - - device->has_odd_byte = (length & 1) != 0; - - if (device->has_odd_byte) { - uint8 buffer[2]; - - // now read the missing byte; as we have to read 2 bytes at once, - // we'll read one byte too much - controller->read_pio(channel_cookie, (uint16 *)buffer, 1, false); - - *virtualAddress = buffer[0]; - device->odd_byte = buffer[1]; - - *transferred += 2; - } - } - - return B_OK; -} - - -/*! Transmit physically continuous data */ -static inline status_t -transfer_PIO_physcont(ide_device_info *device, addr_t physicalAddress, - int length, bool write, int *transferred) -{ - // we must split up chunk into B_PAGE_SIZE blocks as we can map only - // one page into address space at once - while (length > 0) { - addr_t virtualAddress; - void* handle; - int page_left, cur_len; - status_t err; - struct thread* thread = thread_get_current_thread(); - - SHOW_FLOW(4, "Transmitting to/from physical address %lx, %d bytes left", - physicalAddress, length); - - thread_pin_to_current_cpu(thread); - if (vm_get_physical_page_current_cpu(physicalAddress, &virtualAddress, - &handle) != B_OK) { - thread_unpin_from_current_cpu(thread); - // ouch: this should never ever happen -//xxx fix this set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); - return B_ERROR; - } - - ASSERT(physicalAddress % B_PAGE_SIZE == virtualAddress % B_PAGE_SIZE); - - // if chunks starts in the middle of a page, we have even less then - // a page left - page_left = B_PAGE_SIZE - physicalAddress % B_PAGE_SIZE; - - SHOW_FLOW(4, "page_left=%d", page_left); - - cur_len = min(page_left, length); - - SHOW_FLOW(4, "cur_len=%d", cur_len); - - err = transfer_PIO_virtcont(device, (char *)virtualAddress, - cur_len, write, transferred); - - vm_put_physical_page_current_cpu(virtualAddress, handle); - thread_unpin_from_current_cpu(thread); - - if (err != B_OK) - return err; - - length -= cur_len; - physicalAddress += cur_len; - } - - return B_OK; -} - - -/*! Transfer PIO block from/to buffer */ -static inline status_t -transfer_PIO_block(ide_device_info *device, int length, bool write, int *transferred) -{ - // data is usually split up into multiple scatter/gather blocks - while (length > 0) { - int left_bytes, cur_len; - status_t err; - - if (device->left_sg_elem == 0) - // ups - buffer too small (for ATAPI data, this is OK) - return ERR_TOO_BIG; - - // we might have transmitted part of a scatter/entry already! - left_bytes = device->cur_sg_elem->size - device->cur_sg_ofs; - - cur_len = min(left_bytes, length); - - err = transfer_PIO_physcont(device, - (addr_t)device->cur_sg_elem->address + device->cur_sg_ofs, - cur_len, write, transferred); - - if (err != B_OK) - return err; - - if (left_bytes <= length) { - // end of one scatter/gather block reached - device->cur_sg_ofs = 0; - ++device->cur_sg_elem; - --device->left_sg_elem; - } else { - // still in the same block - device->cur_sg_ofs += cur_len; - } - - length -= cur_len; - } - - return B_OK; -} - - -/*! Write zero data (required for ATAPI if we ran out of data) */ - -static void -write_discard_PIO(ide_device_info *device, int length) -{ - static const uint8 buffer[32] = {}; - ide_bus_info *bus = device->bus; - - // we transmit 32 zero-bytes at once - // (not very efficient but easy to implement - you get what you deserve - // when you don't provide enough buffer) - while (length > 0) { - int cur_len; - - // if device asks for odd number of bytes, append an extra byte to - // make length even (this is the "length + 1" term) - cur_len = min(length + 1, (int)(sizeof(buffer))) / 2; - - bus->controller->write_pio(bus->channel_cookie, (uint16 *)buffer, cur_len, false); - - length -= cur_len * 2; - } -} - - -/*! Read PIO data and discard it (required for ATAPI if buffer was too small) */ -static void -read_discard_PIO(ide_device_info *device, int length) -{ - ide_bus_info *bus = device->bus; - uint8 buffer[32]; - - // discard 32 bytes at once (see write_discard_PIO) - while (length > 0) { - int cur_len; - - // read extra byte if length is odd (that's the "length + 1") - cur_len = min(length + 1, (int)sizeof(buffer)) / 2; - - bus->controller->read_pio(bus->channel_cookie, (uint16 *)buffer, cur_len, false); - - length -= cur_len * 2; - } -} - - -/*! write PIO data - return: there are 3 possible results - NO_ERROR - everything's nice and groovy - ERR_TOO_BIG - data buffer was too short, remaining data got discarded - B_ERROR - something serious went wrong, sense data was set -*/ -status_t -write_PIO_block(ata_request *request, int length) -{ - ide_device_info *device = request->device; - int transferred; - status_t err; - - transferred = 0; - err = transfer_PIO_block(device, length, true, &transferred); - - request->ccb->data_resid -= transferred; - - if (err != ERR_TOO_BIG) - return err; - - // there may be a pending odd byte - transmit that now - if (request->device->has_odd_byte) { - uint8 buffer[2]; - - buffer[0] = device->odd_byte; - buffer[1] = 0; - - device->has_odd_byte = false; - - request->ccb->data_resid -= 1; - transferred += 2; - - device->bus->controller->write_pio(device->bus->channel_cookie, (uint16 *)buffer, 1, false); - } - - // "transferred" may actually be larger then length because the last odd-byte - // is sent together with an extra zero-byte - if (transferred >= length) - return err; - - // Ouch! the device asks for data but we haven't got any left. - // Sadly, this behaviour is OK for ATAPI packets, but there is no - // way to tell the device that we don't have any data left; - // only solution is to send zero bytes, though it's BAD BAD BAD - write_discard_PIO(request->device, length - transferred); - return ERR_TOO_BIG; -} - - -/*! read PIO data - return: see write_PIO_block -*/ -status_t -read_PIO_block(ata_request *request, int length) -{ - ide_device_info *device = request->device; - int transferred; - status_t err; - - transferred = 0; - err = transfer_PIO_block(request->device, length, false, &transferred); - - request->ccb->data_resid -= transferred; - - // if length was odd, there's an extra byte waiting in device->odd_byte - if (device->has_odd_byte) { - // discard byte - device->has_odd_byte = false; - // adjust res_id as the extra byte didn't reach the buffer - ++request->ccb->data_resid; - } - - if (err != ERR_TOO_BIG) - return err; - - // the device returns more data then the buffer can store; - // for ATAPI this is OK - we just discard remaining bytes (there - // is no way to tell ATAPI about that, but we "only" waste time) - - // perhaps discarding the extra odd-byte was sufficient - if (transferred >= length) - return err; - - SHOW_FLOW(3, "discarding after %d bytes", transferred); - read_discard_PIO(request->device, length - transferred); - return ERR_TOO_BIG; -} diff --git a/src/add-ons/kernel/bus_managers/ata/scsi2ata.c b/src/add-ons/kernel/bus_managers/ata/scsi2ata.c deleted file mode 100644 index 4f4a29eb48..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/scsi2ata.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2004-2008, Haiku, Inc. All RightsReserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - Part of Open IDE bus manager - - Converts SCSI commands to ATA commands. -*/ - - -#include "ide_internal.h" -#include "ide_sim.h" -#include "ide_cmds.h" - -#include - -#define TRACE dprintf_no_syslog -#define FLOW dprintf_no_syslog - - - -// set sense buffer according to device sense in ata_request -void -scsi_set_sense(scsi_sense *sense, const ata_request *request) -{ - memset(sense, 0, sizeof(*sense)); - - sense->error_code = SCSIS_CURR_ERROR; - sense->sense_key = request->senseKey; - sense->add_sense_length = sizeof(*sense) - 7; - sense->asc = request->senseAsc; - sense->ascq = request->senseAscq; - sense->sense_key_spec.raw.SKSV = 0; // no additional info -} - - -static void -scsi_mode_sense_10(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - scsi_cmd_mode_sense_10 *cmd = (scsi_cmd_mode_sense_10 *)ccb->cdb; - scsi_mode_param_header_10 param_header; - scsi_modepage_control control; - scsi_mode_param_block_desc block_desc; - size_t totalLength = sizeof(scsi_mode_param_header_10) - + sizeof(scsi_mode_param_block_desc) - + sizeof(scsi_modepage_control); - scsi_mode_param_dev_spec_da devspec = { - _res0_0 : 0, - dpo_fua : 0, - _res0_6 : 0, - write_protected : 0 - }; - uint32 allocationLength; - - SHOW_FLOW0(1, "Hi!"); - - allocationLength = B_BENDIAN_TO_HOST_INT16(cmd->allocation_length); - - // we answer control page requests and "all pages" requests - // (as the latter are the same as the first) - if ((cmd->page_code != SCSI_MODEPAGE_CONTROL && cmd->page_code != SCSI_MODEPAGE_ALL) - || (cmd->page_control != SCSI_MODE_SENSE_PC_CURRENT - && cmd->page_control != SCSI_MODE_SENSE_PC_SAVED)) { - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); - return; - } - - //param_header = (scsi_mode_param_header_10 *)ccb->data; - param_header.mode_data_length = B_HOST_TO_BENDIAN_INT16(totalLength - 1); - param_header.medium_type = 0; // XXX standard is a bit vague here - param_header.dev_spec_parameter = *(uint8 *)&devspec; - param_header.block_desc_length - = B_HOST_TO_BENDIAN_INT16(sizeof(scsi_mode_param_block_desc)); - - copy_sg_data(ccb, 0, allocationLength, ¶m_header, - sizeof(param_header), false); - - /*block_desc = (scsi_mode_param_block_desc *)(ccb->data - + sizeof(*param_header));*/ - memset(&block_desc, 0, sizeof(block_desc)); - // density is reserved (0), descriptor apply to entire medium (num_blocks=0) - // remains the blocklen to be set - block_desc.high_blocklen = 0; - block_desc.med_blocklen = 512 >> 8; - block_desc.low_blocklen = 512 & 0xff; - - copy_sg_data(ccb, sizeof(param_header), allocationLength, - &block_desc, sizeof(block_desc), false); - - /*contr = (scsi_modepage_contr *)(ccb->data - + sizeof(*param_header) - + ((uint16)param_header->high_block_desc_len << 8) - + param_header->low_block_desc_len);*/ - - memset(&control, 0, sizeof(control)); - control.RLEC = false; - control.DQue = 1;//!device->CQ_enabled; - control.QErr = false; - // when a command fails we requeue all - // lost commands automagically - control.QAM = SCSI_QAM_UNRESTRICTED; - - copy_sg_data(ccb, sizeof(param_header) - + B_BENDIAN_TO_HOST_INT16(param_header.block_desc_length), - allocationLength, &control, sizeof(control), false); - - // the number of bytes that were transferred to buffer is - // restricted by allocation length and by ccb data buffer size - totalLength = min(totalLength, allocationLength); - totalLength = min(totalLength, ccb->data_length); - - ccb->data_resid = ccb->data_length - totalLength; -} - - -/*! Emulate modifying control page */ -static bool -ata_mode_select_control_page(ide_device_info *device, ata_request *request, - scsi_modepage_control *page) -{ - if (page->header.page_length != sizeof(*page) - sizeof(page->header)) { - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_LIST_LENGTH_ERR); - return false; - } - - // we only support enabling/disabling command queuing -// enable_CQ(device, !page->DQue); - return true; -} - - -/*! Emulate MODE SELECT 10 command */ -static void -scsi_mode_select_10(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - scsi_cmd_mode_select_10 *cmd = (scsi_cmd_mode_select_10 *)ccb->cdb; - scsi_mode_param_header_10 param_header; - scsi_modepage_header page_header; - uint32 totalLength; - uint32 modepageOffset; - char modepage_buffer[64]; // !!! enlarge this to support longer mode pages - - if (cmd->save_pages || cmd->pf != 1) { - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); - return; - } - - totalLength = min(ccb->data_length, - B_BENDIAN_TO_HOST_INT16(cmd->param_list_length)); - - // first, retrieve page header to get size of different chunks - //param_header = (scsi_mode_param_header_10 *)ccb->data; - if (!copy_sg_data(ccb, 0, totalLength, ¶m_header, sizeof(param_header), true)) - goto err; - - totalLength = min(totalLength, - B_BENDIAN_TO_HOST_INT16(param_header.mode_data_length) + 1UL); - - // this is the start of the first mode page; - // we ignore the block descriptor silently - modepageOffset = sizeof(param_header) - + B_BENDIAN_TO_HOST_INT16(param_header.block_desc_length); - - // go through list of pages - while (modepageOffset < totalLength) { - uint32 pageLength; - - // get header to know how long page is - if (!copy_sg_data(ccb, modepageOffset, totalLength, - &page_header, sizeof(page_header), true)) - goto err; - - // get size of one page and copy it to buffer - pageLength = page_header.page_length + sizeof(scsi_modepage_header); - - // the buffer has a maximum size - this is really standard compliant but - // sufficient for our needs - if (pageLength > sizeof(modepage_buffer)) - goto err; - - if (!copy_sg_data(ccb, modepageOffset, totalLength, - &modepage_buffer, min(pageLength, sizeof(modepage_buffer)), true)) - goto err; - - // modify page; - // currently, we only support the control mode page - switch (page_header.page_code) { - case SCSI_MODEPAGE_CONTROL: - if (!ata_mode_select_control_page(device, request, - (scsi_modepage_control *)modepage_buffer)) - return; - break; - - default: - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_PARAM_LIST_FIELD); - return; - } - - modepageOffset += pageLength; - } - - if (modepageOffset != totalLength) - goto err; - - ccb->data_resid = ccb->data_length - totalLength; - return; - - // if we arrive here, data length was incorrect -err: - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_LIST_LENGTH_ERR); -} - - -static void -scsi_test_unit_ready(ide_device_info *device, ata_request *request) -{ - TRACE("scsi_test_unit_ready\n"); - - if (device->infoblock.RMSN_supported == 0 - || device->infoblock._127_RMSN_support != 1) - return; - - // ask device about status - device->tf_param_mask = 0; - device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS; - - if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 15000000) != B_OK) { - ata_request_set_status(request, SCSI_SEQUENCE_FAIL); - return; - } - - // bits ide_error_mcr | ide_error_mc | ide_error_wp are also valid - // but not requested by TUR; ide_error_wp can safely be ignored, but - // we don't want to loose media change (request) reports - ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, - ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc); - // SCSI spec is unclear here: we shouldn't report "media change (request)" - // but what to do if there is one? anyway - we report them -} - - -/*! Flush internal device cache */ -static bool -scsi_synchronize_cache(ide_device_info *device, ata_request *request) -{ - TRACE("scsi_synchronize_cache\n"); - - // we should also ask for FLUSH CACHE support, but everyone denies it - // (looks like they cheat to gain some performance advantage, but - // that's pretty useless: everyone does it...) - if (!device->infoblock.write_cache_supported) - return true; - - device->tf_param_mask = 0; - device->tf.lba.command = device->use_48bits ? IDE_CMD_FLUSH_CACHE_EXT - : IDE_CMD_FLUSH_CACHE; - - // spec says that this may take more then 30s, how much more? - if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 60000000) != B_OK) - return false; - - if (ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt) != B_OK) - return false; - - return true; -} - - -/*! Load or eject medium - load = true - load medium -*/ -static bool -scsi_load_eject(ide_device_info *device, ata_request *request, bool load) -{ - TRACE("scsi_load_eject\n"); - - if (load) { - // ATA doesn't support loading - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_NOT_SUPPORTED); - return false; - } - - device->tf_param_mask = 0; - device->tf.lba.command = IDE_CMD_MEDIA_EJECT; - - if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 15000000) != B_OK) - return false; - - if (ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt | ide_error_nm) != B_OK) - return false; - - return true; -} - - -static void -scsi_prevent_allow(ide_device_info *device, ata_request *request, bool prevent) -{ - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_ILL_FUNCTION); -} - - -static void -scsi_inquiry(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - scsi_res_inquiry data; - scsi_cmd_inquiry *cmd = (scsi_cmd_inquiry *)ccb->cdb; - uint32 allocation_length = cmd->allocation_length; - uint32 transfer_size; - - if (cmd->evpd || cmd->page_code) { - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); - return; - } - - memset(&data, 0, sizeof(data)); - - data.device_type = scsi_dev_direct_access; - data.device_qualifier = scsi_periph_qual_connected; - - data.device_type_modifier = 0; - data.removable_medium = false; - - data.ansi_version = 2; - data.ecma_version = 0; - data.iso_version = 0; - - data.response_data_format = 2; - data.term_iop = false; - // to be changed if we support TERM I/O - - data.additional_length = sizeof(scsi_res_inquiry) - 4; - - data.soft_reset = false; - data.cmd_queue = 0;//device->queue_depth > 1; - data.linked = false; - - // these values are free-style - data.sync = false; - data.write_bus16 = true; - data.write_bus32 = false; - - data.relative_address = false; - - // the following fields are *much* to small, sigh... - memcpy(data.vendor_ident, device->infoblock.model_number, - sizeof(data.vendor_ident)); - memcpy(data.product_ident, device->infoblock.model_number + 8, - sizeof(data.product_ident)); - memcpy(data.product_rev, " ", sizeof(data.product_rev)); - - copy_sg_data(ccb, 0, allocation_length, &data, sizeof(data), false); - - transfer_size = min(sizeof(data), allocation_length); - transfer_size = min(transfer_size, ccb->data_length); - - ccb->data_resid = ccb->data_length - transfer_size; -} - - - -static void -scsi_read_capacity(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - scsi_res_read_capacity data; - scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)ccb->cdb; - uint32 lastBlock; - - TRACE("scsi_read_capacity\n"); - - if (cmd->pmi || cmd->lba) { - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); - return; - } - - // TODO: 512 bytes fixed block size? - data.block_size = B_HOST_TO_BENDIAN_INT32(512); - - lastBlock = device->total_sectors - 1; - data.lba = B_HOST_TO_BENDIAN_INT32(lastBlock); - - copy_sg_data(ccb, 0, ccb->data_length, &data, sizeof(data), false); - ccb->data_resid = max(ccb->data_length - sizeof(data), 0); -} - - -void -scsi_request_sense(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - scsi_cmd_request_sense *cmd = (scsi_cmd_request_sense *)ccb->cdb; - scsi_sense sense; - uint32 transferSize; - - TRACE("scsi_request_sense\n"); - - // Copy sense data from last request into data buffer of current request. - // The sense data of last request is still present in the current request, - // as is isn't been cleared by ata_exec_io for SCSI_OP_REQUEST_SENSE. - - if (request->senseKey != 0) - scsi_set_sense(&sense, request); - else - memset(&sense, 0, sizeof(sense)); - - copy_sg_data(ccb, 0, cmd->allocation_length, &sense, sizeof(sense), false); - - transferSize = min(sizeof(sense), cmd->allocation_length); - transferSize = min(transferSize, ccb->data_length); - - ccb->data_resid = ccb->data_length - transferSize; - - // reset sense information on read - ata_request_clear_sense(request); -} - - -/*! Execute SCSI command */ -void -ata_exec_io(ide_device_info *device, ata_request *request) -{ - scsi_ccb *ccb = request->ccb; - - //FLOW("ata_exec_io: scsi command 0x%02x\n", ccb->cdb[0]); - - // ATA devices have one LUN only - if (ccb->target_lun != 0) { - FLOW("ata_exec_io: wrong target lun\n"); - ata_request_set_status(request, SCSI_SEL_TIMEOUT); - ata_request_finish(request, false /* no resubmit */); - return; - } - - if (ccb->cdb[0] == SCSI_OP_REQUEST_SENSE) { - // No initial clear sense, as this request is used - // by the scsi stack to request the sense data of - // the previous command. - scsi_request_sense(device, request); - ata_request_finish(request, false /* no resubmit */); - return; - } - - ata_request_clear_sense(request); - - switch (ccb->cdb[0]) { - case SCSI_OP_TEST_UNIT_READY: - scsi_test_unit_ready(device, request); - break; - - case SCSI_OP_FORMAT: /* FORMAT UNIT */ - // we could forward ccb to disk, but modern disks cannot - // be formatted anyway, so we just refuse ccb - // (exceptions are removable media devices, but to my knowledge - // they don't have to be formatted as well) - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - break; - - case SCSI_OP_INQUIRY: - scsi_inquiry(device, request); - break; - - case SCSI_OP_MODE_SELECT_10: - scsi_mode_select_10(device, request); - break; - - case SCSI_OP_MODE_SENSE_10: - scsi_mode_sense_10(device, request); - break; - - case SCSI_OP_MODE_SELECT_6: - case SCSI_OP_MODE_SENSE_6: - // we've told SCSI bus manager to emulates these commands - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - break; - - case SCSI_OP_RESERVE: - case SCSI_OP_RELEASE: - // though mandatory, this doesn't make much sense in a - // single initiator environment; so what - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - break; - - case SCSI_OP_START_STOP: { - scsi_cmd_ssu *cmd = (scsi_cmd_ssu *)ccb->cdb; - - // with no LoEj bit set, we should only allow/deny further access - // we ignore that (unsupported for ATA) - // with LoEj bit set, we should additionally either load or eject the medium - // (start = 0 - eject; start = 1 - load) - - if (!cmd->start) - // we must always flush cache if start = 0 - scsi_synchronize_cache(device, request); - - if (cmd->load_eject) - scsi_load_eject(device, request, cmd->start); - break; - } - - case SCSI_OP_PREVENT_ALLOW: - { - scsi_cmd_prevent_allow *cmd = (scsi_cmd_prevent_allow *)ccb->cdb; - scsi_prevent_allow(device, request, cmd->prevent); - break; - } - - case SCSI_OP_READ_CAPACITY: - scsi_read_capacity(device, request); - break; - - case SCSI_OP_VERIFY: - // does anyone uses this function? - // effectly, it does a read-and-compare, which IDE doesn't support - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - break; - - case SCSI_OP_SYNCHRONIZE_CACHE: - // we ignore range and immediate bit, we always immediately flush everything - scsi_synchronize_cache(device, request); - break; - - // sadly, there are two possible read/write operation codes; - // at least, the third one, read/write(12), is not valid for DAS - case SCSI_OP_READ_6: - case SCSI_OP_WRITE_6: - { - scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)ccb->cdb; - uint32 pos; - size_t length; - - pos = ((uint32)cmd->high_lba << 16) | ((uint32)cmd->mid_lba << 8) - | (uint32)cmd->low_lba; - length = cmd->length != 0 ? cmd->length : 256; - - //FLOW("READ6/WRITE6 pos=%lx, length=%lx\n", pos, length); - - ata_exec_read_write(device, request, pos, length, cmd->opcode == SCSI_OP_WRITE_6); - return; - } - - case SCSI_OP_READ_10: - case SCSI_OP_WRITE_10: - { - scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)ccb->cdb; - uint32 pos; - size_t length; - - pos = B_BENDIAN_TO_HOST_INT32(cmd->lba); - length = B_BENDIAN_TO_HOST_INT16(cmd->length); - - //FLOW("READ10/WRITE10 pos=%lx, length=%lx\n", pos, length); - - if (length != 0) { - ata_exec_read_write(device, request, pos, length, cmd->opcode == SCSI_OP_WRITE_10); - return; - } else { - // we cannot transfer zero blocks (apart from LBA48) - ata_request_set_status(request, SCSI_REQ_CMP); - } - } - - default: - FLOW("command not implemented\n"); - ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); - } - ata_request_finish(request, false /* no resubmit */); -} diff --git a/src/add-ons/kernel/bus_managers/ata/sync.c b/src/add-ons/kernel/bus_managers/ata/sync.c deleted file mode 100644 index 382eba3399..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/sync.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/* - Part of Open IDE bus manager - - Handling of passive waiting and synchronized procedure calls. - The latter are calls that get delayed until the bus is idle. -*/ - - -#include "ide_internal.h" -#include "ide_sim.h" - -#include - - -//#define TRACE_SYNC -#ifdef TRACE_SYNC -# define TRACE(x) { dprintf("%s(): ", __FUNCTION__); dprintf x ; } -#else -# define TRACE(x) ; -#endif - - -/** DPC handler for IRQs */ - -void -ide_dpc(void *arg) -{ -#if 0 - ide_bus_info *bus = (ide_bus_info *)arg; - ata_request *request; - ide_device_info *device; - - TRACE(("\n")); - - //snooze(500000); - - // IRQ handler doesn't tell us whether this bus was in async_wait or - // in idle state, so we just check whether there is an active request, - // which means that we were async_waiting - if (bus->active_qrequest != NULL) { - TRACE(("continue command\n")); - - // cancel timeout - cancel_timer(&bus->timer.te); - - request = bus->active_qrequest; - device = request->device; - - // not perfect but simple: we simply know who is waiting why - if (device->is_atapi) - packet_dpc(request); - else { - if (request->uses_dma) - ata_dpc_DMA(request); - else - ata_dpc_PIO(request); - } - } else { - // no request active, so this must be a service request or - // a spurious IRQ; access_finished will take care of testing - // for service requests - TRACE(("irq in idle mode - possible service request\n")); - - device = get_current_device(bus); - if (device == NULL) { - // got an interrupt from a non-existing device - // either this is a spurious interrupt or there *is* a device - // but we haven't detected it - we better ignore it silently - access_finished(bus, bus->first_device); - } else { - // access_finished always checks the other device first, but as - // we do have a service request, we negate the negation - access_finished(bus, device->other_device); - } - - // let XPT resend commands that got blocked - scsi->cont_send_bus(bus->scsi_cookie); - } - - return; - -/*err: - xpt->cont_send( bus->xpt_cookie );*/ -#endif -} - - -/** handler for IDE IRQs */ - -status_t -ide_irq_handler(ide_bus_info *bus, uint8 status) -{ - return B_UNHANDLED_INTERRUPT; -/* - ide_device_info *device; - - // the first IRQ) - IDE_LOCK(bus); - - device = bus->active_device; - - if (device == NULL) { - IDE_UNLOCK(bus); - - TRACE(("IRQ though there is no active device\n")); - return B_UNHANDLED_INTERRUPT; - } - - if ((status & ide_status_bsy) != 0) { - // the IRQ seems to be fired before the last command was sent, - // i.e. it's not the one that signals finishing of command - IDE_UNLOCK(bus); - - TRACE(("IRQ though device is busy\n")); - return B_UNHANDLED_INTERRUPT; - } - - switch (bus->state) { - case ide_state_async_waiting: - TRACE(("state: async waiting\n")); - - bus->state = ide_state_accessing; - - IDE_UNLOCK(bus); - - scsi->schedule_dpc(bus->scsi_cookie, bus->irq_dpc, ide_dpc, bus); - return B_INVOKE_SCHEDULER; - - case ide_state_idle: - TRACE(("state: idle, num_running_reqs %d\n", bus->num_running_reqs)); - - // this must be a service request; - // if no request is pending, the IRQ was fired wrongly - if (bus->num_running_reqs == 0) { - IDE_UNLOCK(bus); - return B_UNHANDLED_INTERRUPT; - }mmand - if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_command) != B_OK) - goto err_clearint; - - bus->state = ide_state_accessing; - - IDE_UNLOCK(bus); - - scsi->schedule_dpc(bus->scsi_cookie, bus->irq_dpc, ide_dpc, bus); - return B_INVOKE_SCHEDULER; - - case ide_state_sync_waiting: - TRACE(("state: sync waiting\n")); - - bus->state = ide_state_accessing; - bus->sync_wait_timeout = false; - - IDE_UNLOCK(bus);mmand - if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_command) != B_OK) - goto err_clearint; - - release_sem_etc(bus->sync_wait_sem, 1, B_DO_NOT_RESCHEDULE); - return B_INVOKE_SCHEDULER; - - case ide_state_accessing: - TRACE(("state: spurious IRQ - there is a command being executed\n")); - - IDE_UNLOCK(bus); - return B_UNHANDLED_INTERRUPT; - - default: - dprintf("BUG: unknown state (%d)\n", bus->state); - - IDE_UNLOCK(bus); - - return B_UNHANDLED_INTERRUPT; - } -*/ -} - - - -/** cancel IRQ timeout - * it doesn't matter whether there really was a timout running; - * on return, bus state is set to _accessing_ - */ - -/* -void -cancel_irq_timeout(ide_bus_info *bus) -{ - IDE_LOCK(bus); - bus->state = ide_state_accessing; - IDE_UNLOCK(bus); - - cancel_timer(&bus->timer.te); -} - - -// start waiting for IRQ with bus lock hold -// new_state must be either sync_wait or async_wait - -void -start_waiting(ide_bus_info *bus, uint32 timeout, int new_state) -{mmand - if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_command) != B_OK) - goto err_clearint; - int res; - - TRACE(("timeout = %u\n", (uint)timeout)); - - bus->state = new_state; - - res = add_timer(&bus->timer.te, ide_timeout, - (bigtime_t)timeout * 1000000, B_ONE_SHOT_RELATIVE_TIMER); - - if (res != B_OK) - panic("Error setting timeout (%s)", strerror(res)); - - IDE_UNLOCK(bus); -} - - -// start waiting for IRQ with bus lock not hold - -void -start_waiting_nolock(ide_bus_info *bus, uint32 timeout, int new_state) -{ - IDE_LOCK(bus); - start_waiting(bus, timeout, new_state); -} - - -// wait for sync IRQ - -void -wait_for_sync(ide_bus_info *bus) -{ - acquire_sem(bus->sync_wait_sem); - cancel_timer(&bus->timer.te); -} -*/ - -// timeout dpc handler - -static void -ide_timeout_dpc(void *arg) -{ -/* - ide_bus_info *bus = (ide_bus_info *)arg; - ata_request *request; - ide_device_info *device; - - device = request->device; - - dprintf("ide: ide_timeout_dpc() bus %p, device %p\n", bus, device); - - // this also resets overlapped commands -// reset_device(device, request); - - device->subsys_status = SCSI_CMD_TIMEOUT; - - if (request->uses_dma) { - if (++device->DMA_failures >= MAX_DMA_FAILURES) { - dprintf("Disabling DMA because of too many errors\n"); - - device->DMA_enabled = false; - } - } - - // let upper layer do the retry - finish_checksense(request); -*/ -} - - -// timeout handler, called by system timer - -status_t -ide_timeout(timer *arg) -{ - ide_bus_info *bus = ((ide_bus_timer_info *)arg)->bus; - - dprintf("ide: ide_timeout() bus %p\n", bus); - -/* - // we need to lock bus to have a solid bus state - // (side effect: we lock out the IRQ handler) - IDE_LOCK(bus); - - switch (bus->state) { - case ide_state_async_waiting: - TRACE(("async waiting\n")); - - bus->state = ide_state_accessing; - - IDE_UNLOCK(bus); - - scsi->schedule_dpc(bus->scsi_cookie, bus->irq_dpc, ide_timeout_dpc, bus); - return B_INVOKE_SCHEDULER; - - case ide_state_sync_waiting: - TRACE(("sync waiting\n")); - - bus->state = ide_state_accessing; - bus->sync_wait_timeout = true; - - IDE_UNLOCK(bus); - - release_sem_etc(bus->sync_wait_sem, 1, B_DO_NOT_RESCHEDULE); - return B_INVOKE_SCHEDULER; - - case ide_state_accessing: - TRACE(("came too late - IRQ occured already\n")); - - IDE_UNLOCK(bus); - return B_DO_NOT_RESCHEDULE; - - default: - // this case also happens if a timeout fires too late; - // unless there is a bug, the timeout should always be canceled - // before declaring bus as being idle - dprintf("BUG: unknown state (%d)\n", (int)bus->state); - - IDE_UNLOCK(bus); - return B_DO_NOT_RESCHEDULE; - } -*/ - return B_DO_NOT_RESCHEDULE; -} - - - - -/** finish bus access; - * check if any device wants to service pending commands + execute synced_pc - */ - -void -access_finished(ide_bus_info *bus, ide_device_info *device) -{ - TRACE(("bus = %p, device = %p\n", bus, device)); - - // this would be the correct place to called synced pc -} diff --git a/src/add-ons/kernel/bus_managers/ata/virtual_memory.c b/src/add-ons/kernel/bus_managers/ata/virtual_memory.c deleted file mode 100644 index 16b4d4a8cc..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/virtual_memory.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * - * Distributed under the terms of the MIT License. - */ - -/* - VM helper functions. - - Important assumption: get_memory_map must combine adjacent - physical pages, so contignous memory always leads to a S/G - list of length one. -*/ - -#include "KernelExport_ext.h" -#include "wrapper.h" - -#include - - -/** get sg list of iovec - * TBD: this should be moved to somewhere in kernel - */ - -status_t -get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len, - physical_entry *map, size_t max_entries, size_t *num_entries, size_t *mapped_len) -{ - size_t cur_idx; - size_t left_len; - - SHOW_FLOW(3, "vec_count=%lu, vec_offset=%lu, len=%lu, max_entries=%lu", - vec_count, vec_offset, len, max_entries); - - // skip iovec blocks if needed - while (vec_count > 0 && vec_offset > vec->iov_len) { - vec_offset -= vec->iov_len; - --vec_count; - ++vec; - } - - for (left_len = len, cur_idx = 0; left_len > 0 && vec_count > 0 && cur_idx < max_entries;) { - char *range_start; - size_t range_len; - status_t res; - size_t cur_num_entries, cur_mapped_len; - uint32 tmp_idx; - - SHOW_FLOW( 3, "left_len=%d, vec_count=%d, cur_idx=%d", - (int)left_len, (int)vec_count, (int)cur_idx ); - - // map one iovec - range_start = (char *)vec->iov_base + vec_offset; - range_len = min( vec->iov_len - vec_offset, left_len ); - - SHOW_FLOW( 3, "range_start=%x, range_len=%x", - (int)range_start, (int)range_len ); - - vec_offset = 0; - - if ((res = get_memory_map(range_start, range_len, &map[cur_idx], - max_entries - cur_idx)) != B_OK) { - // according to docu, no error is ever reported - argh! - SHOW_ERROR(1, "invalid io_vec passed (%s)", strerror(res)); - return res; - } - - // stupid: get_memory_map does neither tell how many sg blocks - // are used nor whether there were enough sg blocks at all; - // -> determine that manually - cur_mapped_len = 0; - cur_num_entries = 0; - - for (tmp_idx = cur_idx; tmp_idx < max_entries; ++tmp_idx) { - if (map[tmp_idx].size == 0) - break; - - cur_mapped_len += map[tmp_idx].size; - ++cur_num_entries; - } - - if (cur_mapped_len == 0) { - panic("get_memory_map() returned empty list; left_len=%d, idx=%d/%d", - (int)left_len, (int)cur_idx, (int)max_entries); - SHOW_ERROR(2, "get_memory_map() returned empty list; left_len=%d, idx=%d/%d", - (int)left_len, (int)cur_idx, (int)max_entries); - return B_ERROR; - } - - SHOW_FLOW( 3, "cur_num_entries=%d, cur_mapped_len=%x", - (int)cur_num_entries, (int)cur_mapped_len ); - - // try to combine with previous sg block - if (cur_num_entries > 0 && cur_idx > 0 - && map[cur_idx].address == (char *)map[cur_idx - 1].address + map[cur_idx - 1].size) { - SHOW_FLOW0( 3, "combine with previous chunk" ); - map[cur_idx - 1].size += map[cur_idx].size; - memcpy(&map[cur_idx], &map[cur_idx + 1], (cur_num_entries - 1) * sizeof(map[0])); - --cur_num_entries; - } - - cur_idx += cur_num_entries; - left_len -= cur_mapped_len; - - // advance iovec if current one is described completely - if (cur_mapped_len == range_len) { - ++vec; - --vec_count; - } - } - - *num_entries = cur_idx; - *mapped_len = len - left_len; - - SHOW_FLOW( 3, "num_entries=%d, mapped_len=%x", - (int)*num_entries, (int)*mapped_len ); - - return B_OK; -} - diff --git a/src/add-ons/kernel/bus_managers/ata/wrapper.h b/src/add-ons/kernel/bus_managers/ata/wrapper.h deleted file mode 100644 index 07a659b296..0000000000 --- a/src/add-ons/kernel/bus_managers/ata/wrapper.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _WRAPPER_H -#define _WRAPPER_H - -#include -#include - - -// benaphores - -#define INIT_BEN(x, prefix) (mutex_init_etc(x, prefix, MUTEX_FLAG_CLONE_NAME), \ - B_OK) -#define DELETE_BEN(x) mutex_destroy(x) -#define ACQUIRE_BEN(x) mutex_lock(x) -#define RELEASE_BEN(x) mutex_unlock(x) - -// debug output - -#ifdef DEBUG_WAIT_ON_MSG -# define DEBUG_WAIT snooze( DEBUG_WAIT_ON_MSG ); -#else -# define DEBUG_WAIT -#endif - -#ifdef DEBUG_WAIT_ON_ERROR -# define DEBUG_WAIT_ERROR snooze( DEBUG_WAIT_ON_ERROR ); -#else -# define DEBUG_WAIT_ERROR -#endif - -#ifndef DEBUG_MAX_LEVEL_FLOW -# define DEBUG_MAX_LEVEL_FLOW 4 -#endif - -#ifndef DEBUG_MAX_LEVEL_INFO -# define DEBUG_MAX_LEVEL_INFO 4 -#endif - -#ifndef DEBUG_MAX_LEVEL_ERROR -# define DEBUG_MAX_LEVEL_ERROR 4 -#endif - -#ifndef DEBUG_MSG_PREFIX -# define DEBUG_MSG_PREFIX "" -#endif - -#ifndef debug_level_flow -# define debug_level_flow 4 -#endif - -#ifndef debug_level_info -# define debug_level_info 4 -#endif - -#ifndef debug_level_error -# define debug_level_error 4 -#endif - -#define FUNC_NAME DEBUG_MSG_PREFIX, __FUNCTION__ - -#define SHOW_FLOW(seriousness, format, param...) \ - do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_FLOW0(seriousness, format) \ - do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_INFO(seriousness, format, param...) \ - do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_INFO0(seriousness, format) \ - do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_ERROR(seriousness, format, param...) \ - do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT_ERROR \ - }} while( 0 ) - -#define SHOW_ERROR0(seriousness, format) \ - do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT_ERROR \ - }} while( 0 ) - -#endif /* _BENAPHORE_H */