FreeBSD/sys/dev/drm2/radeon/radeon_device.c
/**
 * radeon_gpu_reset - reset the asic
 *
 * @rdev: radeon device pointer
 *
 * Attempt the reset the GPU if it has hung (all asics).
 * Returns 0 for success or an error on failure.
 */
reset the asic
@rdev: radeon device pointer

Attempt the reset the GPU if it has hung (all asics).
Returns 0 for success or an error on failure.
reset the asic @rdev : radeon device pointer Attempt the reset the GPU if it has hung ( all asics ) . Returns 0 for success or an error on failure .
int radeon_gpu_reset(struct radeon_device *rdev)
{
	unsigned ring_sizes[RADEON_NUM_RINGS];
	uint32_t *ring_data[RADEON_NUM_RINGS];
	bool saved = false;
	int i, r;
	int resched;
	sx_xlock(&rdev->exclusive_lock);
	radeon_save_bios_scratch_regs(rdev);
	resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
	radeon_suspend(rdev);
	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
		ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
						   &ring_data[i]);
		if (ring_sizes[i]) {
			saved = true;
			dev_info(rdev->dev, "Saved %d dwords of commands "
				 "on ring %d.\n", ring_sizes[i], i);
		}
	}
retry:
	r = radeon_asic_reset(rdev);
	if (!r) {
		dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n");
		radeon_resume(rdev);
	}
	radeon_restore_bios_scratch_regs(rdev);
	if (!r) {
		for (i = 0; i < RADEON_NUM_RINGS; ++i) {
			radeon_ring_restore(rdev, &rdev->ring[i],
					    ring_sizes[i], ring_data[i]);
			ring_sizes[i] = 0;
			ring_data[i] = NULL;
		}
		r = radeon_ib_ring_tests(rdev);
		if (r) {
			dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
			if (saved) {
				saved = false;
				radeon_suspend(rdev);
				goto retry;
			}
		}
	} else {
		radeon_fence_driver_force_completion(rdev);
		for (i = 0; i < RADEON_NUM_RINGS; ++i) {
			free(ring_data[i], DRM_MEM_DRIVER);
		}
	}
	drm_helper_resume_force_mode(rdev->ddev);
	ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
	if (r) {
		dev_info(rdev->dev, "GPU reset failed\n");
	}
	sx_xunlock(&rdev->exclusive_lock);
	return r;
}
int radeon_gpu_reset ( struct radeon_device * rdev ) { unsigned ring_sizes [ RADEON_NUM_RINGS ] ; uint32_t * ring_data [ RADEON_NUM_RINGS ] ; bool saved = false ; int i , r ; int resched ; sx_xlock ( & rdev -> exclusive_lock ) ; radeon_save_bios_scratch_regs ( rdev ) ; resched = ttm_bo_lock_delayed_workqueue ( & rdev -> mman . bdev ) ; radeon_suspend ( rdev ) ; for ( i = 0 ; i < RADEON_NUM_RINGS ; ++ i ) { ring_sizes [ i ] = radeon_ring_backup ( rdev , & rdev -> ring [ i ] , & ring_data [ i ] ) ; if ( ring_sizes [ i ] ) { saved = true ; dev_info ( rdev -> dev , " " " \n " , ring_sizes [ i ] , i ) ; } } retry : r = radeon_asic_reset ( rdev ) ; if ( ! r ) { dev_info ( rdev -> dev , " \n " ) ; radeon_resume ( rdev ) ; } radeon_restore_bios_scratch_regs ( rdev ) ; if ( ! r ) { for ( i = 0 ; i < RADEON_NUM_RINGS ; ++ i ) { radeon_ring_restore ( rdev , & rdev -> ring [ i ] , ring_sizes [ i ] , ring_data [ i ] ) ; ring_sizes [ i ] = 0 ; ring_data [ i ] = NULL ; } r = radeon_ib_ring_tests ( rdev ) ; if ( r ) { dev_err ( rdev -> dev , " \n " , r ) ; if ( saved ) { saved = false ; radeon_suspend ( rdev ) ; goto retry ; } } } else { radeon_fence_driver_force_completion ( rdev ) ; for ( i = 0 ; i < RADEON_NUM_RINGS ; ++ i ) { free ( ring_data [ i ] , DRM_MEM_DRIVER ) ; } } drm_helper_resume_force_mode ( rdev -> ddev ) ; ttm_bo_unlock_delayed_workqueue ( & rdev -> mman . bdev , resched ) ; if ( r ) { dev_info ( rdev -> dev , " \n " ) ; } sx_xunlock ( & rdev -> exclusive_lock ) ; return r ; }
radeon_gpu_reset - reset the asic
 @rdev: radeon device pointer
radeon_gpu_reset - reset the asic @rdev : radeon device pointer
/* block TTM */ /* bad news, how to tell it to userspace ? */