1719f82d3SEliot Blennerhassett /****************************************************************************** 2719f82d3SEliot Blennerhassett 3719f82d3SEliot Blennerhassett AudioScience HPI driver 492fd918cSEliot Blennerhassett Copyright (C) 1997-2012 AudioScience Inc. <support@audioscience.com> 5719f82d3SEliot Blennerhassett 6719f82d3SEliot Blennerhassett This program is free software; you can redistribute it and/or modify 7719f82d3SEliot Blennerhassett it under the terms of version 2 of the GNU General Public License as 8719f82d3SEliot Blennerhassett published by the Free Software Foundation; 9719f82d3SEliot Blennerhassett 10719f82d3SEliot Blennerhassett This program is distributed in the hope that it will be useful, 11719f82d3SEliot Blennerhassett but WITHOUT ANY WARRANTY; without even the implied warranty of 12719f82d3SEliot Blennerhassett MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13719f82d3SEliot Blennerhassett GNU General Public License for more details. 14719f82d3SEliot Blennerhassett 15719f82d3SEliot Blennerhassett You should have received a copy of the GNU General Public License 16719f82d3SEliot Blennerhassett along with this program; if not, write to the Free Software 17719f82d3SEliot Blennerhassett Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18719f82d3SEliot Blennerhassett 19719f82d3SEliot Blennerhassett HPI Operating System function implementation for Linux 20719f82d3SEliot Blennerhassett 21719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 1997-2003 22719f82d3SEliot Blennerhassett ******************************************************************************/ 23719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpios.c" 24719f82d3SEliot Blennerhassett #include "hpi_internal.h" 25719f82d3SEliot Blennerhassett #include "hpidebug.h" 26719f82d3SEliot Blennerhassett #include <linux/delay.h> 27719f82d3SEliot Blennerhassett #include <linux/sched.h> 28719f82d3SEliot Blennerhassett 29719f82d3SEliot Blennerhassett void hpios_delay_micro_seconds(u32 num_micro_sec) 30719f82d3SEliot Blennerhassett { 31719f82d3SEliot Blennerhassett if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) { 32719f82d3SEliot Blennerhassett /* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */ 33719f82d3SEliot Blennerhassett schedule_timeout_uninterruptible(usecs_to_jiffies 34719f82d3SEliot Blennerhassett (num_micro_sec)); 35719f82d3SEliot Blennerhassett } else if (num_micro_sec <= 2000) 36719f82d3SEliot Blennerhassett udelay(num_micro_sec); 37719f82d3SEliot Blennerhassett else 38719f82d3SEliot Blennerhassett mdelay(num_micro_sec / 1000); 39719f82d3SEliot Blennerhassett 40719f82d3SEliot Blennerhassett } 41719f82d3SEliot Blennerhassett 4292fd918cSEliot Blennerhassett /** Allocate an area of locked memory for bus master DMA operations. 43719f82d3SEliot Blennerhassett 4492fd918cSEliot Blennerhassett If allocation fails, return 1, and *pMemArea.size = 0 45719f82d3SEliot Blennerhassett */ 4692fd918cSEliot Blennerhassett u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, 47719f82d3SEliot Blennerhassett struct pci_dev *pdev) 48719f82d3SEliot Blennerhassett { 49719f82d3SEliot Blennerhassett /*?? any benefit in using managed dmam_alloc_coherent? */ 50719f82d3SEliot Blennerhassett p_mem_area->vaddr = 51719f82d3SEliot Blennerhassett dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle, 52*23fdf223SChristoph Hellwig GFP_KERNEL); 53719f82d3SEliot Blennerhassett 54719f82d3SEliot Blennerhassett if (p_mem_area->vaddr) { 55719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n", 56719f82d3SEliot Blennerhassett size, (unsigned int)p_mem_area->dma_handle, 57719f82d3SEliot Blennerhassett p_mem_area->vaddr); 58719f82d3SEliot Blennerhassett p_mem_area->pdev = &pdev->dev; 59719f82d3SEliot Blennerhassett p_mem_area->size = size; 60719f82d3SEliot Blennerhassett return 0; 61719f82d3SEliot Blennerhassett } else { 62719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING, 63719f82d3SEliot Blennerhassett "failed to allocate %d bytes locked memory\n", size); 64719f82d3SEliot Blennerhassett p_mem_area->size = 0; 6592fd918cSEliot Blennerhassett return 1; 66719f82d3SEliot Blennerhassett } 67719f82d3SEliot Blennerhassett } 68719f82d3SEliot Blennerhassett 69719f82d3SEliot Blennerhassett u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area) 70719f82d3SEliot Blennerhassett { 71719f82d3SEliot Blennerhassett if (p_mem_area->size) { 72719f82d3SEliot Blennerhassett dma_free_coherent(p_mem_area->pdev, p_mem_area->size, 73719f82d3SEliot Blennerhassett p_mem_area->vaddr, p_mem_area->dma_handle); 74719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n", 75719f82d3SEliot Blennerhassett (unsigned long)p_mem_area->size, 76719f82d3SEliot Blennerhassett (unsigned int)p_mem_area->dma_handle, 77719f82d3SEliot Blennerhassett p_mem_area->vaddr); 78719f82d3SEliot Blennerhassett p_mem_area->size = 0; 79719f82d3SEliot Blennerhassett return 0; 80719f82d3SEliot Blennerhassett } else { 81719f82d3SEliot Blennerhassett return 1; 82719f82d3SEliot Blennerhassett } 83719f82d3SEliot Blennerhassett } 84