⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmabuf.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
      return IOCTL_OUT (arg, dev_buffsize[dev]);      break;    case SNDCTL_DSP_SUBDIVIDE:      {      	int fact = IOCTL_IN(arg);      	if (fact == 0)      	{      	  fact = dev_subdivision[dev];      	  if (fact == 0) fact = 1;	  return IOCTL_OUT(arg, fact);      	}      	if (dev_subdivision[dev] != 0) /* Too late to change */      	   return RET_ERROR(EINVAL);      	if (fact > MAX_REALTIME_FACTOR) return RET_ERROR(EINVAL);      	if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact !=16)      	   return RET_ERROR(EINVAL);      	dev_subdivision[dev] = fact;      	return IOCTL_OUT(arg, fact);      }      break;    default:      return dsp_devs[dev]->ioctl (dev, cmd, arg, local);    }  return RET_ERROR (EIO);}intDMAbuf_getwrbuffer (int dev, char **buf, int *size){  unsigned long   flags;  int             err = EIO;  if (dma_mode[dev] == DMODE_INPUT)	/* Was input -> Direction change */    {	dma_reset(dev);	dma_mode[dev] = DMODE_NONE;    }  else   if (dev_needs_restart[dev])	/* Restart buffering */    {	dma_sync(dev);	dma_reset(dev);    }    dev_needs_restart[dev] = 0;  if (!bufferalloc_done[dev])    reorganize_buffers (dev);  if (!dma_mode[dev])    {      int             err;      dma_mode[dev] = DMODE_OUTPUT;      if ((err = dsp_devs[dev]->prepare_for_output (dev,				    dev_buffsize[dev], dev_nbufs[dev])) < 0)	return err;    }  DISABLE_INTR (flags);  RESET_WAIT_QUEUE (dev_sleeper[dev], dev_sleep_flag[dev]);  if (dev_qlen[dev] == dev_nbufs[dev])    {      if (!dev_active[dev])	{	  printk ("Soundcard warning: DMA not activated %d/%d\n",		  dev_qlen[dev], dev_nbufs[dev]);	  return RET_ERROR (EIO);	}      /* Wait for free space */      DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);      if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))	{	  printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");	  err = EIO;	  SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);	}      else if (PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))	err = EINTR;    }  RESTORE_INTR (flags);  if (dev_qlen[dev] == dev_nbufs[dev])    return RET_ERROR (err);	/* We have got signal (?) */  *buf = dev_buf[dev][dev_qtail[dev]];  *size = dev_buffsize[dev];  dev_counts[dev][dev_qtail[dev]] = 0;  return dev_qtail[dev];}intDMAbuf_start_output (int dev, int buff_no, int l){  if (buff_no != dev_qtail[dev])    printk ("Soundcard warning: DMA buffers out of sync %d != %d\n", buff_no, dev_qtail[dev]);  dev_qlen[dev]++;  dev_counts[dev][dev_qtail[dev]] = l;  dev_needs_restart[dev] = (l != dev_buffsize[dev]);  dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];  if (!dev_active[dev])    {      dev_active[dev] = 1;      dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], 	dev_counts[dev][dev_qhead[dev]], 0, 	!sound_dma_automode[dev] || !dev_started[dev]);        dev_started[dev] = 1;     }  return 0;}intDMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode){  int             chan = sound_dsp_dmachan[dev];  unsigned long   flags;  /*   * This function is not as portable as it should be.   */  /*   * The count must be one less than the actual size. This is handled by   * set_dma_addr()   */  if (sound_dma_automode[dev])    {				/* Auto restart mode. Transfer the whole				 * buffer */#ifdef linux      DISABLE_INTR (flags);      disable_dma (chan);      clear_dma_ff (chan);      set_dma_mode (chan, dma_mode | DMA_AUTOINIT);      set_dma_addr (chan, snd_raw_buf_phys[dev][0]);      set_dma_count (chan, sound_buffsizes[dev]);      enable_dma (chan);      RESTORE_INTR (flags);#else#ifdef __386BSD__      printk ("sound: Invalid DMA mode for device %d\n", dev);      isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,		    snd_raw_buf_phys[dev][0],		    sound_buffsizes[dev],		    chan);#else#if defined(ISC) || defined(SCO)#ifndef DMAMODE_AUTO      printk ("sound: Invalid DMA mode for device %d\n", dev);#endif      dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)#ifdef DMAMODE_AUTO		 | DMAMODE_AUTO#endif		 ,		 snd_raw_buf_phys[dev][0], count);      dma_enable (chan);#else#  error This routine is not valid for this OS.#endif#endif#endif    }  else    {#ifdef linux      DISABLE_INTR (flags);      disable_dma (chan);      clear_dma_ff (chan);      set_dma_mode (chan, dma_mode);      set_dma_addr (chan, physaddr);      set_dma_count (chan, count);      enable_dma (chan);      RESTORE_INTR (flags);#else#ifdef __386BSD__      isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,		    physaddr,		    count,		    chan);#else#if defined(ISC) || defined(SCO)      dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),		 physaddr, count);      dma_enable (chan);#else#  error This routine is not valid for this OS.#endif /* !ISC */#endif#endif    }  return count;}longDMAbuf_init (long mem_start){  int             i;  /*   * In this version the DMA buffer allocation is done by sound_mem_init()   * which is called by init/main.c   */  for (i = 0; i < MAX_DSP_DEV; i++)    {      dev_qlen[i] = 0;      dev_qhead[i] = 0;      dev_qtail[i] = 0;      dev_active[i] = 0;      dev_busy[i] = 0;      bufferalloc_done[i] = 0;    }  return mem_start;}voidDMAbuf_outputintr (int dev, int underrun_flag){  unsigned long   flags;  dev_qlen[dev]--;  dev_qhead[dev] = (dev_qhead[dev] + 1) % dev_nbufs[dev];  dev_active[dev] = 0;  if (dev_qlen[dev])    {      dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], 	  dev_counts[dev][dev_qhead[dev]], 1, 	  !sound_dma_automode[dev]);      dev_active[dev] = 1;    }  else    if (underrun_flag)    {      dev_underrun[dev]++;      dsp_devs[dev]->halt_xfer (dev);      dev_needs_restart[dev] = 1;    }  DISABLE_INTR (flags);  if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))    {      WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);    }  RESTORE_INTR (flags);}voidDMAbuf_inputintr (int dev){  unsigned long   flags;  if (!dev_busy[dev])    {      dsp_devs[dev]->close (dev);    }  else if (dev_qlen[dev] == (dev_nbufs[dev] - 1))    {      printk("Sound: Recording overrun\n");      dev_underrun[dev]++;      dsp_devs[dev]->halt_xfer (dev);      dev_active[dev] = 0;      dev_needs_restart[dev] = 1;    }  else    {      dev_qlen[dev]++;      dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];      dsp_devs[dev]->start_input (dev, dev_buf_phys[dev][dev_qtail[dev]], 				  dev_buffsize[dev], 1,	  			  !sound_dma_automode[dev]);      dev_active[dev] = 1;    }  DISABLE_INTR (flags);  if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))    {      WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);    }  RESTORE_INTR (flags);}intDMAbuf_open_dma (int dev){  unsigned long   flags;  int             chan = sound_dsp_dmachan[dev];  if (ALLOC_DMA_CHN (chan))    {      printk ("Unable to grab DMA%d for the audio driver\n", chan);      return 0;    }  DISABLE_INTR (flags);#ifdef linux  disable_dma (chan);  clear_dma_ff (chan);#endif  RESTORE_INTR (flags);  return 1;}voidDMAbuf_close_dma (int dev){  int             chan = sound_dsp_dmachan[dev];  DMAbuf_reset_dma (chan);  RELEASE_DMA_CHN (chan);}voidDMAbuf_reset_dma (int chan){}/* * The sound_mem_init() is called by mem_init() immediately after mem_map is * initialized and before free_page_list is created. *  * This routine allocates DMA buffers at the end of available physical memory ( * <16M) and marks pages reserved at mem_map. */#else/* Stub versions if audio services not included	 */intDMAbuf_open (int dev, int mode){  return RET_ERROR (ENXIO);}intDMAbuf_release (int dev, int mode){  return 0;}intDMAbuf_read (int dev, snd_rw_buf * user_buf, int count){  return RET_ERROR (EIO);}intDMAbuf_getwrbuffer (int dev, char **buf, int *size){  return RET_ERROR (EIO);}intDMAbuf_getrdbuffer (int dev, char **buf, int *len){  return RET_ERROR (EIO);}intDMAbuf_rmchars (int dev, int buff_no, int c){  return RET_ERROR (EIO);}intDMAbuf_start_output (int dev, int buff_no, int l){  return RET_ERROR (EIO);}intDMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local){  return RET_ERROR (EIO);}longDMAbuf_init (long mem_start){  return mem_start;}intDMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode){  return RET_ERROR (EIO);}intDMAbuf_open_dma (int chan){  return RET_ERROR (ENXIO);}voidDMAbuf_close_dma (int chan){  return;}voidDMAbuf_reset_dma (int chan){  return;}voidDMAbuf_inputintr (int dev){  return;}voidDMAbuf_outputintr (int dev, int underrun_flag){  return;}#endif#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -