2005-04-17 02:20:36 +04:00
/**
2005-09-25 08:28:13 +04:00
* \ file drm_dma . c
2005-04-17 02:20:36 +04:00
* DMA IOCTL and function support
*
* \ author Rickard E . ( Rik ) Faith < faith @ valinux . com >
* \ author Gareth Hughes < gareth @ valinux . com >
*/
/*
* Created : Fri Mar 19 14 : 30 : 16 1999 by faith @ valinux . com
*
* Copyright 1999 , 2000 Precision Insight , Inc . , Cedar Park , Texas .
* Copyright 2000 VA Linux Systems , Inc . , Sunnyvale , California .
* All Rights Reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* VA LINUX SYSTEMS AND / OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*/
2011-08-31 02:16:33 +04:00
# include <linux/export.h>
2012-10-02 21:01:07 +04:00
# include <drm/drmP.h>
2014-09-11 09:43:25 +04:00
# include "drm_legacy.h"
2005-04-17 02:20:36 +04:00
/**
* Initialize the DMA data .
2005-09-25 08:28:13 +04:00
*
2005-04-17 02:20:36 +04:00
* \ param dev DRM device .
* \ return zero on success or a negative value on failure .
*
* Allocate and initialize a drm_device_dma structure .
*/
2013-08-08 17:41:19 +04:00
int drm_legacy_dma_setup ( struct drm_device * dev )
2005-04-17 02:20:36 +04:00
{
int i ;
2013-08-08 17:41:19 +04:00
if ( ! drm_core_check_feature ( dev , DRIVER_HAVE_DMA ) | |
2016-08-03 22:11:10 +03:00
! drm_core_check_feature ( dev , DRIVER_LEGACY ) )
2013-08-08 17:41:19 +04:00
return 0 ;
dev - > buf_use = 0 ;
atomic_set ( & dev - > buf_alloc , 0 ) ;
2010-05-13 23:58:56 +04:00
dev - > dma = kzalloc ( sizeof ( * dev - > dma ) , GFP_KERNEL ) ;
2005-09-25 08:28:13 +04:00
if ( ! dev - > dma )
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
2005-09-25 08:28:13 +04:00
for ( i = 0 ; i < = DRM_MAX_ORDER ; i + + )
2005-04-17 02:20:36 +04:00
memset ( & dev - > dma - > bufs [ i ] , 0 , sizeof ( dev - > dma - > bufs [ 0 ] ) ) ;
return 0 ;
}
/**
* Cleanup the DMA resources .
*
* \ param dev DRM device .
*
* Free all pages associated with DMA buffers , the buffers and pages lists , and
2007-05-09 10:57:56 +04:00
* finally the drm_device : : dma structure itself .
2005-04-17 02:20:36 +04:00
*/
2013-08-08 17:41:19 +04:00
void drm_legacy_dma_takedown ( struct drm_device * dev )
2005-04-17 02:20:36 +04:00
{
2007-07-11 10:32:08 +04:00
struct drm_device_dma * dma = dev - > dma ;
2005-09-25 08:28:13 +04:00
int i , j ;
2005-04-17 02:20:36 +04:00
2013-08-08 17:41:19 +04:00
if ( ! drm_core_check_feature ( dev , DRIVER_HAVE_DMA ) | |
2016-08-03 22:11:10 +03:00
! drm_core_check_feature ( dev , DRIVER_LEGACY ) )
2013-08-08 17:41:19 +04:00
return ;
2005-09-25 08:28:13 +04:00
if ( ! dma )
return ;
2005-04-17 02:20:36 +04:00
2005-09-25 08:28:13 +04:00
/* Clear dma buffers */
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < = DRM_MAX_ORDER ; i + + ) {
if ( dma - > bufs [ i ] . seg_count ) {
DRM_DEBUG ( " order %d: buf_count = %d, "
" seg_count = %d \n " ,
i ,
dma - > bufs [ i ] . buf_count ,
dma - > bufs [ i ] . seg_count ) ;
for ( j = 0 ; j < dma - > bufs [ i ] . seg_count ; j + + ) {
if ( dma - > bufs [ i ] . seglist [ j ] ) {
2006-03-19 10:56:12 +03:00
drm_pci_free ( dev , dma - > bufs [ i ] . seglist [ j ] ) ;
2005-04-17 02:20:36 +04:00
}
}
2009-03-24 22:23:04 +03:00
kfree ( dma - > bufs [ i ] . seglist ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-25 08:28:13 +04:00
if ( dma - > bufs [ i ] . buf_count ) {
for ( j = 0 ; j < dma - > bufs [ i ] . buf_count ; j + + ) {
2009-03-24 22:23:04 +03:00
kfree ( dma - > bufs [ i ] . buflist [ j ] . dev_private ) ;
2005-04-17 02:20:36 +04:00
}
2009-03-24 22:23:04 +03:00
kfree ( dma - > bufs [ i ] . buflist ) ;
2005-04-17 02:20:36 +04:00
}
}
2009-03-24 22:23:04 +03:00
kfree ( dma - > buflist ) ;
kfree ( dma - > pagelist ) ;
kfree ( dev - > dma ) ;
2005-04-17 02:20:36 +04:00
dev - > dma = NULL ;
}
/**
* Free a buffer .
*
* \ param dev DRM device .
* \ param buf buffer to free .
2005-09-25 08:28:13 +04:00
*
2005-04-17 02:20:36 +04:00
* Resets the fields of \ p buf .
*/
2014-09-11 09:41:51 +04:00
void drm_legacy_free_buffer ( struct drm_device * dev , struct drm_buf * buf )
2005-04-17 02:20:36 +04:00
{
2005-09-25 08:28:13 +04:00
if ( ! buf )
return ;
2005-04-17 02:20:36 +04:00
2005-09-25 08:28:13 +04:00
buf - > waiting = 0 ;
buf - > pending = 0 ;
2007-08-25 14:23:09 +04:00
buf - > file_priv = NULL ;
2005-09-25 08:28:13 +04:00
buf - > used = 0 ;
2005-04-17 02:20:36 +04:00
}
/**
* Reclaim the buffers .
*
2007-08-25 14:23:09 +04:00
* \ param file_priv DRM file private .
2005-04-17 02:20:36 +04:00
*
2007-08-25 14:23:09 +04:00
* Frees each buffer associated with \ p file_priv not already on the hardware .
2005-04-17 02:20:36 +04:00
*/
2014-09-11 09:41:51 +04:00
void drm_legacy_reclaim_buffers ( struct drm_device * dev ,
struct drm_file * file_priv )
2005-04-17 02:20:36 +04:00
{
2007-07-11 10:32:08 +04:00
struct drm_device_dma * dma = dev - > dma ;
2005-09-25 08:28:13 +04:00
int i ;
2005-04-17 02:20:36 +04:00
2005-09-25 08:28:13 +04:00
if ( ! dma )
return ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < dma - > buf_count ; i + + ) {
2007-08-25 14:23:09 +04:00
if ( dma - > buflist [ i ] - > file_priv = = file_priv ) {
2005-04-17 02:20:36 +04:00
switch ( dma - > buflist [ i ] - > list ) {
case DRM_LIST_NONE :
2014-09-11 09:41:51 +04:00
drm_legacy_free_buffer ( dev , dma - > buflist [ i ] ) ;
2005-04-17 02:20:36 +04:00
break ;
case DRM_LIST_WAIT :
dma - > buflist [ i ] - > list = DRM_LIST_RECLAIM ;
break ;
default :
/* Buffer already on hardware. */
break ;
}
}
}
}