From 5f50c05486ece78f44dc41c9daf64110b6a984bc Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Wed, 9 Jan 2008 00:17:51 +0000 Subject: [PATCH] cleanup of the rescanning code git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23293 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/ata/ata.c | 32 ++-- .../kernel/bus_managers/ata/basic_protocol.c | 16 +- src/add-ons/kernel/bus_managers/ata/devices.c | 147 +----------------- .../kernel/bus_managers/ata/ide_internal.h | 2 +- src/add-ons/kernel/bus_managers/ata/ide_sim.c | 33 ++-- 5 files changed, 49 insertions(+), 181 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ata/ata.c b/src/add-ons/kernel/bus_managers/ata/ata.c index b8cd17ca99..b0d235de53 100644 --- a/src/add-ons/kernel/bus_managers/ata/ata.c +++ b/src/add-ons/kernel/bus_managers/ata/ata.c @@ -845,32 +845,34 @@ ata_read_infoblock(ide_device_info *device, bool isAtapi) ide_bus_info *bus = device->bus; int status; - TRACE("ata_read_infoblock: device %p, isAtapi %d\n", device, isAtapi); + TRACE("ata_read_infoblock: bus %p, device %d, isAtapi %d\n", device->bus, device->is_device1, isAtapi); // disable interrupts bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien); - device->tf_param_mask = 0; - device->tf.write.command = isAtapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE : IDE_CMD_IDENTIFY_DEVICE; - // initialize device selection flags, // this is the only place where this bit gets initialized in the task file if (bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, ide_mask_device_head) != B_OK) { TRACE("ata_read_infoblock: read_command_block_regs failed\n"); - return B_ERROR; + goto error; } - device->tf.lba.device = device->is_device1; + ata_select_device(device->bus, device->is_device1); + + device->tf.lba.device = device->is_device1; // XXX fix me + + device->tf_param_mask = 0; + device->tf.write.command = isAtapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE : IDE_CMD_IDENTIFY_DEVICE; if (!send_command(device, NULL, isAtapi ? false : true, 20, ide_state_sync_waiting)) { TRACE("ata_read_infoblock: send_command failed\n"); - return B_ERROR; + goto error; } if (ata_wait(bus, ide_status_drq, ide_status_bsy, true, 4000000) != B_OK) { TRACE("ata_read_infoblock: wait failed\n"); - return B_ERROR; + goto error; } // get the infoblock @@ -879,9 +881,21 @@ ata_read_infoblock(ide_device_info *device, bool isAtapi) if (!wait_for_drqdown(device)) { TRACE("scan_device_int: wait_for_drqdown failed\n"); - return false; + goto error; } + IDE_LOCK(bus); + bus->state = ide_state_idle; + cancel_timer(&bus->timer.te); + IDE_UNLOCK(bus); + TRACE("ata_read_infoblock: success\n"); return B_OK; + +error: + IDE_LOCK(bus); + bus->state = ide_state_idle; + cancel_timer(&bus->timer.te); + IDE_UNLOCK(bus); + return B_ERROR; } diff --git a/src/add-ons/kernel/bus_managers/ata/basic_protocol.c b/src/add-ons/kernel/bus_managers/ata/basic_protocol.c index 65dea4ede4..f53b5565e1 100644 --- a/src/add-ons/kernel/bus_managers/ata/basic_protocol.c +++ b/src/add-ons/kernel/bus_managers/ata/basic_protocol.c @@ -54,22 +54,20 @@ wait_for_drdy(ide_device_info *device) status_t -reset_bus(ide_bus_info *bus, uint32 *sigDev0, uint32 *sigDev1) +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; ide_task_file tf; status_t status; - bool devicePresent0; - bool devicePresent1; dprintf("ATA: reset_bus %p\n", bus); - devicePresent0 = ata_is_device_present(bus, 0); - devicePresent1 = ata_is_device_present(bus, 1); + *devicePresent0 = ata_is_device_present(bus, 0); + *devicePresent1 = ata_is_device_present(bus, 1); - dprintf("ATA: reset_bus: ata_is_device_present device 0, present %d\n", devicePresent0); - dprintf("ATA: reset_bus: ata_is_device_present device 1, present %d\n", devicePresent1); + dprintf("ATA: reset_bus: ata_is_device_present device 0, present %d\n", *devicePresent0); + dprintf("ATA: reset_bus: ata_is_device_present device 1, present %d\n", *devicePresent1); // 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) @@ -81,7 +79,7 @@ reset_bus(ide_bus_info *bus, uint32 *sigDev0, uint32 *sigDev1) goto error; snooze(150000); - if (devicePresent0) { + if (*devicePresent0) { ata_select_device(bus, 0); dprintf("altstatus device 0: %x\n", controller->get_altstatus(channel)); @@ -108,7 +106,7 @@ reset_bus(ide_bus_info *bus, uint32 *sigDev0, uint32 *sigDev1) *sigDev0 = 0; } - if (devicePresent1) { + if (*devicePresent1) { ata_select_device(bus, 1); dprintf("altstatus device 1: %x\n", controller->get_altstatus(channel)); diff --git a/src/add-ons/kernel/bus_managers/ata/devices.c b/src/add-ons/kernel/bus_managers/ata/devices.c index 7b2a0d2927..9c0cfb809d 100644 --- a/src/add-ons/kernel/bus_managers/ata/devices.c +++ b/src/add-ons/kernel/bus_managers/ata/devices.c @@ -184,108 +184,6 @@ prep_infoblock(ide_device_info *device) } -/** read info block of ATA or ATAPI device */ -/* -static bool -scan_device_int(ide_device_info *device, bool atapi) -{ - ide_bus_info *bus = device->bus; - int status; - - TRACE("scan_device_int: device %p, atapi %d\n", device, atapi); - - device->tf_param_mask = 0; - device->tf.write.command = atapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE - : IDE_CMD_IDENTIFY_DEVICE; - - // initialize device selection flags, - // this is the only place where this bit gets initialized in the task file - if (bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, - ide_mask_device_head) != B_OK) { - TRACE("scan_device_int: read_command_block_regs failed\n"); - return false; - } - - device->tf.lba.device = device->is_device1; - - if (!send_command(device, NULL, atapi ? false : true, 20, ide_state_sync_waiting)) { - TRACE("scan_device_int: send_command failed\n"); - return false; - } - - // do a short wait first - if there's no device at all we could wait forever - // ToDo: have a look at this; if it times out (when the time is too short), - // the kernel seems to crash a little later)! - TRACE("scan_device_int: waiting 100ms...\n"); - if (acquire_sem_etc(bus->sync_wait_sem, 1, B_RELATIVE_TIMEOUT, 100000) == B_TIMED_OUT) { - bool cont; - - TRACE("scan_device_int: no fast response to inquiry\n"); - - // check the busy flag - if it's still set, there's probably no device - IDE_LOCK(bus); - - status = bus->controller->get_altstatus(bus->channel_cookie); - cont = (status & ide_status_bsy) == ide_status_bsy; - - IDE_UNLOCK(bus); - - TRACE("scan_device_int: status %#04x\n", status); - - if (!cont) { - TRACE("scan_device_int: busy bit not set after 100ms - probably noone there\n"); - // no reaction -> abort waiting - cancel_irq_timeout(bus); - - // timeout or irq may have been fired, reset semaphore just is case - acquire_sem_etc(bus->sync_wait_sem, 1, B_RELATIVE_TIMEOUT, 0); - - TRACE("scan_device_int: aborting because busy bit not set\n"); - return false; - } - - TRACE("scan_device_int: busy bit set, give device more time\n"); - - // there is something, so wait for it - acquire_sem(bus->sync_wait_sem); - } - TRACE("scan_device_int: got a fast response\n"); - - // cancel the timeout manually; usually this is done by wait_for_sync(), but - // we've used the wait semaphore directly - cancel_irq_timeout(bus); - - if (bus->sync_wait_timeout) { - TRACE("scan_device_int: aborting on sync_wait_timeout\n"); - return false; - } - - ide_wait(device, ide_status_drq, ide_status_bsy, true, 1000); - - status = bus->controller->get_altstatus(bus->channel_cookie); - - if ((status & ide_status_err) != 0) { - // if there's no device, all bits including the error bit are set - TRACE("scan_device_int: error bit set - no device or wrong type (status: %#04x)\n", status); - return false; - } - - // get the infoblock - bus->controller->read_pio(bus->channel_cookie, (uint16 *)&device->infoblock, - sizeof(device->infoblock) / sizeof(uint16), false); - - if (!wait_for_drqdown(device)) { - TRACE("scan_device_int: wait_for_drqdown failed\n"); - return false; - } - - TRACE("scan_device_int: device found\n"); - - prep_infoblock(device); - return true; -} -*/ - /** scan one device */ status_t scan_device(ide_device_info *device, bool isAtapi) @@ -297,49 +195,8 @@ scan_device(ide_device_info *device, bool isAtapi) return B_ERROR; } + device->subsys_status = SCSI_REQ_CMP; + prep_infoblock(device); return B_OK; } - -/* -void -scan_device_worker(ide_bus_info *bus, void *arg) -{ - int is_device1 = (int)arg; - ide_device_info *device; - - TRACE("scan_device_worker: bus %p, device-number %d\n", bus, is_device1); - - // forget everything we know about the device; - // don't care about peripheral drivers using this device - // as the device info is only used by us and not published - // directly or indirectly to the SCSI bus manager - if (bus->devices[is_device1]) - destroy_device(bus->devices[is_device1]); - - device = create_device(bus, is_device1); - - // reset status so we can see what goes wrong during detection - device->subsys_status = SCSI_REQ_CMP; - - if (scan_device_int(device, false)) { - if (!prep_ata(device)) - goto err; - } else if (device->subsys_status != SCSI_TID_INVALID - && scan_device_int(device, true)) { - // only try ATAPI if there is at least some device - // (see send_command - this error code must be unique!) - if (!prep_atapi(device)) - goto err; - } else - goto err; - - bus->state = ide_state_idle; - return; - -err: - destroy_device(device); - - bus->state = ide_state_idle; -} -*/ \ No newline at end of file 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 c0a951e532..5dd6717df0 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_internal.h +++ b/src/add-ons/kernel/bus_managers/ata/ide_internal.h @@ -365,7 +365,7 @@ bool device_start_service( ide_device_info *device, int *tag); bool check_service_req(ide_device_info *device); -status_t reset_bus(ide_bus_info *bus, uint32 *sigDev0, uint32 *sigDev1); +status_t reset_bus(ide_bus_info *bus, bool *devicePresent0, uint32 *sigDev0, bool *devicePresent1, uint32 *sigDev1); // channel_mgr.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 2d0b7b2b2a..80e676ebe7 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.c +++ b/src/add-ons/kernel/bus_managers/ata/ide_sim.c @@ -228,46 +228,45 @@ sim_path_inquiry(ide_bus_info *bus, scsi_path_inquiry *info) } -static uchar -sim_scan_bus(ide_bus_info *bus) +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; - dprintf("ATA: sim_scan_bus: bus %p\n", bus); + dprintf("ATA: scan_bus: bus %p\n", bus); if (bus->disconnected) - return SCSI_NO_HBA; + return; -// IDE_LOCK(bus); - - status = reset_bus(bus, &deviceSignature[0], &deviceSignature[1]); + status = reset_bus(bus, &devicePresent[0], &deviceSignature[0], &devicePresent[1], &deviceSignature[1]); for (i = 0; i < bus->max_devices; ++i) { if (bus->devices[i]) destroy_device(bus->devices[i]); - if (status == B_OK && deviceSignature[i] != 0) { + if (status == B_OK && devicePresent[i]) { isAtapi = deviceSignature[i] == 0xeb140101; + dprintf("ATA: scan_bus: bus %p, creating device %d\n", bus, i); device = create_device(bus, i /* isDevice1 */); - if (scan_device(device, isAtapi) != B_OK) + if (scan_device(device, isAtapi) != B_OK) { + dprintf("ATA: scan_bus: bus %p, scanning failed, destroying device %d\n", bus, i); destroy_device(device); + } } } -// IDE_UNLOCK(bus); - dprintf("ATA: sim_scan_bus: bus %p finished\n", bus); - - return SCSI_REQ_CMP; + dprintf("ATA: scan_bus: bus %p finished\n", bus); } static uchar -sim_not_scan_bus(ide_bus_info *bus) +sim_rescan_bus(ide_bus_info *bus) { - dprintf("ATA: sim_not_scan_bus\n"); + dprintf("ATA: sim_rescan_bus\n"); return SCSI_REQ_CMP; } @@ -667,7 +666,7 @@ ide_sim_init_bus(device_node_handle node, void *user_cookie, void **cookie) */ // detect devices - sim_scan_bus(bus); + scan_bus(bus); return B_OK; err5: @@ -857,7 +856,7 @@ scsi_sim_interface ide_sim_module = { (uchar (*)(scsi_sim_cookie, scsi_ccb *)) sim_term_io, (uchar (*)(scsi_sim_cookie, scsi_path_inquiry *))sim_path_inquiry, - (uchar (*)(scsi_sim_cookie)) sim_not_scan_bus, + (uchar (*)(scsi_sim_cookie)) sim_rescan_bus, (uchar (*)(scsi_sim_cookie)) sim_reset_bus, (void (*)(scsi_sim_cookie, uchar,