You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
Manual fixups for some clashes due to re-indenting.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file ati_pcigart.h
|
||||
* \file ati_pcigart.c
|
||||
* ATI PCI GART support
|
||||
*
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
@@ -52,85 +52,91 @@
|
||||
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
|
||||
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
|
||||
|
||||
static unsigned long drm_ati_alloc_pcigart_table( void )
|
||||
static unsigned long drm_ati_alloc_pcigart_table(void)
|
||||
{
|
||||
unsigned long address;
|
||||
struct page *page;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
|
||||
if ( address == 0UL ) {
|
||||
address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
|
||||
if (address == 0UL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
page = virt_to_page( address );
|
||||
page = virt_to_page(address);
|
||||
|
||||
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
|
||||
get_page(page);
|
||||
SetPageReserved( page );
|
||||
SetPageReserved(page);
|
||||
}
|
||||
|
||||
DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
|
||||
DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
|
||||
return address;
|
||||
}
|
||||
|
||||
static void drm_ati_free_pcigart_table( unsigned long address )
|
||||
static void drm_ati_free_pcigart_table(unsigned long address)
|
||||
{
|
||||
struct page *page;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
page = virt_to_page( address );
|
||||
page = virt_to_page(address);
|
||||
|
||||
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
|
||||
__put_page(page);
|
||||
ClearPageReserved( page );
|
||||
ClearPageReserved(page);
|
||||
}
|
||||
|
||||
free_pages( address, ATI_PCIGART_TABLE_ORDER );
|
||||
free_pages(address, ATI_PCIGART_TABLE_ORDER);
|
||||
}
|
||||
|
||||
int drm_ati_pcigart_cleanup( drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr)
|
||||
int drm_ati_pcigart_cleanup(drm_device_t * dev,
|
||||
drm_ati_pcigart_info * gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
|
||||
/* we need to support large memory configurations */
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( bus_addr ) {
|
||||
pci_unmap_single(dev->pdev, bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (gart_info->bus_addr) {
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
pci_unmap_single(dev->pdev, gart_info->bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
if ( !entry->busaddr[i] ) break;
|
||||
for (i = 0; i < pages; i++) {
|
||||
if (!entry->busaddr[i])
|
||||
break;
|
||||
pci_unmap_single(dev->pdev, entry->busaddr[i],
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
|
||||
gart_info->bus_addr = 0;
|
||||
}
|
||||
|
||||
if ( addr ) {
|
||||
drm_ati_free_pcigart_table( addr );
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
|
||||
&& gart_info->addr) {
|
||||
drm_ati_free_pcigart_table(gart_info->addr);
|
||||
gart_info->addr = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
|
||||
|
||||
int drm_ati_pcigart_init( drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr)
|
||||
int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long address = 0;
|
||||
@@ -138,48 +144,57 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
||||
u32 *pci_gart, page_base, bus_address = 0;
|
||||
int i, j, ret = 0;
|
||||
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
address = drm_ati_alloc_pcigart_table();
|
||||
if ( !address ) {
|
||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||
goto done;
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
|
||||
|
||||
address = drm_ati_alloc_pcigart_table();
|
||||
if (!address) {
|
||||
DRM_ERROR("cannot allocate PCI GART page!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!dev->pdev) {
|
||||
DRM_ERROR("PCI device unknown!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
bus_address = pci_map_single(dev->pdev, (void *)address,
|
||||
ATI_PCIGART_TABLE_PAGES *
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
if (bus_address == 0) {
|
||||
DRM_ERROR("unable to map PCIGART pages!\n");
|
||||
drm_ati_free_pcigart_table(address);
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
address = gart_info->addr;
|
||||
bus_address = gart_info->bus_addr;
|
||||
DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
|
||||
bus_address, address);
|
||||
}
|
||||
|
||||
if ( !dev->pdev ) {
|
||||
DRM_ERROR( "PCI device unknown!\n" );
|
||||
goto done;
|
||||
}
|
||||
pci_gart = (u32 *) address;
|
||||
|
||||
bus_address = pci_map_single(dev->pdev, (void *)address,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (bus_address == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
drm_ati_free_pcigart_table( address );
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
pci_gart = (u32 *)address;
|
||||
memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
for (i = 0; i < pages; i++) {
|
||||
/* we need to support large memory configurations */
|
||||
entry->busaddr[i] = pci_map_single(dev->pdev,
|
||||
page_address( entry->pagelist[i] ),
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
page_address(entry->
|
||||
pagelist[i]),
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
if (entry->busaddr[i] == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
drm_ati_pcigart_cleanup( dev, address, bus_address );
|
||||
DRM_ERROR("unable to map PCIGART pages!\n");
|
||||
drm_ati_pcigart_cleanup(dev, gart_info);
|
||||
address = 0;
|
||||
bus_address = 0;
|
||||
goto done;
|
||||
@@ -187,7 +202,11 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
||||
page_base = (u32) entry->busaddr[i];
|
||||
|
||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||
*pci_gart++ = cpu_to_le32( page_base );
|
||||
if (gart_info->is_pcie)
|
||||
*pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc;
|
||||
else
|
||||
*pci_gart = cpu_to_le32(page_base);
|
||||
*pci_gart++;
|
||||
page_base += ATI_PCIGART_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
@@ -200,9 +219,10 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
||||
mb();
|
||||
#endif
|
||||
|
||||
done:
|
||||
*addr = address;
|
||||
*bus_addr = bus_address;
|
||||
done:
|
||||
gart_info->addr = address;
|
||||
gart_info->bus_addr = bus_address;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_init);
|
||||
|
||||
+125
-168
File diff suppressed because it is too large
Load Diff
+435
-429
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file drm_agpsupport.h
|
||||
* \file drm_agpsupport.h
|
||||
* DRM support for AGP/GART backend
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
@@ -48,30 +48,31 @@
|
||||
* Verifies the AGP device has been initialized and acquired and fills in the
|
||||
* drm_agp_info structure with the information in drm_agp_head::agp_info.
|
||||
*/
|
||||
int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info)
|
||||
int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info)
|
||||
{
|
||||
DRM_AGP_KERN *kern;
|
||||
DRM_AGP_KERN *kern;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
||||
kern = &dev->agp->agp_info;
|
||||
kern = &dev->agp->agp_info;
|
||||
info->agp_version_major = kern->version.major;
|
||||
info->agp_version_minor = kern->version.minor;
|
||||
info->mode = kern->mode;
|
||||
info->aperture_base = kern->aper_base;
|
||||
info->aperture_size = kern->aper_size * 1024 * 1024;
|
||||
info->memory_allowed = kern->max_memory << PAGE_SHIFT;
|
||||
info->memory_used = kern->current_memory << PAGE_SHIFT;
|
||||
info->id_vendor = kern->device->vendor;
|
||||
info->id_device = kern->device->device;
|
||||
info->mode = kern->mode;
|
||||
info->aperture_base = kern->aper_base;
|
||||
info->aperture_size = kern->aper_size * 1024 * 1024;
|
||||
info->memory_allowed = kern->max_memory << PAGE_SHIFT;
|
||||
info->memory_used = kern->current_memory << PAGE_SHIFT;
|
||||
info->id_vendor = kern->device->vendor;
|
||||
info->id_device = kern->device->device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_info);
|
||||
|
||||
int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
@@ -81,7 +82,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
||||
err = drm_agp_info(dev, &info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@@ -91,12 +92,12 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
||||
* Acquire the AGP device.
|
||||
*
|
||||
* \param dev DRM device that is to acquire AGP
|
||||
* \return zero on success or a negative number on failure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Verifies the AGP device hasn't been acquired before and calls
|
||||
* \c agp_backend_acquire.
|
||||
*/
|
||||
int drm_agp_acquire(drm_device_t *dev)
|
||||
int drm_agp_acquire(drm_device_t * dev)
|
||||
{
|
||||
if (!dev->agp)
|
||||
return -ENODEV;
|
||||
@@ -107,6 +108,7 @@ int drm_agp_acquire(drm_device_t *dev)
|
||||
dev->agp->acquired = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_acquire);
|
||||
|
||||
/**
|
||||
@@ -125,8 +127,8 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
|
||||
return drm_agp_acquire( (drm_device_t *) priv->head->dev );
|
||||
|
||||
return drm_agp_acquire((drm_device_t *) priv->head->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +139,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
||||
*
|
||||
* Verifies the AGP device has been acquired and calls \c agp_backend_release.
|
||||
*/
|
||||
int drm_agp_release(drm_device_t *dev)
|
||||
int drm_agp_release(drm_device_t * dev)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
@@ -145,6 +147,7 @@ int drm_agp_release(drm_device_t *dev)
|
||||
dev->agp->acquired = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_release);
|
||||
|
||||
int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
||||
@@ -152,13 +155,13 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
||||
|
||||
return drm_agp_release(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the AGP bus.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device that has previously acquired AGP.
|
||||
* \param mode Requested AGP mode.
|
||||
* \return zero on success or a negative number on failure.
|
||||
@@ -166,27 +169,27 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
||||
* Verifies the AGP device has been acquired but not enabled, and calls
|
||||
* \c agp_enable.
|
||||
*/
|
||||
int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
|
||||
int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
||||
dev->agp->mode = mode.mode;
|
||||
dev->agp->mode = mode.mode;
|
||||
agp_enable(dev->agp->bridge, mode.mode);
|
||||
dev->agp->base = dev->agp->agp_info.aper_base;
|
||||
dev->agp->base = dev->agp->agp_info.aper_base;
|
||||
dev->agp->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_enable);
|
||||
|
||||
int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_mode_t mode;
|
||||
|
||||
|
||||
if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -201,20 +204,20 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_buffer structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Verifies the AGP device is present and has been acquired, allocates the
|
||||
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
|
||||
*/
|
||||
int drm_agp_alloc(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
DRM_AGP_MEM *memory;
|
||||
unsigned long pages;
|
||||
u32 type;
|
||||
drm_agp_mem_t *entry;
|
||||
DRM_AGP_MEM *memory;
|
||||
unsigned long pages;
|
||||
u32 type;
|
||||
drm_agp_buffer_t __user *argp = (void __user *)arg;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
@@ -224,7 +227,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
||||
if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
|
||||
return -ENOMEM;
|
||||
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
|
||||
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
type = (u32) request.type;
|
||||
@@ -234,21 +237,21 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
entry->handle = (unsigned long)memory->key + 1;
|
||||
entry->memory = memory;
|
||||
entry->bound = 0;
|
||||
entry->pages = pages;
|
||||
entry->prev = NULL;
|
||||
entry->next = dev->agp->memory;
|
||||
entry->handle = (unsigned long)memory->key + 1;
|
||||
entry->memory = memory;
|
||||
entry->bound = 0;
|
||||
entry->pages = pages;
|
||||
entry->prev = NULL;
|
||||
entry->next = dev->agp->memory;
|
||||
if (dev->agp->memory)
|
||||
dev->agp->memory->prev = entry;
|
||||
dev->agp->memory = entry;
|
||||
|
||||
request.handle = entry->handle;
|
||||
request.handle = entry->handle;
|
||||
request.physical = memory->physical;
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request))) {
|
||||
dev->agp->memory = entry->next;
|
||||
dev->agp->memory = entry->next;
|
||||
dev->agp->memory->prev = NULL;
|
||||
drm_free_agp(memory, pages);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||
@@ -263,11 +266,11 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
||||
* \param dev DRM device structure.
|
||||
* \param handle AGP memory handle.
|
||||
* \return pointer to the drm_agp_mem structure associated with \p handle.
|
||||
*
|
||||
*
|
||||
* Walks through drm_agp_head::memory until finding a matching handle.
|
||||
*/
|
||||
static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
|
||||
unsigned long handle)
|
||||
static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
|
||||
unsigned long handle)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
@@ -291,17 +294,18 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
|
||||
* entry and passes it to the unbind_agp() function.
|
||||
*/
|
||||
int drm_agp_unbind(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
drm_agp_mem_t *entry;
|
||||
int ret;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
@@ -309,7 +313,7 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
|
||||
return -EINVAL;
|
||||
ret = drm_unbind_agp(entry->memory);
|
||||
if (ret == 0)
|
||||
entry->bound = 0;
|
||||
entry->bound = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -327,18 +331,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
|
||||
* it to bind_agp() function.
|
||||
*/
|
||||
int drm_agp_bind(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
int retcode;
|
||||
int page;
|
||||
drm_agp_mem_t *entry;
|
||||
int retcode;
|
||||
int page;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
@@ -368,16 +373,17 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
|
||||
* and unlinks from the doubly linked list it's inserted in.
|
||||
*/
|
||||
int drm_agp_free(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
@@ -403,9 +409,9 @@ int drm_agp_free(struct inode *inode, struct file *filp,
|
||||
* \return pointer to a drm_agp_head structure.
|
||||
*
|
||||
*/
|
||||
drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
||||
drm_agp_head_t *drm_agp_init(drm_device_t * dev)
|
||||
{
|
||||
drm_agp_head_t *head = NULL;
|
||||
drm_agp_head_t *head = NULL;
|
||||
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
@@ -433,13 +439,14 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
||||
}
|
||||
|
||||
/** Calls agp_allocate_memory() */
|
||||
DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
|
||||
DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge,
|
||||
size_t pages, u32 type)
|
||||
{
|
||||
return agp_allocate_memory(bridge, pages, type);
|
||||
}
|
||||
|
||||
/** Calls agp_free_memory() */
|
||||
int drm_agp_free_memory(DRM_AGP_MEM *handle)
|
||||
int drm_agp_free_memory(DRM_AGP_MEM * handle)
|
||||
{
|
||||
if (!handle)
|
||||
return 0;
|
||||
@@ -448,20 +455,21 @@ int drm_agp_free_memory(DRM_AGP_MEM *handle)
|
||||
}
|
||||
|
||||
/** Calls agp_bind_memory() */
|
||||
int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
|
||||
int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
|
||||
{
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
return agp_bind_memory(handle, start);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_bind_memory);
|
||||
|
||||
/** Calls agp_unbind_memory() */
|
||||
int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
|
||||
int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
|
||||
{
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
return agp_unbind_memory(handle);
|
||||
}
|
||||
|
||||
#endif /* __OS_HAS_AGP */
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
||||
+35
-33
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_auth.h
|
||||
* \file drm_auth.c
|
||||
* IOCTLs for authentication
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -46,7 +46,7 @@
|
||||
*/
|
||||
static int drm_hash_magic(drm_magic_t magic)
|
||||
{
|
||||
return magic & (DRM_HASH_SIZE-1);
|
||||
return magic & (DRM_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,11 +59,11 @@ static int drm_hash_magic(drm_magic_t magic)
|
||||
* the one with matching magic number, while holding the drm_device::struct_sem
|
||||
* lock.
|
||||
*/
|
||||
static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
||||
static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_file_t *retval = NULL;
|
||||
drm_file_t *retval = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash = drm_hash_magic(magic);
|
||||
int hash = drm_hash_magic(magic);
|
||||
|
||||
down(&dev->struct_sem);
|
||||
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
|
||||
@@ -78,7 +78,7 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
||||
|
||||
/**
|
||||
* Adds a magic number.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param priv file private data.
|
||||
* \param magic magic number.
|
||||
@@ -87,28 +87,30 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
||||
* associated the magic number hash key in drm_device::magiclist, while holding
|
||||
* the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
||||
static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
|
||||
drm_magic_t magic)
|
||||
{
|
||||
int hash;
|
||||
int hash;
|
||||
drm_magic_entry_t *entry;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
|
||||
hash = drm_hash_magic(magic);
|
||||
entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
|
||||
if (!entry) return -ENOMEM;
|
||||
hash = drm_hash_magic(magic);
|
||||
entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->magic = magic;
|
||||
entry->priv = priv;
|
||||
entry->next = NULL;
|
||||
entry->priv = priv;
|
||||
entry->next = NULL;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (dev->magiclist[hash].tail) {
|
||||
dev->magiclist[hash].tail->next = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
} else {
|
||||
dev->magiclist[hash].head = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
dev->magiclist[hash].head = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
@@ -117,19 +119,18 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
||||
|
||||
/**
|
||||
* Remove a magic number.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param magic magic number.
|
||||
*
|
||||
* Searches and unlinks the entry in drm_device::magiclist with the magic
|
||||
* number hash key, while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
||||
static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_magic_entry_t *prev = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash;
|
||||
|
||||
int hash;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
hash = drm_hash_magic(magic);
|
||||
@@ -171,21 +172,22 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
||||
* filp.
|
||||
*/
|
||||
int drm_getmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
static drm_magic_t sequence = 0;
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
|
||||
/* Find unique magic */
|
||||
/* Find unique magic */
|
||||
if (priv->magic) {
|
||||
auth.magic = priv->magic;
|
||||
} else {
|
||||
do {
|
||||
spin_lock(&lock);
|
||||
if (!sequence) ++sequence; /* reserve 0 */
|
||||
if (!sequence)
|
||||
++sequence; /* reserve 0 */
|
||||
auth.magic = sequence++;
|
||||
spin_unlock(&lock);
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
@@ -194,7 +196,7 @@ int drm_getmagic(struct inode *inode, struct file *filp,
|
||||
}
|
||||
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
|
||||
if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -211,14 +213,14 @@ int drm_getmagic(struct inode *inode, struct file *filp,
|
||||
* Checks if \p filp is associated with the magic number passed in \arg.
|
||||
*/
|
||||
int drm_authmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
|
||||
if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
|
||||
if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if ((file = drm_find_file(dev, auth.magic))) {
|
||||
|
||||
+445
-446
File diff suppressed because it is too large
Load Diff
+155
-153
File diff suppressed because it is too large
Load Diff
+44
-43
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_dma.h
|
||||
* \file drm_dma.c
|
||||
* DMA IOCTL and function support
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -37,23 +37,23 @@
|
||||
|
||||
/**
|
||||
* Initialize the DMA data.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \return zero on success or a negative value on failure.
|
||||
*
|
||||
* Allocate and initialize a drm_device_dma structure.
|
||||
*/
|
||||
int drm_dma_setup( drm_device_t *dev )
|
||||
int drm_dma_setup(drm_device_t * dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
|
||||
if ( !dev->dma )
|
||||
dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
|
||||
if (!dev->dma)
|
||||
return -ENOMEM;
|
||||
|
||||
memset( dev->dma, 0, sizeof(*dev->dma) );
|
||||
memset(dev->dma, 0, sizeof(*dev->dma));
|
||||
|
||||
for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++)
|
||||
memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
|
||||
|
||||
return 0;
|
||||
@@ -67,14 +67,15 @@ int drm_dma_setup( drm_device_t *dev )
|
||||
* Free all pages associated with DMA buffers, the buffers and pages lists, and
|
||||
* finally the the drm_device::dma structure itself.
|
||||
*/
|
||||
void drm_dma_takedown(drm_device_t *dev)
|
||||
void drm_dma_takedown(drm_device_t * dev)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i, j;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i, j;
|
||||
|
||||
if (!dma) return;
|
||||
if (!dma)
|
||||
return;
|
||||
|
||||
/* Clear dma buffers */
|
||||
/* Clear dma buffers */
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++) {
|
||||
if (dma->bufs[i].seg_count) {
|
||||
DRM_DEBUG("order %d: buf_count = %d,"
|
||||
@@ -85,64 +86,63 @@ void drm_dma_takedown(drm_device_t *dev)
|
||||
for (j = 0; j < dma->bufs[i].seg_count; j++) {
|
||||
if (dma->bufs[i].seglist[j]) {
|
||||
drm_free_pages(dma->bufs[i].seglist[j],
|
||||
dma->bufs[i].page_order,
|
||||
DRM_MEM_DMA);
|
||||
dma->bufs[i].page_order,
|
||||
DRM_MEM_DMA);
|
||||
}
|
||||
}
|
||||
drm_free(dma->bufs[i].seglist,
|
||||
dma->bufs[i].seg_count
|
||||
* sizeof(*dma->bufs[0].seglist),
|
||||
DRM_MEM_SEGS);
|
||||
dma->bufs[i].seg_count
|
||||
* sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS);
|
||||
}
|
||||
if (dma->bufs[i].buf_count) {
|
||||
for (j = 0; j < dma->bufs[i].buf_count; j++) {
|
||||
if (dma->bufs[i].buf_count) {
|
||||
for (j = 0; j < dma->bufs[i].buf_count; j++) {
|
||||
if (dma->bufs[i].buflist[j].dev_private) {
|
||||
drm_free(dma->bufs[i].buflist[j].dev_private,
|
||||
dma->bufs[i].buflist[j].dev_priv_size,
|
||||
DRM_MEM_BUFS);
|
||||
drm_free(dma->bufs[i].buflist[j].
|
||||
dev_private,
|
||||
dma->bufs[i].buflist[j].
|
||||
dev_priv_size, DRM_MEM_BUFS);
|
||||
}
|
||||
}
|
||||
drm_free(dma->bufs[i].buflist,
|
||||
dma->bufs[i].buf_count *
|
||||
sizeof(*dma->bufs[0].buflist),
|
||||
DRM_MEM_BUFS);
|
||||
drm_free(dma->bufs[i].buflist,
|
||||
dma->bufs[i].buf_count *
|
||||
sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS);
|
||||
}
|
||||
}
|
||||
|
||||
if (dma->buflist) {
|
||||
drm_free(dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS);
|
||||
}
|
||||
|
||||
if (dma->pagelist) {
|
||||
drm_free(dma->pagelist,
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
}
|
||||
drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
|
||||
dev->dma = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free a buffer.
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param buf buffer to free.
|
||||
*
|
||||
*
|
||||
* Resets the fields of \p buf.
|
||||
*/
|
||||
void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
|
||||
void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
|
||||
{
|
||||
if (!buf) return;
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->used = 0;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->used = 0;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
|
||||
&& waitqueue_active(&buf->dma_wait)) {
|
||||
wake_up_interruptible(&buf->dma_wait);
|
||||
}
|
||||
}
|
||||
@@ -154,12 +154,13 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
|
||||
*
|
||||
* Frees each buffer associated with \p filp not already on the hardware.
|
||||
*/
|
||||
void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
|
||||
void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!dma) return;
|
||||
if (!dma)
|
||||
return;
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (dma->buflist[i]->filp == filp) {
|
||||
switch (dma->buflist[i]->list) {
|
||||
@@ -176,5 +177,5 @@ void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_core_reclaim_buffers);
|
||||
|
||||
EXPORT_SYMBOL(drm_core_reclaim_buffers);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_drawable.h
|
||||
* \file drm_drawable.c
|
||||
* IOCTLs for drawables
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -37,20 +37,20 @@
|
||||
|
||||
/** No-op. */
|
||||
int drm_adddraw(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_draw_t draw;
|
||||
|
||||
draw.handle = 0; /* NOOP */
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
|
||||
if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** No-op. */
|
||||
int drm_rmdraw(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return 0; /* NOOP */
|
||||
}
|
||||
|
||||
+173
-170
File diff suppressed because it is too large
Load Diff
+152
-144
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_init.h
|
||||
* \file drm_init.c
|
||||
* Setup/Cleanup for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -43,10 +43,11 @@
|
||||
int drm_cpu_valid(void)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
|
||||
if (boot_cpu_data.x86 == 3)
|
||||
return 0; /* No cmpxchg on a 386 */
|
||||
#endif
|
||||
#if defined(__sparc__) && !defined(__sparc_v9__)
|
||||
return 0; /* No cmpxchg before v9 sparc. */
|
||||
return 0; /* No cmpxchg before v9 sparc. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
+112
-111
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_ioctl.h
|
||||
* \file drm_ioctl.c
|
||||
* IOCTL processing for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/**
|
||||
* Get the bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
@@ -50,12 +50,12 @@
|
||||
* Copies the bus id from drm_device::unique into user space.
|
||||
*/
|
||||
int drm_getunique(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t __user *argp = (void __user *)arg;
|
||||
drm_unique_t u;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t __user *argp = (void __user *)arg;
|
||||
drm_unique_t u;
|
||||
|
||||
if (copy_from_user(&u, argp, sizeof(u)))
|
||||
return -EFAULT;
|
||||
@@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
|
||||
|
||||
/**
|
||||
* Set the bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
@@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, struct file *filp,
|
||||
* version 1.1 or greater.
|
||||
*/
|
||||
int drm_setunique(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t u;
|
||||
int domain, bus, slot, func, ret;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t u;
|
||||
int domain, bus, slot, func, ret;
|
||||
|
||||
if (dev->unique_len || dev->unique) return -EBUSY;
|
||||
if (dev->unique_len || dev->unique)
|
||||
return -EBUSY;
|
||||
|
||||
if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
|
||||
if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
|
||||
if (!u.unique_len || u.unique_len > 1024)
|
||||
return -EINVAL;
|
||||
|
||||
dev->unique_len = u.unique_len;
|
||||
dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
|
||||
if(!dev->unique) return -ENOMEM;
|
||||
dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
|
||||
if (!dev->unique)
|
||||
return -ENOMEM;
|
||||
if (copy_from_user(dev->unique, u.unique, dev->unique_len))
|
||||
return -EFAULT;
|
||||
|
||||
dev->unique[dev->unique_len] = '\0';
|
||||
|
||||
dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
|
||||
DRM_MEM_DRIVER);
|
||||
dev->devname =
|
||||
drm_alloc(strlen(dev->driver->pci_driver.name) +
|
||||
strlen(dev->unique) + 2, DRM_MEM_DRIVER);
|
||||
if (!dev->devname)
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
dev->unique);
|
||||
|
||||
/* Return error if the busid submitted doesn't match the device's actual
|
||||
* busid.
|
||||
@@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, struct file *filp,
|
||||
return DRM_ERR(EINVAL);
|
||||
domain = bus >> 8;
|
||||
bus &= 0xff;
|
||||
|
||||
|
||||
if ((domain != dev->pci_domain) ||
|
||||
(bus != dev->pci_bus) ||
|
||||
(slot != dev->pci_slot) ||
|
||||
(func != dev->pci_func))
|
||||
(slot != dev->pci_slot) || (func != dev->pci_func))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_set_busid(drm_device_t *dev)
|
||||
static int drm_set_busid(drm_device_t * dev)
|
||||
{
|
||||
if (dev->unique != NULL)
|
||||
return EBUSY;
|
||||
@@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev)
|
||||
return ENOMEM;
|
||||
|
||||
snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
|
||||
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
|
||||
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
|
||||
|
||||
dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
|
||||
DRM_MEM_DRIVER);
|
||||
dev->devname =
|
||||
drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
|
||||
2, DRM_MEM_DRIVER);
|
||||
if (dev->devname == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
dev->unique);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a mapping information.
|
||||
*
|
||||
@@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev)
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_map structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Searches for the mapping with the specified offset and copies its information
|
||||
* into userspace
|
||||
*/
|
||||
int drm_getmap( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getmap(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t __user *argp = (void __user *)arg;
|
||||
drm_map_t map;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t __user *argp = (void __user *)arg;
|
||||
drm_map_t map;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct list_head *list;
|
||||
int idx;
|
||||
int i;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&map, argp, sizeof(map)))
|
||||
return -EFAULT;
|
||||
@@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, struct file *filp,
|
||||
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
if(i == idx) {
|
||||
if (i == idx) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(!r_list || !r_list->map) {
|
||||
if (!r_list || !r_list->map) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map.offset = r_list->map->offset;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = (void *)(unsigned long) r_list->user_token;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = (void *)(unsigned long)r_list->user_token;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
|
||||
if (copy_to_user(argp, &map, sizeof(map)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, struct file *filp,
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_client structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Searches for the client with the specified index and copies its information
|
||||
* into userspace
|
||||
*/
|
||||
int drm_getclient( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getclient(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_client_t __user *argp = (void __user *)arg;
|
||||
drm_client_t client;
|
||||
drm_file_t *pt;
|
||||
int idx;
|
||||
int i;
|
||||
drm_file_t *pt;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&client, argp, sizeof(client)))
|
||||
return -EFAULT;
|
||||
idx = client.idx;
|
||||
down(&dev->struct_sem);
|
||||
for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
|
||||
;
|
||||
for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
|
||||
|
||||
if (!pt) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
client.auth = pt->authenticated;
|
||||
client.pid = pt->pid;
|
||||
client.uid = pt->uid;
|
||||
client.auth = pt->authenticated;
|
||||
client.pid = pt->pid;
|
||||
client.uid = pt->uid;
|
||||
client.magic = pt->magic;
|
||||
client.iocs = pt->ioctl_count;
|
||||
client.iocs = pt->ioctl_count;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
|
||||
if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics information.
|
||||
*
|
||||
/**
|
||||
* Get statistics information.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_stats structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_getstats( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getstats(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_stats_t stats;
|
||||
int i;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_stats_t stats;
|
||||
int i;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
|
||||
|
||||
down(&dev->struct_sem);
|
||||
|
||||
for (i = 0; i < dev->counters; i++) {
|
||||
if (dev->types[i] == _DRM_STAT_LOCK)
|
||||
stats.data[i].value
|
||||
= (dev->lock.hw_lock
|
||||
? dev->lock.hw_lock->lock : 0);
|
||||
else
|
||||
= (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
|
||||
else
|
||||
stats.data[i].value = atomic_read(&dev->counts[i]);
|
||||
stats.data[i].type = dev->types[i];
|
||||
stats.data[i].type = dev->types[i];
|
||||
}
|
||||
|
||||
|
||||
stats.count = dev->counters;
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
|
||||
if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
|
||||
|
||||
if (sv.drm_dd_major != -1) {
|
||||
if (sv.drm_dd_major != version.version_major ||
|
||||
sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
|
||||
sv.drm_dd_minor < 0
|
||||
|| sv.drm_dd_minor > version.version_minor)
|
||||
return EINVAL;
|
||||
|
||||
if (dev->driver->set_version)
|
||||
@@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
|
||||
|
||||
/** No-op ioctl. */
|
||||
int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
return 0;
|
||||
|
||||
+86
-83
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_irq.h
|
||||
* \file drm_irq.c
|
||||
* IRQ support
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -39,19 +39,19 @@
|
||||
|
||||
/**
|
||||
* Get interrupt from bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_irq_busid structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Finds the PCI device with the specified bus id and gets its IRQ number.
|
||||
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
|
||||
* to that of the device that this DRM instance attached to.
|
||||
*/
|
||||
int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
@@ -66,14 +66,12 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
||||
|
||||
if ((p.busnum >> 8) != dev->pci_domain ||
|
||||
(p.busnum & 0xff) != dev->pci_bus ||
|
||||
p.devnum != dev->pci_slot ||
|
||||
p.funcnum != dev->pci_func)
|
||||
p.devnum != dev->pci_slot || p.funcnum != dev->pci_func)
|
||||
return -EINVAL;
|
||||
|
||||
p.irq = dev->irq;
|
||||
|
||||
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
|
||||
p.busnum, p.devnum, p.funcnum, p.irq);
|
||||
DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
|
||||
if (copy_to_user(argp, &p, sizeof(p)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@@ -89,61 +87,61 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
||||
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
|
||||
* before and after the installation.
|
||||
*/
|
||||
static int drm_irq_install( drm_device_t *dev )
|
||||
static int drm_irq_install(drm_device_t * dev)
|
||||
{
|
||||
int ret;
|
||||
unsigned long sh_flags=0;
|
||||
unsigned long sh_flags = 0;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return -EINVAL;
|
||||
|
||||
if ( dev->irq == 0 )
|
||||
if (dev->irq == 0)
|
||||
return -EINVAL;
|
||||
|
||||
down( &dev->struct_sem );
|
||||
down(&dev->struct_sem);
|
||||
|
||||
/* Driver must have been initialized */
|
||||
if ( !dev->dev_private ) {
|
||||
up( &dev->struct_sem );
|
||||
if (!dev->dev_private) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( dev->irq_enabled ) {
|
||||
up( &dev->struct_sem );
|
||||
if (dev->irq_enabled) {
|
||||
up(&dev->struct_sem);
|
||||
return -EBUSY;
|
||||
}
|
||||
dev->irq_enabled = 1;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
|
||||
DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
|
||||
init_waitqueue_head(&dev->vbl_queue);
|
||||
|
||||
spin_lock_init( &dev->vbl_lock );
|
||||
|
||||
INIT_LIST_HEAD( &dev->vbl_sigs.head );
|
||||
|
||||
|
||||
spin_lock_init(&dev->vbl_lock);
|
||||
|
||||
INIT_LIST_HEAD(&dev->vbl_sigs.head);
|
||||
|
||||
dev->vbl_pending = 0;
|
||||
}
|
||||
|
||||
/* Before installing handler */
|
||||
/* Before installing handler */
|
||||
dev->driver->irq_preinstall(dev);
|
||||
|
||||
/* Install handler */
|
||||
/* Install handler */
|
||||
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
|
||||
sh_flags = SA_SHIRQ;
|
||||
|
||||
ret = request_irq( dev->irq, dev->driver->irq_handler,
|
||||
sh_flags, dev->devname, dev );
|
||||
if ( ret < 0 ) {
|
||||
down( &dev->struct_sem );
|
||||
|
||||
ret = request_irq(dev->irq, dev->driver->irq_handler,
|
||||
sh_flags, dev->devname, dev);
|
||||
if (ret < 0) {
|
||||
down(&dev->struct_sem);
|
||||
dev->irq_enabled = 0;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* After installing handler */
|
||||
/* After installing handler */
|
||||
dev->driver->irq_postinstall(dev);
|
||||
|
||||
return 0;
|
||||
@@ -156,29 +154,30 @@ static int drm_irq_install( drm_device_t *dev )
|
||||
*
|
||||
* Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
|
||||
*/
|
||||
int drm_irq_uninstall( drm_device_t *dev )
|
||||
int drm_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
int irq_enabled;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return -EINVAL;
|
||||
|
||||
down( &dev->struct_sem );
|
||||
down(&dev->struct_sem);
|
||||
irq_enabled = dev->irq_enabled;
|
||||
dev->irq_enabled = 0;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if ( !irq_enabled )
|
||||
if (!irq_enabled)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
|
||||
DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
|
||||
|
||||
dev->driver->irq_uninstall(dev);
|
||||
|
||||
free_irq( dev->irq, dev );
|
||||
free_irq(dev->irq, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_irq_uninstall);
|
||||
|
||||
/**
|
||||
@@ -192,30 +191,30 @@ EXPORT_SYMBOL(drm_irq_uninstall);
|
||||
*
|
||||
* Calls irq_install() or irq_uninstall() according to \p arg.
|
||||
*/
|
||||
int drm_control( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_control(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_control_t ctl;
|
||||
|
||||
|
||||
/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
|
||||
|
||||
if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
|
||||
if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl)))
|
||||
return -EFAULT;
|
||||
|
||||
switch ( ctl.func ) {
|
||||
switch (ctl.func) {
|
||||
case DRM_INST_HANDLER:
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return 0;
|
||||
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
|
||||
ctl.irq != dev->irq)
|
||||
return -EINVAL;
|
||||
return drm_irq_install( dev );
|
||||
return drm_irq_install(dev);
|
||||
case DRM_UNINST_HANDLER:
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return 0;
|
||||
return drm_irq_uninstall( dev );
|
||||
return drm_irq_uninstall(dev);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -230,7 +229,7 @@ int drm_control( struct inode *inode, struct file *filp,
|
||||
* \param data user argument, pointing to a drm_wait_vblank structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Verifies the IRQ is installed.
|
||||
* Verifies the IRQ is installed.
|
||||
*
|
||||
* If a signal is requested checks if this task has already scheduled the same signal
|
||||
* for the same vblank sequence number - nothing to be done in
|
||||
@@ -240,7 +239,7 @@ int drm_control( struct inode *inode, struct file *filp,
|
||||
*
|
||||
* If a signal is not requested, then calls vblank_wait().
|
||||
*/
|
||||
int drm_wait_vblank( DRM_IOCTL_ARGS )
|
||||
int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
@@ -256,11 +255,11 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
|
||||
if (!dev->irq)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
|
||||
DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait));
|
||||
|
||||
switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
|
||||
switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
|
||||
case _DRM_VBLANK_RELATIVE:
|
||||
vblwait.request.sequence += atomic_read( &dev->vbl_received );
|
||||
vblwait.request.sequence += atomic_read(&dev->vbl_received);
|
||||
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||
case _DRM_VBLANK_ABSOLUTE:
|
||||
break;
|
||||
@@ -269,64 +268,68 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
|
||||
}
|
||||
|
||||
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
|
||||
|
||||
if ( flags & _DRM_VBLANK_SIGNAL ) {
|
||||
|
||||
if (flags & _DRM_VBLANK_SIGNAL) {
|
||||
unsigned long irqflags;
|
||||
drm_vbl_sig_t *vbl_sig;
|
||||
|
||||
vblwait.reply.sequence = atomic_read( &dev->vbl_received );
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, irqflags );
|
||||
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
|
||||
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
|
||||
/* Check if this task has already scheduled the same signal
|
||||
* for the same vblank sequence number; nothing to be done in
|
||||
* that case
|
||||
*/
|
||||
list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
|
||||
list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) {
|
||||
if (vbl_sig->sequence == vblwait.request.sequence
|
||||
&& vbl_sig->info.si_signo == vblwait.request.signal
|
||||
&& vbl_sig->task == current)
|
||||
{
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
&& vbl_sig->task == current) {
|
||||
spin_unlock_irqrestore(&dev->vbl_lock,
|
||||
irqflags);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dev->vbl_pending >= 100 ) {
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
if (dev->vbl_pending >= 100) {
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dev->vbl_pending++;
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
|
||||
if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
|
||||
if (!
|
||||
(vbl_sig =
|
||||
drm_alloc(sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER))) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
|
||||
memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
|
||||
|
||||
vbl_sig->sequence = vblwait.request.sequence;
|
||||
vbl_sig->info.si_signo = vblwait.request.signal;
|
||||
vbl_sig->task = current;
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, irqflags );
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
|
||||
list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
|
||||
list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head);
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
} else {
|
||||
if (dev->driver->vblank_wait)
|
||||
ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
|
||||
ret =
|
||||
dev->driver->vblank_wait(dev,
|
||||
&vblwait.request.sequence);
|
||||
|
||||
do_gettimeofday( &now );
|
||||
do_gettimeofday(&now);
|
||||
vblwait.reply.tval_sec = now.tv_sec;
|
||||
vblwait.reply.tval_usec = now.tv_usec;
|
||||
}
|
||||
|
||||
done:
|
||||
DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
|
||||
done:
|
||||
DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -340,31 +343,31 @@ done:
|
||||
*
|
||||
* If a signal is not requested, then calls vblank_wait().
|
||||
*/
|
||||
void drm_vbl_send_signals( drm_device_t *dev )
|
||||
void drm_vbl_send_signals(drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list, *tmp;
|
||||
drm_vbl_sig_t *vbl_sig;
|
||||
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
|
||||
unsigned int vbl_seq = atomic_read(&dev->vbl_received);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, flags );
|
||||
spin_lock_irqsave(&dev->vbl_lock, flags);
|
||||
|
||||
list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
|
||||
vbl_sig = list_entry( list, drm_vbl_sig_t, head );
|
||||
if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
|
||||
list_for_each_safe(list, tmp, &dev->vbl_sigs.head) {
|
||||
vbl_sig = list_entry(list, drm_vbl_sig_t, head);
|
||||
if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
|
||||
vbl_sig->info.si_code = vbl_seq;
|
||||
send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
|
||||
send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info,
|
||||
vbl_sig->task);
|
||||
|
||||
list_del( list );
|
||||
list_del(list);
|
||||
|
||||
drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
|
||||
drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER);
|
||||
|
||||
dev->vbl_pending--;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, flags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, flags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_vbl_send_signals);
|
||||
|
||||
|
||||
|
||||
+90
-91
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file drm_lock.h
|
||||
* \file drm_lock.c
|
||||
* IOCTLs for locking
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
@@ -35,12 +35,12 @@
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
static int drm_lock_transfer(drm_device_t *dev,
|
||||
static int drm_lock_transfer(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock,
|
||||
unsigned int context);
|
||||
static int drm_notifier(void *priv);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Lock ioctl.
|
||||
*
|
||||
* \param inode device inode.
|
||||
@@ -51,91 +51,89 @@ static int drm_notifier(void *priv);
|
||||
*
|
||||
* Add the current task to the lock wait queue, and attempt to take to lock.
|
||||
*/
|
||||
int drm_lock( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_lock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
DECLARE_WAITQUEUE( entry, current );
|
||||
drm_lock_t lock;
|
||||
int ret = 0;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_lock_t lock;
|
||||
int ret = 0;
|
||||
|
||||
++priv->lock_count;
|
||||
|
||||
if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
|
||||
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if ( lock.context == DRM_KERNEL_CONTEXT ) {
|
||||
DRM_ERROR( "Process %d using kernel context %d\n",
|
||||
current->pid, lock.context );
|
||||
return -EINVAL;
|
||||
}
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid,
|
||||
dev->lock.hw_lock->lock, lock.flags );
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid,
|
||||
dev->lock.hw_lock->lock, lock.flags);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
|
||||
if ( lock.context < 0 )
|
||||
if (lock.context < 0)
|
||||
return -EINVAL;
|
||||
|
||||
add_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if ( drm_lock_take( &dev->lock.hw_lock->lock,
|
||||
lock.context ) ) {
|
||||
dev->lock.filp = filp;
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
|
||||
dev->lock.filp = filp;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||
break; /* Got lock */
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
|
||||
/* Contention */
|
||||
schedule();
|
||||
if ( signal_pending( current ) ) {
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
|
||||
sigemptyset( &dev->sigmask );
|
||||
sigaddset( &dev->sigmask, SIGSTOP );
|
||||
sigaddset( &dev->sigmask, SIGTSTP );
|
||||
sigaddset( &dev->sigmask, SIGTTIN );
|
||||
sigaddset( &dev->sigmask, SIGTTOU );
|
||||
sigemptyset(&dev->sigmask);
|
||||
sigaddset(&dev->sigmask, SIGSTOP);
|
||||
sigaddset(&dev->sigmask, SIGTSTP);
|
||||
sigaddset(&dev->sigmask, SIGTTIN);
|
||||
sigaddset(&dev->sigmask, SIGTTOU);
|
||||
dev->sigdata.context = lock.context;
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals( drm_notifier,
|
||||
&dev->sigdata, &dev->sigmask );
|
||||
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
|
||||
|
||||
if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
|
||||
dev->driver->dma_ready(dev);
|
||||
|
||||
if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
|
||||
|
||||
if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
|
||||
return dev->driver->dma_quiescent(dev);
|
||||
|
||||
/* dev->driver->kernel_context_switch isn't used by any of the x86
|
||||
|
||||
/* dev->driver->kernel_context_switch isn't used by any of the x86
|
||||
* drivers but is used by the Sparc driver.
|
||||
*/
|
||||
|
||||
if (dev->driver->kernel_context_switch &&
|
||||
dev->last_context != lock.context) {
|
||||
dev->driver->kernel_context_switch(dev, dev->last_context,
|
||||
lock.context);
|
||||
}
|
||||
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
|
||||
|
||||
return ret;
|
||||
if (dev->driver->kernel_context_switch &&
|
||||
dev->last_context != lock.context) {
|
||||
dev->driver->kernel_context_switch(dev, dev->last_context,
|
||||
lock.context);
|
||||
}
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Unlock ioctl.
|
||||
*
|
||||
* \param inode device inode.
|
||||
@@ -146,23 +144,23 @@ int drm_lock( struct inode *inode, struct file *filp,
|
||||
*
|
||||
* Transfer and free the lock.
|
||||
*/
|
||||
int drm_unlock( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_unlock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_lock_t lock;
|
||||
|
||||
if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
|
||||
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if ( lock.context == DRM_KERNEL_CONTEXT ) {
|
||||
DRM_ERROR( "Process %d using kernel context %d\n",
|
||||
current->pid, lock.context );
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
|
||||
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
|
||||
|
||||
/* kernel_context_switch isn't used by any of the x86 drm
|
||||
* modules but is required by the Sparc driver.
|
||||
@@ -170,12 +168,12 @@ int drm_unlock( struct inode *inode, struct file *filp,
|
||||
if (dev->driver->kernel_context_switch_unlock)
|
||||
dev->driver->kernel_context_switch_unlock(dev, &lock);
|
||||
else {
|
||||
drm_lock_transfer( dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT );
|
||||
|
||||
if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT ) ) {
|
||||
DRM_ERROR( "\n" );
|
||||
drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT);
|
||||
|
||||
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,8 +196,10 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
||||
|
||||
do {
|
||||
old = *lock;
|
||||
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
||||
else new = context | _DRM_LOCK_HELD;
|
||||
if (old & _DRM_LOCK_HELD)
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
else
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
||||
@@ -212,7 +212,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
||||
}
|
||||
}
|
||||
if (new == (context | _DRM_LOCK_HELD)) {
|
||||
/* Have lock */
|
||||
/* Have lock */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -220,8 +220,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
||||
|
||||
/**
|
||||
* This takes a lock forcibly and hands it to context. Should ONLY be used
|
||||
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
|
||||
*
|
||||
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param lock lock pointer.
|
||||
* \param context locking context.
|
||||
@@ -230,7 +230,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
||||
* Resets the lock file pointer.
|
||||
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
|
||||
*/
|
||||
static int drm_lock_transfer(drm_device_t *dev,
|
||||
static int drm_lock_transfer(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock,
|
||||
unsigned int context)
|
||||
{
|
||||
@@ -238,8 +238,8 @@ static int drm_lock_transfer(drm_device_t *dev,
|
||||
|
||||
dev->lock.filp = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
old = *lock;
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
return 1;
|
||||
@@ -247,30 +247,29 @@ static int drm_lock_transfer(drm_device_t *dev,
|
||||
|
||||
/**
|
||||
* Free lock.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param lock lock.
|
||||
* \param context context.
|
||||
*
|
||||
*
|
||||
* Resets the lock file pointer.
|
||||
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
|
||||
* waiting on the lock queue.
|
||||
*/
|
||||
int drm_lock_free(drm_device_t *dev,
|
||||
__volatile__ unsigned int *lock, unsigned int context)
|
||||
int drm_lock_free(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock, unsigned int context)
|
||||
{
|
||||
unsigned int old, new, prev;
|
||||
|
||||
dev->lock.filp = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = 0;
|
||||
old = *lock;
|
||||
new = 0;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
||||
DRM_ERROR("%d freed heavyweight lock held by %d\n",
|
||||
context,
|
||||
_DRM_LOCKING_CONTEXT(old));
|
||||
context, _DRM_LOCKING_CONTEXT(old));
|
||||
return 1;
|
||||
}
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
@@ -290,19 +289,19 @@ int drm_lock_free(drm_device_t *dev,
|
||||
*/
|
||||
static int drm_notifier(void *priv)
|
||||
{
|
||||
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
||||
unsigned int old, new, prev;
|
||||
drm_sigdata_t *s = (drm_sigdata_t *) priv;
|
||||
unsigned int old, new, prev;
|
||||
|
||||
|
||||
/* Allow signal delivery if lock isn't held */
|
||||
/* Allow signal delivery if lock isn't held */
|
||||
if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
|
||||
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
|
||||
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context)
|
||||
return 1;
|
||||
|
||||
/* Otherwise, set flag to force call to
|
||||
drmUnlock */
|
||||
/* Otherwise, set flag to force call to
|
||||
drmUnlock */
|
||||
do {
|
||||
old = s->lock->lock;
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
old = s->lock->lock;
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
prev = cmpxchg(&s->lock->lock, old, new);
|
||||
} while (prev != old);
|
||||
return 0;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* \file drm_memory.h
|
||||
/**
|
||||
* \file drm_memory.c
|
||||
* Memory management wrappers for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
@@ -48,7 +48,7 @@ void drm_mem_init(void)
|
||||
|
||||
/**
|
||||
* Called when "/proc/dri/%dev%/mem" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
@@ -57,10 +57,10 @@ void drm_mem_init(void)
|
||||
* \param data private data.
|
||||
* \return number of written bytes.
|
||||
*
|
||||
* No-op.
|
||||
* No-op.
|
||||
*/
|
||||
int drm_mem_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -70,7 +70,8 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
{
|
||||
void *pt;
|
||||
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL)))
|
||||
return NULL;
|
||||
if (oldpt && oldsize) {
|
||||
memcpy(pt, oldpt, oldsize);
|
||||
kfree(oldpt);
|
||||
@@ -90,21 +91,20 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
unsigned long drm_alloc_pages(int order, int area)
|
||||
{
|
||||
unsigned long address;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
address = __get_free_pages(GFP_KERNEL, order);
|
||||
if (!address)
|
||||
if (!address)
|
||||
return 0;
|
||||
|
||||
/* Zero */
|
||||
/* Zero */
|
||||
memset((void *)address, 0, bytes);
|
||||
|
||||
/* Reserve */
|
||||
/* Reserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
SetPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ unsigned long drm_alloc_pages(int order, int area)
|
||||
|
||||
/**
|
||||
* Free pages.
|
||||
*
|
||||
*
|
||||
* \param address address of the pages to free.
|
||||
* \param order size order.
|
||||
* \param area memory area. (Not used.)
|
||||
@@ -124,49 +124,51 @@ void drm_free_pages(unsigned long address, int order, int area)
|
||||
{
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
if (!address)
|
||||
if (!address)
|
||||
return;
|
||||
|
||||
/* Unreserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
free_pages(address, order);
|
||||
}
|
||||
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
/** Wrapper around agp_allocate_memory() */
|
||||
DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
|
||||
DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
|
||||
{
|
||||
return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_alloc_agp);
|
||||
|
||||
/** Wrapper around agp_free_memory() */
|
||||
int drm_free_agp(DRM_AGP_MEM *handle, int pages)
|
||||
int drm_free_agp(DRM_AGP_MEM * handle, int pages)
|
||||
{
|
||||
return drm_agp_free_memory(handle) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_free_agp);
|
||||
|
||||
/** Wrapper around agp_bind_memory() */
|
||||
int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
|
||||
int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
|
||||
{
|
||||
return drm_agp_bind_memory(handle, start);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_bind_agp);
|
||||
|
||||
/** Wrapper around agp_unbind_memory() */
|
||||
int drm_unbind_agp(DRM_AGP_MEM *handle)
|
||||
int drm_unbind_agp(DRM_AGP_MEM * handle)
|
||||
{
|
||||
return drm_agp_unbind_memory(handle);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_unbind_agp);
|
||||
#endif /* agp */
|
||||
#endif /* debug_memory */
|
||||
#endif /* agp */
|
||||
#endif /* debug_memory */
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* \file drm_memory.h
|
||||
/**
|
||||
* \file drm_memory.h
|
||||
* Memory management wrappers for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/**
|
||||
* Cut down version of drm_memory_debug.h, which used to be called
|
||||
* drm_memory.h.
|
||||
* drm_memory.h.
|
||||
*/
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
@@ -60,8 +60,8 @@
|
||||
/*
|
||||
* Find the drm_map that covers the range [offset, offset+size).
|
||||
*/
|
||||
static inline drm_map_t *
|
||||
drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
@@ -72,16 +72,18 @@ drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
map = r_list->map;
|
||||
if (!map)
|
||||
continue;
|
||||
if (map->offset <= offset && (offset + size) <= (map->offset + map->size))
|
||||
if (map->offset <= offset
|
||||
&& (offset + size) <= (map->offset + map->size))
|
||||
return map;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE;
|
||||
unsigned long *phys_addr_map, i, num_pages =
|
||||
PAGE_ALIGN(size) / PAGE_SIZE;
|
||||
struct drm_agp_mem *agpmem;
|
||||
struct page **page_map;
|
||||
void *addr;
|
||||
@@ -94,7 +96,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
|
||||
for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
|
||||
if (agpmem->bound <= offset
|
||||
&& (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size))
|
||||
&& (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
|
||||
(offset + size))
|
||||
break;
|
||||
if (!agpmem)
|
||||
return NULL;
|
||||
@@ -109,7 +112,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
if (!page_map)
|
||||
return NULL;
|
||||
|
||||
phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
|
||||
phys_addr_map =
|
||||
agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
|
||||
for (i = 0; i < num_pages; ++i)
|
||||
page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
|
||||
addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
|
||||
@@ -118,36 +122,38 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
drm_follow_page (void *vaddr)
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
|
||||
pud_t *pud = pud_offset(pgd, (unsigned long) vaddr);
|
||||
pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr);
|
||||
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
|
||||
pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
|
||||
pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
|
||||
pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
|
||||
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
|
||||
return pte_pfn(*ptep) << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#else /* __OS_HAS_AGP */
|
||||
#else /* __OS_HAS_AGP */
|
||||
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline unsigned long drm_follow_page (void *vaddr)
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *drm_ioremap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
@@ -158,8 +164,8 @@ static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_de
|
||||
return ioremap(offset, size);
|
||||
}
|
||||
|
||||
static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
|
||||
drm_device_t *dev)
|
||||
static inline void *drm_ioremap_nocache(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
@@ -170,7 +176,8 @@ static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size
|
||||
return ioremap_nocache(offset, size);
|
||||
}
|
||||
|
||||
static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
|
||||
static inline void drm_ioremapfree(void *pt, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
/*
|
||||
* This is a bit ugly. It would be much cleaner if the DRM API would use separate
|
||||
@@ -178,12 +185,12 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
|
||||
* a future revision of the interface...
|
||||
*/
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
|
||||
&& ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END))
|
||||
{
|
||||
&& ((unsigned long)pt >= VMALLOC_START
|
||||
&& (unsigned long)pt < VMALLOC_END)) {
|
||||
unsigned long offset;
|
||||
drm_map_t *map;
|
||||
|
||||
offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK);
|
||||
offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
|
||||
map = drm_lookup_map(offset, size, dev);
|
||||
if (map && map->type == _DRM_AGP) {
|
||||
vunmap(pt);
|
||||
@@ -193,5 +200,3 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
|
||||
|
||||
iounmap(pt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+107
-117
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file drm_memory.h
|
||||
* \file drm_memory.h
|
||||
* Memory management wrappers for DRM.
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
@@ -35,75 +35,75 @@
|
||||
#include "drmP.h"
|
||||
|
||||
typedef struct drm_mem_stats {
|
||||
const char *name;
|
||||
int succeed_count;
|
||||
int free_count;
|
||||
int fail_count;
|
||||
unsigned long bytes_allocated;
|
||||
unsigned long bytes_freed;
|
||||
const char *name;
|
||||
int succeed_count;
|
||||
int free_count;
|
||||
int fail_count;
|
||||
unsigned long bytes_allocated;
|
||||
unsigned long bytes_freed;
|
||||
} drm_mem_stats_t;
|
||||
|
||||
static DEFINE_SPINLOCK(DRM(mem_lock));
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||
[DRM_MEM_DMA] = { "dmabufs" },
|
||||
[DRM_MEM_SAREA] = { "sareas" },
|
||||
[DRM_MEM_DRIVER] = { "driver" },
|
||||
[DRM_MEM_MAGIC] = { "magic" },
|
||||
[DRM_MEM_IOCTLS] = { "ioctltab" },
|
||||
[DRM_MEM_MAPS] = { "maplist" },
|
||||
[DRM_MEM_VMAS] = { "vmalist" },
|
||||
[DRM_MEM_BUFS] = { "buflist" },
|
||||
[DRM_MEM_SEGS] = { "seglist" },
|
||||
[DRM_MEM_PAGES] = { "pagelist" },
|
||||
[DRM_MEM_FILES] = { "files" },
|
||||
[DRM_MEM_QUEUES] = { "queues" },
|
||||
[DRM_MEM_CMDS] = { "commands" },
|
||||
[DRM_MEM_MAPPINGS] = { "mappings" },
|
||||
[DRM_MEM_BUFLISTS] = { "buflists" },
|
||||
[DRM_MEM_AGPLISTS] = { "agplist" },
|
||||
[DRM_MEM_SGLISTS] = { "sglist" },
|
||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
[DRM_MEM_CTXLIST] = { "ctxlist" },
|
||||
[DRM_MEM_STUB] = { "stub" },
|
||||
{ NULL, 0, } /* Last entry must be null */
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] =
|
||||
{
|
||||
[DRM_MEM_DMA] = {
|
||||
"dmabufs"},[DRM_MEM_SAREA] = {
|
||||
"sareas"},[DRM_MEM_DRIVER] = {
|
||||
"driver"},[DRM_MEM_MAGIC] = {
|
||||
"magic"},[DRM_MEM_IOCTLS] = {
|
||||
"ioctltab"},[DRM_MEM_MAPS] = {
|
||||
"maplist"},[DRM_MEM_VMAS] = {
|
||||
"vmalist"},[DRM_MEM_BUFS] = {
|
||||
"buflist"},[DRM_MEM_SEGS] = {
|
||||
"seglist"},[DRM_MEM_PAGES] = {
|
||||
"pagelist"},[DRM_MEM_FILES] = {
|
||||
"files"},[DRM_MEM_QUEUES] = {
|
||||
"queues"},[DRM_MEM_CMDS] = {
|
||||
"commands"},[DRM_MEM_MAPPINGS] = {
|
||||
"mappings"},[DRM_MEM_BUFLISTS] = {
|
||||
"buflists"},[DRM_MEM_AGPLISTS] = {
|
||||
"agplist"},[DRM_MEM_SGLISTS] = {
|
||||
"sglist"},[DRM_MEM_TOTALAGP] = {
|
||||
"totalagp"},[DRM_MEM_BOUNDAGP] = {
|
||||
"boundagp"},[DRM_MEM_CTXBITMAP] = {
|
||||
"ctxbitmap"},[DRM_MEM_CTXLIST] = {
|
||||
"ctxlist"},[DRM_MEM_STUB] = {
|
||||
"stub"}, {
|
||||
NULL, 0,} /* Last entry must be null */
|
||||
};
|
||||
|
||||
void DRM(mem_init)(void)
|
||||
{
|
||||
void DRM(mem_init) (void) {
|
||||
drm_mem_stats_t *mem;
|
||||
struct sysinfo si;
|
||||
struct sysinfo si;
|
||||
|
||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
mem->bytes_allocated = 0;
|
||||
mem->bytes_freed = 0;
|
||||
mem->bytes_freed = 0;
|
||||
}
|
||||
|
||||
si_meminfo(&si);
|
||||
DRM(ram_available) = si.totalram;
|
||||
DRM(ram_used) = 0;
|
||||
DRM(ram_used) = 0;
|
||||
}
|
||||
|
||||
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
|
||||
|
||||
static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
static int DRM(_mem_info) (char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data) {
|
||||
drm_mem_stats_t *pt;
|
||||
int len = 0;
|
||||
int len = 0;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
*start = &buf[offset];
|
||||
|
||||
DRM_PROC_PRINT(" total counts "
|
||||
@@ -129,24 +129,23 @@ static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
||||
- (long)pt->bytes_freed);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
int DRM(mem_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
int DRM(mem_info) (char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data) {
|
||||
int ret;
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_mem_info) (buf, start, offset, len, eof, data);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *DRM(alloc)(size_t size, int area)
|
||||
{
|
||||
void *DRM(alloc) (size_t size, int area) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
@@ -167,40 +166,40 @@ void *DRM(alloc)(size_t size, int area)
|
||||
return pt;
|
||||
}
|
||||
|
||||
void *DRM(calloc)(size_t nmemb, size_t size, int area)
|
||||
{
|
||||
void *DRM(calloc) (size_t nmemb, size_t size, int area) {
|
||||
void *addr;
|
||||
|
||||
addr = DRM(alloc)(nmemb * size, area);
|
||||
addr = DRM(alloc) (nmemb * size, area);
|
||||
if (addr != NULL)
|
||||
memset((void *)addr, 0, size * nmemb);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
{
|
||||
void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) {
|
||||
void *pt;
|
||||
|
||||
if (!(pt = DRM(alloc)(size, area))) return NULL;
|
||||
if (!(pt = DRM(alloc) (size, area)))
|
||||
return NULL;
|
||||
if (oldpt && oldsize) {
|
||||
memcpy(pt, oldpt, oldsize);
|
||||
DRM(free)(oldpt, oldsize, area);
|
||||
DRM(free) (oldpt, oldsize, area);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
void DRM(free)(void *pt, size_t size, int area)
|
||||
{
|
||||
void DRM(free) (void *pt, size_t size, int area) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
|
||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else kfree(pt);
|
||||
if (!pt)
|
||||
DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else
|
||||
kfree(pt);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[area].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
|
||||
@@ -208,12 +207,11 @@ void DRM(free)(void *pt, size_t size, int area)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long DRM(alloc_pages)(int order, int area)
|
||||
{
|
||||
unsigned long DRM(alloc_pages) (int order, int area) {
|
||||
unsigned long address;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
if ((DRM(ram_used) >> PAGE_SHIFT)
|
||||
@@ -233,48 +231,44 @@ unsigned long DRM(alloc_pages)(int order, int area)
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
|
||||
/* Zero outside the lock */
|
||||
/* Zero outside the lock */
|
||||
memset((void *)address, 0, bytes);
|
||||
|
||||
/* Reserve */
|
||||
/* Reserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
SetPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void DRM(free_pages)(unsigned long address, int order, int area)
|
||||
{
|
||||
void DRM(free_pages) (unsigned long address, int order, int area) {
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
if (!address) {
|
||||
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
|
||||
} else {
|
||||
/* Unreserve */
|
||||
/* Unreserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
}
|
||||
free_pages(address, order);
|
||||
}
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_freed += bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area,
|
||||
@@ -283,8 +277,8 @@ void DRM(free_pages)(unsigned long address, int order, int area)
|
||||
}
|
||||
}
|
||||
|
||||
void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void *DRM(ioremap) (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
@@ -306,8 +300,8 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
return pt;
|
||||
}
|
||||
|
||||
void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
@@ -329,8 +323,7 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_
|
||||
return pt;
|
||||
}
|
||||
|
||||
void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
|
||||
@@ -342,8 +335,8 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
@@ -354,8 +347,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
|
||||
DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
||||
{
|
||||
DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
|
||||
DRM_AGP_MEM *handle;
|
||||
|
||||
if (!pages) {
|
||||
@@ -363,11 +355,11 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((handle = DRM(agp_allocate_memory)(pages, type))) {
|
||||
if ((handle = DRM(agp_allocate_memory) (pages, type))) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
+= pages << PAGE_SHIFT;
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return handle;
|
||||
}
|
||||
@@ -377,11 +369,10 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
||||
{
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retval = -EINVAL;
|
||||
int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (!handle) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
@@ -389,12 +380,12 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (DRM(agp_free_memory)(handle)) {
|
||||
if (DRM(agp_free_memory) (handle)) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
|
||||
+= pages << PAGE_SHIFT;
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
@@ -406,8 +397,7 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
||||
{
|
||||
int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
|
||||
int retcode = -EINVAL;
|
||||
|
||||
if (!handle) {
|
||||
@@ -416,11 +406,11 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
|
||||
if (!(retcode = DRM(agp_bind_memory) (handle, start))) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
@@ -430,8 +420,7 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int DRM(unbind_agp)(DRM_AGP_MEM *handle)
|
||||
{
|
||||
int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retcode = -EINVAL;
|
||||
@@ -442,12 +431,13 @@ int DRM(unbind_agp)(DRM_AGP_MEM *handle)
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
|
||||
if ((retcode = DRM(agp_unbind_memory) (handle)))
|
||||
return retcode;
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* OS abstraction macros.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/delay.h>
|
||||
|
||||
@@ -47,25 +46,25 @@
|
||||
#else
|
||||
/* define some dummy types for non AGP supporting kernels */
|
||||
struct no_agp_kern {
|
||||
unsigned long aper_base;
|
||||
unsigned long aper_size;
|
||||
unsigned long aper_base;
|
||||
unsigned long aper_size;
|
||||
};
|
||||
#define DRM_AGP_MEM int
|
||||
#define DRM_AGP_KERN struct no_agp_kern
|
||||
#endif
|
||||
|
||||
#if !(__OS_HAS_MTRR)
|
||||
static __inline__ int mtrr_add (unsigned long base, unsigned long size,
|
||||
unsigned int type, char increment)
|
||||
static __inline__ int mtrr_add(unsigned long base, unsigned long size,
|
||||
unsigned int type, char increment)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static __inline__ int mtrr_del (int reg, unsigned long base,
|
||||
unsigned long size)
|
||||
static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
|
||||
#endif
|
||||
@@ -99,7 +98,7 @@ static __inline__ int mtrr_del (int reg, unsigned long base,
|
||||
|
||||
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the pointer to the SAREA.
|
||||
*
|
||||
* Searches the SAREA on the mapping lists and points drm_device::sarea to it.
|
||||
@@ -143,7 +142,5 @@ do { \
|
||||
remove_wait_queue(&(queue), &entry); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
|
||||
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user