Esempio n. 1
0
void
Fish::collision_tile(uint32_t tile_attributes)
{
  if(tile_attributes & Tile::WATER) {
    start_waiting();
    movement = Vector(0, 0);
  }
}
Esempio n. 2
0
/*! Start waiting for DMA to be finished */
void
start_dma_wait(ide_device_info *device, ide_qrequest *qrequest)
{
	ide_bus_info *bus = device->bus;

	bus->controller->start_dma(bus->channel_cookie);

	start_waiting(bus, qrequest->request->timeout > 0 ? 
		qrequest->request->timeout : IDE_STD_TIMEOUT, ide_state_async_waiting);
}
Esempio n. 3
0
void
Fish::collision_tile(uint32_t tile_attributes)
{
  if ((tile_attributes & Tile::WATER) && (physic.get_velocity_y() >= 0)) {

    // initialize stop position if uninitialized
    if (stop_y == 0) stop_y = get_pos().y + bbox.get_height();

    // stop when we have reached the stop position
    if (get_pos().y >= stop_y) {
      if(!frozen)
        start_waiting();
      movement = Vector(0, 0);
    }

  }
}
Esempio n. 4
0
void
Fish::unfreeze()
{ // does this happen at all? (or do fishes die when they fall frozen?)
  BadGuy::unfreeze();
  start_waiting();
}
Esempio n. 5
0
bool
send_command(ide_device_info *device, ide_qrequest *qrequest,
	bool need_drdy, uint32 timeout, ide_bus_state new_state)
{
	ide_bus_info *bus = device->bus;
	bigtime_t irq_disabled_at = 0; // make compiler happy
	uint8 num_retries = 0;
	bool irq_guard;

retry:
	irq_guard = bus->num_running_reqs > 1;

	SHOW_FLOW(3, "qrequest=%p, request=%p", qrequest,
		qrequest ? qrequest->request : NULL);

	// if there are pending requests, IRQs must be disabled to
	// not mix up IRQ reasons
	// XXX can we avoid that with the IDE_LOCK trick? It would
	//     save some work and the bug workaround!
	if (irq_guard) {
		if (bus->controller->write_device_control(bus->channel_cookie,
				ide_devctrl_nien | ide_devctrl_bit3) != B_OK)
			goto err;

		irq_disabled_at = system_time();
	}

	// select device
	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
			ide_mask_device_head) != B_OK)
		goto err;

	bus->active_device = device;

	if (!ide_wait(device, 0, ide_status_bsy | ide_status_drq, false, 50000)) {
		uint8 status;

		SHOW_FLOW0(1, "device is not ready");

		status = bus->controller->get_altstatus(bus->channel_cookie);
		if (status == 0xff) {
			// there is no device (should happen during detection only)
			SHOW_FLOW0(1, "there is no device");

			// device detection recognizes this code as "all hope lost", so
			// neither replace it nor use it anywhere else
			device->subsys_status = SCSI_TID_INVALID;
			return false;
		}

		// reset device and retry
		if (reset_device(device, qrequest) && ++num_retries <= MAX_FAILED_SEND) {
			SHOW_FLOW0(1, "retrying");
			goto retry;
		}

		SHOW_FLOW0(1, "giving up");

		// reset to often - abort request
		device->subsys_status = SCSI_SEL_TIMEOUT;
		return false;
	}

	if (need_drdy
		&& (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) {
		SHOW_FLOW0(3, "drdy not set");
		device->subsys_status = SCSI_SEQUENCE_FAIL;
		return false;
	}

	// write parameters
	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
			device->tf_param_mask) != B_OK)
		goto err;

	if (irq_guard) {
		// IRQ may be fired by service requests and by the process of disabling(!)
		// them (I heard this is caused by edge triggered PCI IRQs)

		// wait at least 50 µs to catch all pending irq's
		// (at my system, up to 30 µs elapsed)

		// additionally, old drives (at least my IBM-DTTA-351010) loose
		// sync if they are pushed too hard - on heavy overlapped write
		// stress this drive tends to forget outstanding requests,
		// waiting at least 50 µs seems(!) to solve this
		while (system_time() - irq_disabled_at < MAX_IRQ_DELAY)
			spin(1);
	}

	// if we will start waiting once the command is sent, we have to
	// lock the bus before sending; this way, IRQs that are fired
	// shortly before/after sending of command are delayed until the
	// command is really sent (start_waiting unlocks the bus) and then
	// the IRQ handler can check savely whether the IRQ really signals
	// finishing of command or not by testing the busy-signal of the device
	if (new_state != ide_state_accessing) {
		IDE_LOCK(bus);
	}

	if (irq_guard) {
		// now it's clear why IRQs gets fired, so we can enable them again
		if (bus->controller->write_device_control(bus->channel_cookie,
				ide_devctrl_bit3) != B_OK)
			goto err1;
	}

	// write command code - this will start the actual command
	SHOW_FLOW(3, "Writing command 0x%02x", (int)device->tf.write.command);
	if (bus->controller->write_command_block_regs(bus->channel_cookie,
			&device->tf, ide_mask_command) != B_OK)
		goto err1;

	// start waiting now; also un-blocks IRQ handler (see above)
	if (new_state != ide_state_accessing)
		start_waiting(bus, timeout, new_state);

	return true;

err1:
	if (timeout > 0) {
		bus->state = ide_state_accessing;
		IDE_UNLOCK(bus);
	}

err:
	device->subsys_status = SCSI_HBA_ERR;
	return false;
}
Esempio n. 6
0
// new_state must be either accessing, async_waiting or sync_waiting
// param_mask must not include command register
bool send_command( ide_device_info *device,
	bool need_drdy, bigtime_t timeout, ide_bus_state new_state )
{
	ide_bus_info *bus = device->bus;
	bigtime_t irq_disabled_at = 0; // make compiler happy

	bool irq_guard = bus->num_running_reqs > 1;

	SHOW_FLOW0( 3, "" );

	reset_timeouts( device );

	if( irq_guard ) {
		if( bus->controller->write_device_control( bus->channel,
			ide_devctrl_nien | ide_devctrl_bit3 ) != NO_ERROR )
			goto err;

		irq_disabled_at = system_time();
	}

	if( bus->controller->write_command_block_regs( bus->channel, &device->tf,
		ide_mask_device_head ) != NO_ERROR )
		goto err;

	SHOW_FLOW0( 3, "1" );

	bus->active_device = device;

	if( !ide_wait( device, 0, ide_status_bsy | ide_status_drq, false, 50000 )) {
		uint8 status;

		SHOW_FLOW0( 1, "device is not ready" );

		status = bus->controller->get_altstatus( bus->channel );
		if( status == 0xff ) {
			// this shouldn't happen unless the device has died
			// as we only submit commands to existing devices
			// (only detection routines shoot at will)
			set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );
			return false;
		}

		if( !reset_bus( device ))
			return false;

		SHOW_FLOW0( 1, "retrying" );

		if( bus->controller->write_command_block_regs( bus->channel,
			 &device->tf, ide_mask_device_head ) != NO_ERROR )
			goto err;

		bus->active_device = device;

		if( !ide_wait( device, 0, ide_status_bsy | ide_status_drq, false, 50000 )) {
			// XXX this is not a device but a bus error, we should return
			// CAM_SEL_TIMEOUT instead
			SHOW_FLOW0( 1, "device is dead" );
			set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_LUN_SEL_FAILED );
			return false;
		}
	}

	SHOW_FLOW0( 3, "3" );

	if( need_drdy &&
		(bus->controller->get_altstatus( bus->channel ) & ide_status_drdy) == 0 )
	{
		SHOW_FLOW0( 3, "drdy not set" );
		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT );
		return false;
	}

	SHOW_FLOW0( 3, "4" );

	if( bus->controller->write_command_block_regs( bus->channel, &device->tf,
		device->tf_param_mask ) != NO_ERROR )
		goto err;

	SHOW_FLOW0( 3, "5" );

	if( irq_guard ) {
		// enable IRQs now
		// IRQ may be fired by service requests and by the process of disabling(!)
		// them (I heard this is caused by edge triggered PCI IRQs)

		// wait at least 50 µs to catch all pending irq's
		// (at my system, up to 30 µs elapsed)

		// additionally, old drives (at least my IBM-DTTA-351010) loose
		// sync if they are pushed too hard - on heavy overlapped write
		// stress this drive tends to forget outstanding requests,
		// waiting at least 50 µs seems(!) to solve this
		while( system_time() - irq_disabled_at < MAX_IRQ_DELAY )
			cpu_spin( 1 );

	}

	SHOW_FLOW0( 3, "6" );

	if( new_state != ide_state_accessing ) {
		IDE_LOCK( bus );
	}

	SHOW_FLOW( 3, "Writing command %x", (int)device->tf.write.command );
	if( bus->controller->write_command_block_regs( bus->channel,
		&device->tf, ide_mask_command ) != NO_ERROR )
		goto err2;

	SHOW_FLOW0( 3, "7" );

	if( irq_guard ) {
		if( bus->controller->write_device_control( bus->channel,
			ide_devctrl_bit3 ) != NO_ERROR )
			goto err1;
	}

	SHOW_FLOW0( 3, "8" );

	if( new_state != ide_state_accessing ) {
		start_waiting( bus, timeout, new_state );
	}

	SHOW_FLOW0( 3, "9" );

	return true;

err2:
	if( irq_guard )
		bus->controller->write_device_control( bus->channel,
			ide_devctrl_bit3 );

err1:
	if( timeout > 0 ) {
		bus->state = ide_state_accessing;
		IDE_UNLOCK( bus );
	}

err:
	set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );
	return false;
}