bool ide_wait( ide_device_info *device, int mask, int not_mask, bool check_err, bigtime_t timeout ) { ide_bus_info *bus = device->bus; bigtime_t start_time = system_time(); while( 1 ) { bigtime_t elapsed_time; int status; cpu_spin( 1 ); status = bus->controller->get_altstatus( bus->channel ); if( (status & mask) == mask && (status & not_mask) == 0 ) return true; if( check_err && (status & ide_status_err) != 0 ) { set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); return false; } elapsed_time = system_time() - start_time; if( elapsed_time > timeout ) { set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT ); return false; } if( elapsed_time > 3000 ) thread_snooze( elapsed_time / 10 ); } }
static READ_HANDLER( vblank_r ) { int val = readinputport( 0 ); if ( ( val & 0x02 ) ) cpu_spin(); return val; }
static int vblank_r( int offset ) { int val = readinputport( 0 ); if ( ( val & 0x02 ) ) cpu_spin(); return val; }
static READ16_HANDLER( sub_cpu_spina_r ) { int pc=cpu_get_pc(space->cpu); int ret=raiden_shared_ram[0x4]; if (pc==0xfcde8 && ret!=0x40) cpu_spin(space->cpu); return ret; }
/* Transmit a frame */ static inline void send_frame(u32 fqid, const struct qm_fd *fd) { int ret; local_fq.fqid = fqid; retry: ret = qman_enqueue(&local_fq, fd, 0); if (ret) { cpu_spin(CPU_SPIN_BACKOFF_CYCLES); goto retry; } }
/* Drop a frame (releases buffers to Bman) */ static inline void drop_frame(const struct qm_fd *fd) { struct bm_buffer buf; int ret; BUG_ON(fd->format != qm_fd_contig); bm_buffer_set64(&buf, qm_fd_addr(fd)); retry: ret = bman_release(pool[fd->bpid], &buf, 1, 0); if (ret) { cpu_spin(CPU_SPIN_BACKOFF_CYCLES); goto retry; } }
ROM_END /***************************************************************************/ /* Spin the sub-cpu if it is waiting on the master cpu */ static READ16_HANDLER( sub_cpu_spin_r ) { int pc=cpu_get_pc(space->cpu); int ret=raiden_shared_ram[0x4]; if (pc==0xfcde6 && ret!=0x40) cpu_spin(space->cpu); return ret; }
static void dpaa_buf_free(struct dpaa_bp_info *bp_info, uint64_t addr) { struct bm_buffer buf; int ret; DPAA_MEMPOOL_DEBUG("Free 0x%lx to bpid: %d", addr, bp_info->bpid); bm_buffer_set64(&buf, addr); retry: ret = bman_release(bp_info->bp, &buf, 1, 0); if (ret) { DPAA_MEMPOOL_DEBUG("BMAN busy. Retrying..."); cpu_spin(CPU_SPIN_BACKOFF_CYCLES); goto retry; } }
static void do_enqueues(struct qman_fq *fq) { unsigned int loop = test_frames; dcbt_rw(eq_capture); while (loop) { int err; if (loop == test_start) eq_capture[0] = mfatb(); retry: err = qman_enqueue(fq, &fd, 0); if (err) { eq_jam++; cpu_spin(ENQUEUE_BACKOFF); goto retry; } #ifdef TEST_FD fd_inc(&fd); #endif loop--; } eq_capture[1] = mfatb(); }
bool check_service_req( ide_device_info *device ) { ide_bus_info *bus = device->bus; int status; if( device->num_running_reqs == 0 ) return false; if( bus->controller->write_command_block_regs( bus->channel, &device->tf, ide_mask_device_head ) != NO_ERROR ) // on error, pretend that this device asks for service // -> the disappeared controller will be recognized soon return true; bus->active_device = device; // give one clock (400 ns) to take notice cpu_spin( 1 ); status = bus->controller->get_altstatus( bus->channel ); return (status & ide_status_service) != 0; }
// we need a device to store sense information // (we could just take device 0, but this were not fair if the reset // was done because of a device 1 failure) bool reset_bus( ide_device_info *device ) { ide_bus_info *bus = device->bus; ide_controller_interface *controller = bus->controller; ide_channel_cookie channel = bus->channel; SHOW_FLOW0( 3, "" ); // activate srst signal for 5 µs reset_timeouts( device ); reset_timeouts( device->other_device ); //set_irq_state( device, ide_irq_state_ignore ); SHOW_FLOW0( 3, "1" ); if( controller->write_device_control( channel, ide_devctrl_nien | ide_devctrl_srst | ide_devctrl_bit3 ) != NO_ERROR ) goto err0; SHOW_FLOW0( 3, "2" ); cpu_spin( 5 ); if( controller->write_device_control( channel, ide_devctrl_nien | ide_devctrl_bit3 ) != NO_ERROR ) goto err0; SHOW_FLOW0( 3, "3" ); // let devices wake up thread_snooze( 2000 ); SHOW_FLOW0( 3, "4" ); // ouch, we have to wait up to 31 seconds! if( !ide_wait( device, 0, ide_status_bsy, false, 31000000 )) { // we don't know which of the devices is broken // so we don't disable them if( controller->write_device_control( channel, ide_devctrl_bit3 ) != NO_ERROR ) goto err0; set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT ); goto err1; } SHOW_FLOW0( 3, "5" ); if( controller->write_device_control( channel, ide_devctrl_bit3 ) != NO_ERROR ) goto err0; SHOW_FLOW0( 3, "6" ); finish_all_requests( bus->devices[0], CAM_SCSI_BUS_RESET ); finish_all_requests( bus->devices[1], CAM_SCSI_BUS_RESET ); SHOW_FLOW0( 3, "7" ); xpt->call_async( bus->xpt_cookie, -1, -1, AC_BUS_RESET, NULL, 0 ); SHOW_FLOW0( 3, "8" ); return true; err0: set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); err1: finish_all_requests( bus->devices[0], CAM_SCSI_BUS_RESET ); finish_all_requests( bus->devices[1], CAM_SCSI_BUS_RESET ); xpt->call_async( bus->xpt_cookie, -1, -1, AC_BUS_RESET, NULL, 0 ); return false; }
bool device_start_service( ide_device_info *device, int *tag ) { ide_bus_info *bus = device->bus; bigtime_t irq_disabled_at = 0; // makes compiler happy bool irq_guard = bus->num_running_reqs > 1; device->tf.write.command = IDE_CMD_SERVICE; device->tf.queued.mode = ide_mode_lba; reset_timeouts( device ); //set_irq_state( device, ide_irq_state_ignore ); if( irq_guard ) { irq_disabled_at = system_time(); if( bus->controller->write_device_control( bus->channel, ide_devctrl_nien | ide_devctrl_bit3 ) != NO_ERROR ) goto err; } 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 set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); return false; } if( irq_guard ) { // see send_ata while( system_time() - irq_disabled_at < MAX_IRQ_DELAY ) cpu_spin( 1 ); if( bus->controller->write_device_control( bus->channel, ide_devctrl_bit3 ) != NO_ERROR ) goto err; } // here we go... if( bus->controller->write_command_block_regs( bus->channel, &device->tf, ide_mask_command ) != NO_ERROR ) goto err; if( !ide_wait( device, ide_status_drdy, ide_status_bsy, false, 1000000 )) { set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT ); return false; } if( bus->controller->read_command_block_regs( bus->channel, &device->tf, ide_mask_sector_count ) != NO_ERROR ) goto err; if( device->tf.queued.release ) { // bus release is the wrong answer to a service request set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); return false; } *tag = device->tf.queued.tag; return true; err: set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); return false; }
// 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; }