diff --git a/src/add-ons/kernel/bus_managers/ata/ata.c b/src/add-ons/kernel/bus_managers/ata/ata.c index 1990955937..e2f135bc28 100644 --- a/src/add-ons/kernel/bus_managers/ata/ata.c +++ b/src/add-ons/kernel/bus_managers/ata/ata.c @@ -130,15 +130,14 @@ ata_wait_for_drdy(ide_bus_info *bus) status_t ata_pio_wait_drdy(ide_device_info *device) { - ASSERT(bus->state == ata_state_pio); - return ata_wait(bus, ide_status_drdy, ide_status_bsy, false, device->bus->pio_timeout); + ASSERT(device->bus->state == ata_state_pio); + return ata_wait(device->bus, ide_status_drdy, ide_status_bsy, false, device->pio_timeout); } - status_t -ata_send_command(ide_device_info *device, ata_request *request, - bool need_drdy, uint32 timeout, ata_bus_state new_state) +ata_send_command(ide_device_info *device, ata_request *request, bool need_drdy, + uint32 timeout, ata_bus_state new_state) { ide_bus_info *bus = device->bus; @@ -170,13 +169,13 @@ ata_send_command(ide_device_info *device, ata_request *request, // resetting the device here will discard current configuration, // it's better when the SCSI bus manager requests an external reset. TRACE("device selection timeout\n"); - device->subsys_status = SCSI_SEL_TIMEOUT; + ata_request_set_status(request, SCSI_SEL_TIMEOUT); return B_ERROR; } if (need_drdy && (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) { TRACE("drdy not set\n"); - device->subsys_status = SCSI_SEQUENCE_FAIL; + ata_request_set_status(request, SCSI_SEQUENCE_FAIL); return B_ERROR; } @@ -200,7 +199,8 @@ ata_send_command(ide_device_info *device, ata_request *request, ASSERT(bus->state == ata_state_busy); bus->state = new_state; - bus->pio_timeout = timeout * 1000; + if (request) + request->device->pio_timeout = timeout * 1000; IDE_UNLOCK(bus); @@ -212,7 +212,7 @@ err_clearint: bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien); err: - device->subsys_status = SCSI_HBA_ERR; + ata_request_set_status(request, SCSI_HBA_ERR); IDE_UNLOCK(bus); return B_ERROR; } @@ -220,6 +220,7 @@ err: status_t ata_finish_command(ide_device_info *device) { + return B_OK; } @@ -292,7 +293,7 @@ ata_reset_bus(ide_bus_info *bus, bool *_devicePresent0, uint32 *_sigDev0, bool * dprintf("ATA: reset_bus: timeout\n"); goto error; } -timeout + 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; @@ -339,6 +340,7 @@ ata_reset_device(ide_device_info *device, bool *_devicePresent) static bool check_rw_status(ide_device_info *device, bool drqStatus) { +/* ide_bus_info *bus = device->bus; int status; @@ -353,7 +355,7 @@ check_rw_status(ide_device_info *device, bool drqStatus) device->subsys_status = SCSI_SEQUENCE_FAIL; return false; } - +*/ return true; } @@ -456,6 +458,7 @@ finish: void ata_dpc_DMA(ata_request *request) { +/* ide_device_info *device = request->device; bool dma_success, dev_err; @@ -480,6 +483,7 @@ ata_dpc_DMA(ata_request *request) // reset queue in case queuing is active finish_reset_queue(request); } +*/ } @@ -578,8 +582,7 @@ create_rw_taskfile(ide_device_info *device, ata_request *request, track_size = infoblock->current_heads * infoblock->current_sectors; if (track_size == 0) { - set_sense(device, - SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED); + ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED); return false; } @@ -600,7 +603,7 @@ create_rw_taskfile(ide_device_info *device, ata_request *request, return true; err: - set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); + ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); return false; } @@ -669,7 +672,7 @@ err_setup: if (request->uses_dma) abort_dma(device, request); - finish_checksense(request); + ata_request_finish(request, false); return; err_send: @@ -678,7 +681,9 @@ err_send: if (request->uses_dma) abort_dma(device, request); - finish_reset_queue(request); +// finish_reset_queue(request); + ata_request_finish(request, false); + } diff --git a/src/add-ons/kernel/bus_managers/ata/ata_request.c b/src/add-ons/kernel/bus_managers/ata/ata_request.c index 27618528a7..f6f66cbd89 100644 --- a/src/add-ons/kernel/bus_managers/ata/ata_request.c +++ b/src/add-ons/kernel/bus_managers/ata/ata_request.c @@ -74,6 +74,8 @@ void ata_request_set_status(ata_request *request, uint8 status) { ASSERT(status != SCSI_REQ_CMP); + if (!request) + return; request->ccb->subsys_status = status; } @@ -81,6 +83,8 @@ ata_request_set_status(ata_request *request, uint8 status) void ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq) { + if (!request) + return; request->senseKey = key; request->senseAsc = asc_acq >> 8; request->senseAscq = asc_acq & 0xff; diff --git a/src/add-ons/kernel/bus_managers/ata/atapi.c b/src/add-ons/kernel/bus_managers/ata/atapi.c index 290264a738..c963882f90 100644 --- a/src/add-ons/kernel/bus_managers/ata/atapi.c +++ b/src/add-ons/kernel/bus_managers/ata/atapi.c @@ -25,6 +25,9 @@ // 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 @@ -45,7 +48,7 @@ check_packet_error(ide_device_info *device, ata_request *request) if (bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_error) != B_OK) { - device->subsys_status = SCSI_HBA_ERR; + ata_request_set_status(request, SCSI_HBA_ERR); return true; } @@ -77,10 +80,14 @@ check_packet_error(ide_device_info *device, ata_request *request) // tell SCSI layer that sense must be requested // (we don't take care of auto-sense ourselve) - device->subsys_status = SCSI_REQ_CMP_ERR; + + // 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; } @@ -113,7 +120,7 @@ packet_dpc(ata_request *request) if (!device->tf.packet_res.cmd_or_data || device->tf.packet_res.input_or_output || (status & ide_status_drq) == 0) { - device->subsys_status = SCSI_SEQUENCE_FAIL; + ata_request_set_status(request, SCSI_SEQUENCE_FAIL); goto err; } @@ -125,7 +132,7 @@ packet_dpc(ata_request *request) true) != B_OK) { SHOW_ERROR0( 1, "Error sending command packet" ); - device->subsys_status = SCSI_HBA_ERR; + ata_request_set_status(request, SCSI_HBA_ERR); goto err_cancel_timer; } @@ -186,7 +193,7 @@ packet_dpc(ata_request *request) SHOW_FLOW0(3, "data transmission"); if (device->tf.packet_res.cmd_or_data) { - device->subsys_status = SCSI_SEQUENCE_FAIL; + ata_request_set_status(request, SCSI_SEQUENCE_FAIL); goto err; } @@ -233,7 +240,7 @@ packet_dpc(ata_request *request) if (err == B_ERROR) { SHOW_ERROR0(2, "Error during PIO transmission"); - device->subsys_status = SCSI_HBA_ERR; + ata_request_set_status(request, SCSI_HBA_ERR); goto err_cancel_timer; } @@ -376,7 +383,7 @@ send_packet(ide_device_info *device, ata_request *request, bool write) if (!device->tf.packet_res.cmd_or_data || device->tf.packet_res.input_or_output) { - device->subsys_status = SCSI_SEQUENCE_FAIL; + ata_request_set_status(request, SCSI_SEQUENCE_FAIL); goto err_setup; } @@ -427,7 +434,7 @@ err_packet2: IDE_UNLOCK(bus); err_packet: - device->subsys_status = SCSI_HBA_ERR; + data_request_set_status(request, SCSI_HBA_ERR); err_setup: if (request->uses_dma) @@ -442,6 +449,8 @@ err_setup: void atapi_exec_io(ide_device_info *device, ata_request *request) { + TRACE("atapi_exec_io\n"); +/* scsi_ccb *ccb = request->ccb; SHOW_FLOW(3, "command=%x", request->ccb->cdb[0]); @@ -463,6 +472,7 @@ atapi_exec_io(ide_device_info *device, ata_request *request) send_packet(device, request, (ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_OUT); } +*/ } diff --git a/src/add-ons/kernel/bus_managers/ata/devices.c b/src/add-ons/kernel/bus_managers/ata/devices.c index f508dc3165..85f255f3bf 100644 --- a/src/add-ons/kernel/bus_managers/ata/devices.c +++ b/src/add-ons/kernel/bus_managers/ata/devices.c @@ -24,76 +24,12 @@ #define TRACE(x...) dprintf("IDE: " x) -/** 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 (device->other_device) { - if (device->other_device != device) { - device->other_device->other_device = device->other_device; - bus->first_device = device->other_device; - } else - bus->first_device = NULL; - } - - device->other_device = NULL; -} - - -/** destroy device info */ - -void -destroy_device(ide_device_info *device) -{ - TRACE("destroy_device: device %p\n", device); - - // paranoia - device->exec_io = NULL; - - 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; - - device->other_device = device; - - if (device->is_device1) { - if (bus->devices[0]) { - device->other_device = bus->devices[0]; - bus->devices[0]->other_device = device; - } - } else { - if (bus->devices[1]) { - device->other_device = bus->devices[1]; - bus->devices[1]->other_device = device; - } - } - - if (bus->first_device == NULL) - bus->first_device = device; -} +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) { @@ -115,10 +51,12 @@ create_device(ide_bus_info *bus, bool is_device1) device->DMA_failures = 0; device->num_failed_send = 0; - device->combined_sense = 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); @@ -131,6 +69,49 @@ create_device(ide_bus_info *bus, bool is_device1) 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 { \ @@ -154,7 +135,7 @@ create_device(ide_bus_info *bus, bool is_device1) /** prepare infoblock for further use, i.e. fix endianess */ static void -prep_infoblock(ide_device_info *device) +fix_infoblock_endian(ide_device_info *device) { ide_device_infoblock *infoblock = &device->infoblock; @@ -183,9 +164,7 @@ scan_device(ide_device_info *device, bool isAtapi) return B_ERROR; } - device->subsys_status = SCSI_REQ_CMP; - - prep_infoblock(device); + fix_infoblock_endian(device); return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/ata/emulation.c b/src/add-ons/kernel/bus_managers/ata/emulation.c index 1048b0b7a7..aa6be3ed4d 100644 --- a/src/add-ons/kernel/bus_managers/ata/emulation.c +++ b/src/add-ons/kernel/bus_managers/ata/emulation.c @@ -12,44 +12,9 @@ #include "ide_sim.h" #include - #include -/*! Emulate REQUEST SENSE */ -void -ide_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; - - // cannot use finish_checksense here, as data is not copied into autosense buffer - // but into normal data buffer, SCSI result is GOOD and CAM status is REQ_CMP - - if (device->combined_sense) - create_sense(device, &sense); - else - memset(&sense, 0, sizeof(sense)); - - copy_sg_data(ccb, 0, cmd->allocation_length, &sense, sizeof(sense), false); - - // reset sense information on read - device->combined_sense = 0; - - transferSize = min(sizeof(sense), cmd->allocation_length); - transferSize = min(transferSize, ccb->data_length); - - ccb->data_resid = ccb->data_length - transferSize; - - // normally, all flags are set to "success", but for Request Sense - // this would have overwritten the sense we want to read - device->subsys_status = SCSI_REQ_CMP; - ccb->device_status = SCSI_STATUS_GOOD; -} - - /*! Copy data between ccb data and buffer ccb - ccb to copy data from/to offset - offset of data in ccb diff --git a/src/add-ons/kernel/bus_managers/ata/ide_internal.h b/src/add-ons/kernel/bus_managers/ata/ide_internal.h index d723f81c39..8e3b49223b 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_internal.h +++ b/src/add-ons/kernel/bus_managers/ata/ide_internal.h @@ -17,6 +17,7 @@ #include "ide_device_infoblock.h" #include #include +#include "ata_request.h" #define debug_level_error 2 #define debug_level_info 1 @@ -42,7 +43,7 @@ extern device_manager_info *pnp; - +extern scsi_for_sim_interface *scsi; typedef struct ide_bus_info ide_bus_info; @@ -59,28 +60,7 @@ typedef struct ide_bus_timer_info { struct ide_bus_info *bus; } ide_bus_timer_info; -// ide request -typedef struct ata_request { - struct ide_device_info * device; - 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 -} ata_request; - - -//void init_ata_request(ata_request *request, struct ide_device_info *device, scsi_ccb *ccb); - -static inline void -init_ata_request(ata_request *request, struct ide_device_info *device, scsi_ccb *ccb) -{ - request->device = device; - request->ccb = ccb; - request->is_write = 0; - request->uses_dma = 0; - request->packet_irq = 0; -} typedef struct ide_device_info { @@ -98,14 +78,9 @@ typedef struct ide_device_info { uint8 DMA_failures; // DMA failures in a row uint8 num_failed_send; // number of consequetive send problems - // next two error codes are copied to request on finish_request & co. - uint8 subsys_status; // subsystem status of current request - uint32 new_combined_sense; // emulated sense of current request - // pending error codes - uint32 combined_sense; // emulated sense of device - - struct ide_device_info *other_device; // other device on same bus + 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 ); @@ -172,10 +147,6 @@ struct ide_bus_info { ata_bus_state state; // current state of bus - struct ata_request * requestActive; - struct ata_request * requestFree; - - benaphore status_report_ben; // to lock when you report XPT about bus state // i.e. during requeue, resubmit or finished @@ -188,7 +159,6 @@ struct ide_bus_info { ide_device_info *active_device; ide_device_info *devices[2]; - ide_device_info *first_device; uchar path_id; @@ -227,6 +197,7 @@ status_t ata_wait(ide_bus_info *bus, uint8 set, uint8 not_set, bool check_err, b 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, bool need_drdy, uint32 timeout, ata_bus_state new_state); @@ -295,6 +266,12 @@ 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); + // sync.c diff --git a/src/add-ons/kernel/bus_managers/ata/ide_sim.c b/src/add-ons/kernel/bus_managers/ata/ide_sim.c index e74d33d1dc..afb261c3d1 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.c +++ b/src/add-ons/kernel/bus_managers/ata/ide_sim.c @@ -283,15 +283,16 @@ ide_sim_init_bus(device_node_handle node, void *user_cookie, void **cookie) } bus->scsi_cookie = user_cookie; - bus->state = ata_state_idle; 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] = bus->devices[1] = NULL; + bus->devices[0] = NULL; + bus->devices[1] = NULL; status = INIT_BEN(&bus->status_report_ben, "ide_status_report"); if (status < B_OK) diff --git a/src/add-ons/kernel/bus_managers/ata/ide_sim.h b/src/add-ons/kernel/bus_managers/ata/ide_sim.h index 87f592d719..00faae56e7 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.h +++ b/src/add-ons/kernel/bus_managers/ata/ide_sim.h @@ -13,66 +13,9 @@ #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; -// set sense of current ccb -static inline void -set_sense(ide_device_info *device, int sense_key, int sense_asc) -{ - device->new_combined_sense = (sense_key << 16) | sense_asc; -} - -// retrieve key from combined sense -static inline uint8 -decode_sense_key(uint32 combined_sense) -{ - return (combined_sense >> 16) & 0xff; -} - -// retrieve asc from combined sense -static inline uint8 -decode_sense_asc(uint32 combined_sense) -{ - return (combined_sense >> 8) & 0xff; -} - -// retrieve ascq from combined sense -static inline uint8 -decode_sense_ascq(uint32 combined_sense) -{ - return combined_sense & 0xff; -} - -// retrieve asc and ascq from combined sense -static inline uint16 -decode_sense_asc_ascq(uint32 combined_sense) -{ - return combined_sense & 0xffff; -} - -void finish_request(ata_request *request, bool resubmit); -void finish_reset_queue(ata_request *request); -void finish_retry(ata_request *request); -void finish_all_requests(ide_device_info *device, ata_request *ignore, - int subsys_status, bool resubmit); -void finish_checksense(ata_request *request); - - -// start ccb by resetting sense -static inline void -start_request(ide_device_info *device, ata_request *request) -{ - device->new_combined_sense = 0; - device->subsys_status = SCSI_REQ_CMP; - request->ccb->device_status = SCSI_STATUS_GOOD; -} - - -void create_sense(ide_device_info *device, scsi_sense *sense); - - #endif diff --git a/src/add-ons/kernel/bus_managers/ata/pio.c b/src/add-ons/kernel/bus_managers/ata/pio.c index ee832e5f62..fb36bb1d84 100644 --- a/src/add-ons/kernel/bus_managers/ata/pio.c +++ b/src/add-ons/kernel/bus_managers/ata/pio.c @@ -153,7 +153,7 @@ transfer_PIO_physcont(ide_device_info *device, addr_t physicalAddress, if (vm_get_physical_page(physicalAddress, &virtualAddress, PHYSICAL_PAGE_CAN_WAIT) != B_OK) { // ouch: this should never ever happen - set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); +//xxx fix this set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); return B_ERROR; } diff --git a/src/add-ons/kernel/bus_managers/ata/scsi2ata.c b/src/add-ons/kernel/bus_managers/ata/scsi2ata.c index 5c839e00a4..f3fcdd7e83 100644 --- a/src/add-ons/kernel/bus_managers/ata/scsi2ata.c +++ b/src/add-ons/kernel/bus_managers/ata/scsi2ata.c @@ -230,7 +230,7 @@ scsi_test_unit_ready(ide_device_info *device, ata_request *request) device->tf_param_mask = 0; device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS; - if (ata_send_command(request, true, 15, ata_state_pio) != B_OK) { + if (ata_send_command(device, request, true, 15, ata_state_pio) != B_OK) { return; }