• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/arm/mach-bcmring/
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17*   @file   dma.c
18*
19*   @brief  Implements the DMA interface.
20*/
21/****************************************************************************/
22
23/* ---- Include Files ---------------------------------------------------- */
24
25#include <linux/module.h>
26#include <linux/device.h>
27#include <linux/dma-mapping.h>
28#include <linux/interrupt.h>
29#include <linux/irqreturn.h>
30#include <linux/proc_fs.h>
31#include <linux/slab.h>
32
33#include <mach/timer.h>
34
35#include <linux/mm.h>
36#include <linux/pfn.h>
37#include <asm/atomic.h>
38#include <mach/dma.h>
39
40/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
41/* especially since dc4 doesn't use kmalloc'd memory. */
42
43#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
44
45/* ---- Public Variables ------------------------------------------------- */
46
47/* ---- Private Constants and Types -------------------------------------- */
48
49#define MAKE_HANDLE(controllerIdx, channelIdx)    (((controllerIdx) << 4) | (channelIdx))
50
51#define CONTROLLER_FROM_HANDLE(handle)    (((handle) >> 4) & 0x0f)
52#define CHANNEL_FROM_HANDLE(handle)       ((handle) & 0x0f)
53
54#define DMA_MAP_DEBUG   0
55
56#if DMA_MAP_DEBUG
57#   define  DMA_MAP_PRINT(fmt, args...)   printk("%s: " fmt, __func__,  ## args)
58#else
59#   define  DMA_MAP_PRINT(fmt, args...)
60#endif
61
62/* ---- Private Variables ------------------------------------------------ */
63
64static DMA_Global_t gDMA;
65static struct proc_dir_entry *gDmaDir;
66
67static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
68static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
69static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
70static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
71
72#include "dma_device.c"
73
74/* ---- Private Function Prototypes -------------------------------------- */
75
76/* ---- Functions  ------------------------------------------------------- */
77
78/****************************************************************************/
79/**
80*   Displays information for /proc/dma/mem-type
81*/
82/****************************************************************************/
83
84static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
85				  int count, int *eof, void *data)
86{
87	int len = 0;
88
89	len += sprintf(buf + len, "dma_map_mem statistics\n");
90	len +=
91	    sprintf(buf + len, "coherent: %d\n",
92		    atomic_read(&gDmaStatMemTypeCoherent));
93	len +=
94	    sprintf(buf + len, "kmalloc:  %d\n",
95		    atomic_read(&gDmaStatMemTypeKmalloc));
96	len +=
97	    sprintf(buf + len, "vmalloc:  %d\n",
98		    atomic_read(&gDmaStatMemTypeVmalloc));
99	len +=
100	    sprintf(buf + len, "user:     %d\n",
101		    atomic_read(&gDmaStatMemTypeUser));
102
103	return len;
104}
105
106/****************************************************************************/
107/**
108*   Displays information for /proc/dma/channels
109*/
110/****************************************************************************/
111
112static int dma_proc_read_channels(char *buf, char **start, off_t offset,
113				  int count, int *eof, void *data)
114{
115	int controllerIdx;
116	int channelIdx;
117	int limit = count - 200;
118	int len = 0;
119	DMA_Channel_t *channel;
120
121	if (down_interruptible(&gDMA.lock) < 0) {
122		return -ERESTARTSYS;
123	}
124
125	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
126	     controllerIdx++) {
127		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
128		     channelIdx++) {
129			if (len >= limit) {
130				break;
131			}
132
133			channel =
134			    &gDMA.controller[controllerIdx].channel[channelIdx];
135
136			len +=
137			    sprintf(buf + len, "%d:%d ", controllerIdx,
138				    channelIdx);
139
140			if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
141			    0) {
142				len +=
143				    sprintf(buf + len, "Dedicated for %s ",
144					    DMA_gDeviceAttribute[channel->
145								 devType].name);
146			} else {
147				len += sprintf(buf + len, "Shared ");
148			}
149
150			if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) != 0) {
151				len += sprintf(buf + len, "No ISR ");
152			}
153
154			if ((channel->flags & DMA_CHANNEL_FLAG_LARGE_FIFO) != 0) {
155				len += sprintf(buf + len, "Fifo: 128 ");
156			} else {
157				len += sprintf(buf + len, "Fifo: 64  ");
158			}
159
160			if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
161				len +=
162				    sprintf(buf + len, "InUse by %s",
163					    DMA_gDeviceAttribute[channel->
164								 devType].name);
165#if DMA_DEBUG_TRACK_RESERVATION
166				len +=
167				    sprintf(buf + len, " (%s:%d)",
168					    channel->fileName,
169					    channel->lineNum);
170#endif
171			} else {
172				len += sprintf(buf + len, "Avail ");
173			}
174
175			if (channel->lastDevType != DMA_DEVICE_NONE) {
176				len +=
177				    sprintf(buf + len, "Last use: %s ",
178					    DMA_gDeviceAttribute[channel->
179								 lastDevType].
180					    name);
181			}
182
183			len += sprintf(buf + len, "\n");
184		}
185	}
186	up(&gDMA.lock);
187	*eof = 1;
188
189	return len;
190}
191
192/****************************************************************************/
193/**
194*   Displays information for /proc/dma/devices
195*/
196/****************************************************************************/
197
198static int dma_proc_read_devices(char *buf, char **start, off_t offset,
199				 int count, int *eof, void *data)
200{
201	int limit = count - 200;
202	int len = 0;
203	int devIdx;
204
205	if (down_interruptible(&gDMA.lock) < 0) {
206		return -ERESTARTSYS;
207	}
208
209	for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
210		DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
211
212		if (devAttr->name == NULL) {
213			continue;
214		}
215
216		if (len >= limit) {
217			break;
218		}
219
220		len += sprintf(buf + len, "%-12s ", devAttr->name);
221
222		if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
223			len +=
224			    sprintf(buf + len, "Dedicated %d:%d ",
225				    devAttr->dedicatedController,
226				    devAttr->dedicatedChannel);
227		} else {
228			len += sprintf(buf + len, "Shared DMA:");
229			if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA0) != 0) {
230				len += sprintf(buf + len, "0");
231			}
232			if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA1) != 0) {
233				len += sprintf(buf + len, "1");
234			}
235			len += sprintf(buf + len, " ");
236		}
237		if ((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) {
238			len += sprintf(buf + len, "NoISR ");
239		}
240		if ((devAttr->flags & DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) != 0) {
241			len += sprintf(buf + len, "Allow-128 ");
242		}
243
244		len +=
245		    sprintf(buf + len,
246			    "Xfer #: %Lu Ticks: %Lu Bytes: %Lu DescLen: %u\n",
247			    devAttr->numTransfers, devAttr->transferTicks,
248			    devAttr->transferBytes,
249			    devAttr->ring.bytesAllocated);
250
251	}
252
253	up(&gDMA.lock);
254	*eof = 1;
255
256	return len;
257}
258
259/****************************************************************************/
260/**
261*   Determines if a DMA_Device_t is "valid".
262*
263*   @return
264*       TRUE        - dma device is valid
265*       FALSE       - dma device isn't valid
266*/
267/****************************************************************************/
268
269static inline int IsDeviceValid(DMA_Device_t device)
270{
271	return (device >= 0) && (device < DMA_NUM_DEVICE_ENTRIES);
272}
273
274/****************************************************************************/
275/**
276*   Translates a DMA handle into a pointer to a channel.
277*
278*   @return
279*       non-NULL    - pointer to DMA_Channel_t
280*       NULL        - DMA Handle was invalid
281*/
282/****************************************************************************/
283
284static inline DMA_Channel_t *HandleToChannel(DMA_Handle_t handle)
285{
286	int controllerIdx;
287	int channelIdx;
288
289	controllerIdx = CONTROLLER_FROM_HANDLE(handle);
290	channelIdx = CHANNEL_FROM_HANDLE(handle);
291
292	if ((controllerIdx > DMA_NUM_CONTROLLERS)
293	    || (channelIdx > DMA_NUM_CHANNELS)) {
294		return NULL;
295	}
296	return &gDMA.controller[controllerIdx].channel[channelIdx];
297}
298
299/****************************************************************************/
300/**
301*   Interrupt handler which is called to process DMA interrupts.
302*/
303/****************************************************************************/
304
305static irqreturn_t dma_interrupt_handler(int irq, void *dev_id)
306{
307	DMA_Channel_t *channel;
308	DMA_DeviceAttribute_t *devAttr;
309	int irqStatus;
310
311	channel = (DMA_Channel_t *) dev_id;
312
313	/* Figure out why we were called, and knock down the interrupt */
314
315	irqStatus = dmacHw_getInterruptStatus(channel->dmacHwHandle);
316	dmacHw_clearInterrupt(channel->dmacHwHandle);
317
318	if ((channel->devType < 0)
319	    || (channel->devType > DMA_NUM_DEVICE_ENTRIES)) {
320		printk(KERN_ERR "dma_interrupt_handler: Invalid devType: %d\n",
321		       channel->devType);
322		return IRQ_NONE;
323	}
324	devAttr = &DMA_gDeviceAttribute[channel->devType];
325
326	/* Update stats */
327
328	if ((irqStatus & dmacHw_INTERRUPT_STATUS_TRANS) != 0) {
329		devAttr->transferTicks +=
330		    (timer_get_tick_count() - devAttr->transferStartTime);
331	}
332
333	if ((irqStatus & dmacHw_INTERRUPT_STATUS_ERROR) != 0) {
334		printk(KERN_ERR
335		       "dma_interrupt_handler: devType :%d DMA error (%s)\n",
336		       channel->devType, devAttr->name);
337	} else {
338		devAttr->numTransfers++;
339		devAttr->transferBytes += devAttr->numBytes;
340	}
341
342	/* Call any installed handler */
343
344	if (devAttr->devHandler != NULL) {
345		devAttr->devHandler(channel->devType, irqStatus,
346				    devAttr->userData);
347	}
348
349	return IRQ_HANDLED;
350}
351
352/****************************************************************************/
353/**
354*   Allocates memory to hold a descriptor ring. The descriptor ring then
355*   needs to be populated by making one or more calls to
356*   dna_add_descriptors.
357*
358*   The returned descriptor ring will be automatically initialized.
359*
360*   @return
361*       0           Descriptor ring was allocated successfully
362*       -EINVAL     Invalid parameters passed in
363*       -ENOMEM     Unable to allocate memory for the desired number of descriptors.
364*/
365/****************************************************************************/
366
367int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to populate */
368			      int numDescriptors	/* Number of descriptors that need to be allocated. */
369    ) {
370	size_t bytesToAlloc = dmacHw_descriptorLen(numDescriptors);
371
372	if ((ring == NULL) || (numDescriptors <= 0)) {
373		return -EINVAL;
374	}
375
376	ring->physAddr = 0;
377	ring->descriptorsAllocated = 0;
378	ring->bytesAllocated = 0;
379
380	ring->virtAddr = dma_alloc_writecombine(NULL,
381						     bytesToAlloc,
382						     &ring->physAddr,
383						     GFP_KERNEL);
384	if (ring->virtAddr == NULL) {
385		return -ENOMEM;
386	}
387
388	ring->bytesAllocated = bytesToAlloc;
389	ring->descriptorsAllocated = numDescriptors;
390
391	return dma_init_descriptor_ring(ring, numDescriptors);
392}
393
394EXPORT_SYMBOL(dma_alloc_descriptor_ring);
395
396/****************************************************************************/
397/**
398*   Releases the memory which was previously allocated for a descriptor ring.
399*/
400/****************************************************************************/
401
402void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring	/* Descriptor to release */
403    ) {
404	if (ring->virtAddr != NULL) {
405		dma_free_writecombine(NULL,
406				      ring->bytesAllocated,
407				      ring->virtAddr, ring->physAddr);
408	}
409
410	ring->bytesAllocated = 0;
411	ring->descriptorsAllocated = 0;
412	ring->virtAddr = NULL;
413	ring->physAddr = 0;
414}
415
416EXPORT_SYMBOL(dma_free_descriptor_ring);
417
418/****************************************************************************/
419/**
420*   Initializes a descriptor ring, so that descriptors can be added to it.
421*   Once a descriptor ring has been allocated, it may be reinitialized for
422*   use with additional/different regions of memory.
423*
424*   Note that if 7 descriptors are allocated, it's perfectly acceptable to
425*   initialize the ring with a smaller number of descriptors. The amount
426*   of memory allocated for the descriptor ring will not be reduced, and
427*   the descriptor ring may be reinitialized later
428*
429*   @return
430*       0           Descriptor ring was initialized successfully
431*       -ENOMEM     The descriptor which was passed in has insufficient space
432*                   to hold the desired number of descriptors.
433*/
434/****************************************************************************/
435
436int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to initialize */
437			     int numDescriptors	/* Number of descriptors to initialize. */
438    ) {
439	if (ring->virtAddr == NULL) {
440		return -EINVAL;
441	}
442	if (dmacHw_initDescriptor(ring->virtAddr,
443				  ring->physAddr,
444				  ring->bytesAllocated, numDescriptors) < 0) {
445		printk(KERN_ERR
446		       "dma_init_descriptor_ring: dmacHw_initDescriptor failed\n");
447		return -ENOMEM;
448	}
449
450	return 0;
451}
452
453EXPORT_SYMBOL(dma_init_descriptor_ring);
454
455/****************************************************************************/
456/**
457*   Determines the number of descriptors which would be required for a
458*   transfer of the indicated memory region.
459*
460*   This function also needs to know which DMA device this transfer will
461*   be destined for, so that the appropriate DMA configuration can be retrieved.
462*   DMA parameters such as transfer width, and whether this is a memory-to-memory
463*   or memory-to-peripheral, etc can all affect the actual number of descriptors
464*   required.
465*
466*   @return
467*       > 0     Returns the number of descriptors required for the indicated transfer
468*       -ENODEV - Device handed in is invalid.
469*       -EINVAL Invalid parameters
470*       -ENOMEM Memory exhausted
471*/
472/****************************************************************************/
473
474int dma_calculate_descriptor_count(DMA_Device_t device,	/* DMA Device that this will be associated with */
475				   dma_addr_t srcData,	/* Place to get data to write to device */
476				   dma_addr_t dstData,	/* Pointer to device data address */
477				   size_t numBytes	/* Number of bytes to transfer to the device */
478    ) {
479	int numDescriptors;
480	DMA_DeviceAttribute_t *devAttr;
481
482	if (!IsDeviceValid(device)) {
483		return -ENODEV;
484	}
485	devAttr = &DMA_gDeviceAttribute[device];
486
487	numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
488							      (void *)srcData,
489							      (void *)dstData,
490							      numBytes);
491	if (numDescriptors < 0) {
492		printk(KERN_ERR
493		       "dma_calculate_descriptor_count: dmacHw_calculateDescriptorCount failed\n");
494		return -EINVAL;
495	}
496
497	return numDescriptors;
498}
499
500EXPORT_SYMBOL(dma_calculate_descriptor_count);
501
502/****************************************************************************/
503/**
504*   Adds a region of memory to the descriptor ring. Note that it may take
505*   multiple descriptors for each region of memory. It is the callers
506*   responsibility to allocate a sufficiently large descriptor ring.
507*
508*   @return
509*       0       Descriptors were added successfully
510*       -ENODEV Device handed in is invalid.
511*       -EINVAL Invalid parameters
512*       -ENOMEM Memory exhausted
513*/
514/****************************************************************************/
515
516int dma_add_descriptors(DMA_DescriptorRing_t *ring,	/* Descriptor ring to add descriptors to */
517			DMA_Device_t device,	/* DMA Device that descriptors are for */
518			dma_addr_t srcData,	/* Place to get data (memory or device) */
519			dma_addr_t dstData,	/* Place to put data (memory or device) */
520			size_t numBytes	/* Number of bytes to transfer to the device */
521    ) {
522	int rc;
523	DMA_DeviceAttribute_t *devAttr;
524
525	if (!IsDeviceValid(device)) {
526		return -ENODEV;
527	}
528	devAttr = &DMA_gDeviceAttribute[device];
529
530	rc = dmacHw_setDataDescriptor(&devAttr->config,
531				      ring->virtAddr,
532				      (void *)srcData,
533				      (void *)dstData, numBytes);
534	if (rc < 0) {
535		printk(KERN_ERR
536		       "dma_add_descriptors: dmacHw_setDataDescriptor failed with code: %d\n",
537		       rc);
538		return -ENOMEM;
539	}
540
541	return 0;
542}
543
544EXPORT_SYMBOL(dma_add_descriptors);
545
546/****************************************************************************/
547/**
548*   Sets the descriptor ring associated with a device.
549*
550*   Once set, the descriptor ring will be associated with the device, even
551*   across channel request/free calls. Passing in a NULL descriptor ring
552*   will release any descriptor ring currently associated with the device.
553*
554*   Note: If you call dma_transfer, or one of the other dma_alloc_ functions
555*         the descriptor ring may be released and reallocated.
556*
557*   Note: This function will release the descriptor memory for any current
558*         descriptor ring associated with this device.
559*
560*   @return
561*       0       Descriptors were added successfully
562*       -ENODEV Device handed in is invalid.
563*/
564/****************************************************************************/
565
566int dma_set_device_descriptor_ring(DMA_Device_t device,	/* Device to update the descriptor ring for. */
567				   DMA_DescriptorRing_t *ring	/* Descriptor ring to add descriptors to */
568    ) {
569	DMA_DeviceAttribute_t *devAttr;
570
571	if (!IsDeviceValid(device)) {
572		return -ENODEV;
573	}
574	devAttr = &DMA_gDeviceAttribute[device];
575
576	/* Free the previously allocated descriptor ring */
577
578	dma_free_descriptor_ring(&devAttr->ring);
579
580	if (ring != NULL) {
581		/* Copy in the new one */
582
583		devAttr->ring = *ring;
584	}
585
586	/* Set things up so that if dma_transfer is called then this descriptor */
587	/* ring will get freed. */
588
589	devAttr->prevSrcData = 0;
590	devAttr->prevDstData = 0;
591	devAttr->prevNumBytes = 0;
592
593	return 0;
594}
595
596EXPORT_SYMBOL(dma_set_device_descriptor_ring);
597
598/****************************************************************************/
599/**
600*   Retrieves the descriptor ring associated with a device.
601*
602*   @return
603*       0       Descriptors were added successfully
604*       -ENODEV Device handed in is invalid.
605*/
606/****************************************************************************/
607
608int dma_get_device_descriptor_ring(DMA_Device_t device,	/* Device to retrieve the descriptor ring for. */
609				   DMA_DescriptorRing_t *ring	/* Place to store retrieved ring */
610    ) {
611	DMA_DeviceAttribute_t *devAttr;
612
613	memset(ring, 0, sizeof(*ring));
614
615	if (!IsDeviceValid(device)) {
616		return -ENODEV;
617	}
618	devAttr = &DMA_gDeviceAttribute[device];
619
620	*ring = devAttr->ring;
621
622	return 0;
623}
624
625EXPORT_SYMBOL(dma_get_device_descriptor_ring);
626
627/****************************************************************************/
628/**
629*   Configures a DMA channel.
630*
631*   @return
632*       >= 0    - Initialization was successfull.
633*
634*       -EBUSY  - Device is currently being used.
635*       -ENODEV - Device handed in is invalid.
636*/
637/****************************************************************************/
638
639static int ConfigChannel(DMA_Handle_t handle)
640{
641	DMA_Channel_t *channel;
642	DMA_DeviceAttribute_t *devAttr;
643	int controllerIdx;
644
645	channel = HandleToChannel(handle);
646	if (channel == NULL) {
647		return -ENODEV;
648	}
649	devAttr = &DMA_gDeviceAttribute[channel->devType];
650	controllerIdx = CONTROLLER_FROM_HANDLE(handle);
651
652	if ((devAttr->flags & DMA_DEVICE_FLAG_PORT_PER_DMAC) != 0) {
653		if (devAttr->config.transferType ==
654		    dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL) {
655			devAttr->config.dstPeripheralPort =
656			    devAttr->dmacPort[controllerIdx];
657		} else if (devAttr->config.transferType ==
658			   dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) {
659			devAttr->config.srcPeripheralPort =
660			    devAttr->dmacPort[controllerIdx];
661		}
662	}
663
664	if (dmacHw_configChannel(channel->dmacHwHandle, &devAttr->config) != 0) {
665		printk(KERN_ERR "ConfigChannel: dmacHw_configChannel failed\n");
666		return -EIO;
667	}
668
669	return 0;
670}
671
672/****************************************************************************/
673/**
674*   Intializes all of the data structures associated with the DMA.
675*   @return
676*       >= 0    - Initialization was successfull.
677*
678*       -EBUSY  - Device is currently being used.
679*       -ENODEV - Device handed in is invalid.
680*/
681/****************************************************************************/
682
683int dma_init(void)
684{
685	int rc = 0;
686	int controllerIdx;
687	int channelIdx;
688	DMA_Device_t devIdx;
689	DMA_Channel_t *channel;
690	DMA_Handle_t dedicatedHandle;
691
692	memset(&gDMA, 0, sizeof(gDMA));
693
694	init_MUTEX_LOCKED(&gDMA.lock);
695	init_waitqueue_head(&gDMA.freeChannelQ);
696
697	/* Initialize the Hardware */
698
699	dmacHw_initDma();
700
701	/* Start off by marking all of the DMA channels as shared. */
702
703	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
704	     controllerIdx++) {
705		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
706		     channelIdx++) {
707			channel =
708			    &gDMA.controller[controllerIdx].channel[channelIdx];
709
710			channel->flags = 0;
711			channel->devType = DMA_DEVICE_NONE;
712			channel->lastDevType = DMA_DEVICE_NONE;
713
714#if DMA_DEBUG_TRACK_RESERVATION
715			channel->fileName = "";
716			channel->lineNum = 0;
717#endif
718
719			channel->dmacHwHandle =
720			    dmacHw_getChannelHandle(dmacHw_MAKE_CHANNEL_ID
721						    (controllerIdx,
722						     channelIdx));
723			dmacHw_initChannel(channel->dmacHwHandle);
724		}
725	}
726
727	/* Record any special attributes that channels may have */
728
729	gDMA.controller[0].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
730	gDMA.controller[0].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
731	gDMA.controller[1].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
732	gDMA.controller[1].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
733
734	/* Now walk through and record the dedicated channels. */
735
736	for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
737		DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
738
739		if (((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0)
740		    && ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0)) {
741			printk(KERN_ERR
742			       "DMA Device: %s Can only request NO_ISR for dedicated devices\n",
743			       devAttr->name);
744			rc = -EINVAL;
745			goto out;
746		}
747
748		if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
749			/* This is a dedicated device. Mark the channel as being reserved. */
750
751			if (devAttr->dedicatedController >= DMA_NUM_CONTROLLERS) {
752				printk(KERN_ERR
753				       "DMA Device: %s DMA Controller %d is out of range\n",
754				       devAttr->name,
755				       devAttr->dedicatedController);
756				rc = -EINVAL;
757				goto out;
758			}
759
760			if (devAttr->dedicatedChannel >= DMA_NUM_CHANNELS) {
761				printk(KERN_ERR
762				       "DMA Device: %s DMA Channel %d is out of range\n",
763				       devAttr->name,
764				       devAttr->dedicatedChannel);
765				rc = -EINVAL;
766				goto out;
767			}
768
769			dedicatedHandle =
770			    MAKE_HANDLE(devAttr->dedicatedController,
771					devAttr->dedicatedChannel);
772			channel = HandleToChannel(dedicatedHandle);
773
774			if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
775			    0) {
776				printk
777				    ("DMA Device: %s attempting to use same DMA Controller:Channel (%d:%d) as %s\n",
778				     devAttr->name,
779				     devAttr->dedicatedController,
780				     devAttr->dedicatedChannel,
781				     DMA_gDeviceAttribute[channel->devType].
782				     name);
783				rc = -EBUSY;
784				goto out;
785			}
786
787			channel->flags |= DMA_CHANNEL_FLAG_IS_DEDICATED;
788			channel->devType = devIdx;
789
790			if (devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) {
791				channel->flags |= DMA_CHANNEL_FLAG_NO_ISR;
792			}
793
794			/* For dedicated channels, we can go ahead and configure the DMA channel now */
795			/* as well. */
796
797			ConfigChannel(dedicatedHandle);
798		}
799	}
800
801	/* Go through and register the interrupt handlers */
802
803	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
804	     controllerIdx++) {
805		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
806		     channelIdx++) {
807			channel =
808			    &gDMA.controller[controllerIdx].channel[channelIdx];
809
810			if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) == 0) {
811				snprintf(channel->name, sizeof(channel->name),
812					 "dma %d:%d %s", controllerIdx,
813					 channelIdx,
814					 channel->devType ==
815					 DMA_DEVICE_NONE ? "" :
816					 DMA_gDeviceAttribute[channel->devType].
817					 name);
818
819				rc =
820				     request_irq(IRQ_DMA0C0 +
821						 (controllerIdx *
822						  DMA_NUM_CHANNELS) +
823						 channelIdx,
824						 dma_interrupt_handler,
825						 IRQF_DISABLED, channel->name,
826						 channel);
827				if (rc != 0) {
828					printk(KERN_ERR
829					       "request_irq for IRQ_DMA%dC%d failed\n",
830					       controllerIdx, channelIdx);
831				}
832			}
833		}
834	}
835
836	/* Create /proc/dma/channels and /proc/dma/devices */
837
838	gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
839
840	if (gDmaDir == NULL) {
841		printk(KERN_ERR "Unable to create /proc/dma\n");
842	} else {
843		create_proc_read_entry("channels", 0, gDmaDir,
844				       dma_proc_read_channels, NULL);
845		create_proc_read_entry("devices", 0, gDmaDir,
846				       dma_proc_read_devices, NULL);
847		create_proc_read_entry("mem-type", 0, gDmaDir,
848				       dma_proc_read_mem_type, NULL);
849	}
850
851out:
852
853	up(&gDMA.lock);
854
855	return rc;
856}
857
858/****************************************************************************/
859/**
860*   Reserves a channel for use with @a dev. If the device is setup to use
861*   a shared channel, then this function will block until a free channel
862*   becomes available.
863*
864*   @return
865*       >= 0    - A valid DMA Handle.
866*       -EBUSY  - Device is currently being used.
867*       -ENODEV - Device handed in is invalid.
868*/
869/****************************************************************************/
870
871#if DMA_DEBUG_TRACK_RESERVATION
872DMA_Handle_t dma_request_channel_dbg
873    (DMA_Device_t dev, const char *fileName, int lineNum)
874#else
875DMA_Handle_t dma_request_channel(DMA_Device_t dev)
876#endif
877{
878	DMA_Handle_t handle;
879	DMA_DeviceAttribute_t *devAttr;
880	DMA_Channel_t *channel;
881	int controllerIdx;
882	int controllerIdx2;
883	int channelIdx;
884
885	if (down_interruptible(&gDMA.lock) < 0) {
886		return -ERESTARTSYS;
887	}
888
889	if ((dev < 0) || (dev >= DMA_NUM_DEVICE_ENTRIES)) {
890		handle = -ENODEV;
891		goto out;
892	}
893	devAttr = &DMA_gDeviceAttribute[dev];
894
895#if DMA_DEBUG_TRACK_RESERVATION
896	{
897		char *s;
898
899		s = strrchr(fileName, '/');
900		if (s != NULL) {
901			fileName = s + 1;
902		}
903	}
904#endif
905	if ((devAttr->flags & DMA_DEVICE_FLAG_IN_USE) != 0) {
906		/* This device has already been requested and not been freed */
907
908		printk(KERN_ERR "%s: device %s is already requested\n",
909		       __func__, devAttr->name);
910		handle = -EBUSY;
911		goto out;
912	}
913
914	if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
915		/* This device has a dedicated channel. */
916
917		channel =
918		    &gDMA.controller[devAttr->dedicatedController].
919		    channel[devAttr->dedicatedChannel];
920		if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
921			handle = -EBUSY;
922			goto out;
923		}
924
925		channel->flags |= DMA_CHANNEL_FLAG_IN_USE;
926		devAttr->flags |= DMA_DEVICE_FLAG_IN_USE;
927
928#if DMA_DEBUG_TRACK_RESERVATION
929		channel->fileName = fileName;
930		channel->lineNum = lineNum;
931#endif
932		handle =
933		    MAKE_HANDLE(devAttr->dedicatedController,
934				devAttr->dedicatedChannel);
935		goto out;
936	}
937
938	/* This device needs to use one of the shared channels. */
939
940	handle = DMA_INVALID_HANDLE;
941	while (handle == DMA_INVALID_HANDLE) {
942		/* Scan through the shared channels and see if one is available */
943
944		for (controllerIdx2 = 0; controllerIdx2 < DMA_NUM_CONTROLLERS;
945		     controllerIdx2++) {
946			/* Check to see if we should try on controller 1 first. */
947
948			controllerIdx = controllerIdx2;
949			if ((devAttr->
950			     flags & DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST) != 0) {
951				controllerIdx = 1 - controllerIdx;
952			}
953
954			/* See if the device is available on the controller being tested */
955
956			if ((devAttr->
957			     flags & (DMA_DEVICE_FLAG_ON_DMA0 << controllerIdx))
958			    != 0) {
959				for (channelIdx = 0;
960				     channelIdx < DMA_NUM_CHANNELS;
961				     channelIdx++) {
962					channel =
963					    &gDMA.controller[controllerIdx].
964					    channel[channelIdx];
965
966					if (((channel->
967					      flags &
968					      DMA_CHANNEL_FLAG_IS_DEDICATED) ==
969					     0)
970					    &&
971					    ((channel->
972					      flags & DMA_CHANNEL_FLAG_IN_USE)
973					     == 0)) {
974						if (((channel->
975						      flags &
976						      DMA_CHANNEL_FLAG_LARGE_FIFO)
977						     != 0)
978						    &&
979						    ((devAttr->
980						      flags &
981						      DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO)
982						     == 0)) {
983							/* This channel is a large fifo - don't tie it up */
984							/* with devices that we don't want using it. */
985
986							continue;
987						}
988
989						channel->flags |=
990						    DMA_CHANNEL_FLAG_IN_USE;
991						channel->devType = dev;
992						devAttr->flags |=
993						    DMA_DEVICE_FLAG_IN_USE;
994
995#if DMA_DEBUG_TRACK_RESERVATION
996						channel->fileName = fileName;
997						channel->lineNum = lineNum;
998#endif
999						handle =
1000						    MAKE_HANDLE(controllerIdx,
1001								channelIdx);
1002
1003						/* Now that we've reserved the channel - we can go ahead and configure it */
1004
1005						if (ConfigChannel(handle) != 0) {
1006							handle = -EIO;
1007							printk(KERN_ERR
1008							       "dma_request_channel: ConfigChannel failed\n");
1009						}
1010						goto out;
1011					}
1012				}
1013			}
1014		}
1015
1016		/* No channels are currently available. Let's wait for one to free up. */
1017
1018		{
1019			DEFINE_WAIT(wait);
1020
1021			prepare_to_wait(&gDMA.freeChannelQ, &wait,
1022					TASK_INTERRUPTIBLE);
1023			up(&gDMA.lock);
1024			schedule();
1025			finish_wait(&gDMA.freeChannelQ, &wait);
1026
1027			if (signal_pending(current)) {
1028				/* We don't currently hold gDMA.lock, so we return directly */
1029
1030				return -ERESTARTSYS;
1031			}
1032		}
1033
1034		if (down_interruptible(&gDMA.lock)) {
1035			return -ERESTARTSYS;
1036		}
1037	}
1038
1039out:
1040	up(&gDMA.lock);
1041
1042	return handle;
1043}
1044
1045/* Create both _dbg and non _dbg functions for modules. */
1046
1047#if DMA_DEBUG_TRACK_RESERVATION
1048#undef dma_request_channel
1049DMA_Handle_t dma_request_channel(DMA_Device_t dev)
1050{
1051	return dma_request_channel_dbg(dev, __FILE__, __LINE__);
1052}
1053
1054EXPORT_SYMBOL(dma_request_channel_dbg);
1055#endif
1056EXPORT_SYMBOL(dma_request_channel);
1057
1058/****************************************************************************/
1059/**
1060*   Frees a previously allocated DMA Handle.
1061*/
1062/****************************************************************************/
1063
1064int dma_free_channel(DMA_Handle_t handle	/* DMA handle. */
1065    ) {
1066	int rc = 0;
1067	DMA_Channel_t *channel;
1068	DMA_DeviceAttribute_t *devAttr;
1069
1070	if (down_interruptible(&gDMA.lock) < 0) {
1071		return -ERESTARTSYS;
1072	}
1073
1074	channel = HandleToChannel(handle);
1075	if (channel == NULL) {
1076		rc = -EINVAL;
1077		goto out;
1078	}
1079
1080	devAttr = &DMA_gDeviceAttribute[channel->devType];
1081
1082	if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) == 0) {
1083		channel->lastDevType = channel->devType;
1084		channel->devType = DMA_DEVICE_NONE;
1085	}
1086	channel->flags &= ~DMA_CHANNEL_FLAG_IN_USE;
1087	devAttr->flags &= ~DMA_DEVICE_FLAG_IN_USE;
1088
1089out:
1090	up(&gDMA.lock);
1091
1092	wake_up_interruptible(&gDMA.freeChannelQ);
1093
1094	return rc;
1095}
1096
1097EXPORT_SYMBOL(dma_free_channel);
1098
1099/****************************************************************************/
1100/**
1101*   Determines if a given device has been configured as using a shared
1102*   channel.
1103*
1104*   @return
1105*       0           Device uses a dedicated channel
1106*       > zero      Device uses a shared channel
1107*       < zero      Error code
1108*/
1109/****************************************************************************/
1110
1111int dma_device_is_channel_shared(DMA_Device_t device	/* Device to check. */
1112    ) {
1113	DMA_DeviceAttribute_t *devAttr;
1114
1115	if (!IsDeviceValid(device)) {
1116		return -ENODEV;
1117	}
1118	devAttr = &DMA_gDeviceAttribute[device];
1119
1120	return ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0);
1121}
1122
1123EXPORT_SYMBOL(dma_device_is_channel_shared);
1124
1125/****************************************************************************/
1126/**
1127*   Allocates buffers for the descriptors. This is normally done automatically
1128*   but needs to be done explicitly when initiating a dma from interrupt
1129*   context.
1130*
1131*   @return
1132*       0       Descriptors were allocated successfully
1133*       -EINVAL Invalid device type for this kind of transfer
1134*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
1135*       -ENOMEM Memory exhausted
1136*/
1137/****************************************************************************/
1138
1139int dma_alloc_descriptors(DMA_Handle_t handle,	/* DMA Handle */
1140			  dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
1141			  dma_addr_t srcData,	/* Place to get data to write to device */
1142			  dma_addr_t dstData,	/* Pointer to device data address */
1143			  size_t numBytes	/* Number of bytes to transfer to the device */
1144    ) {
1145	DMA_Channel_t *channel;
1146	DMA_DeviceAttribute_t *devAttr;
1147	int numDescriptors;
1148	size_t ringBytesRequired;
1149	int rc = 0;
1150
1151	channel = HandleToChannel(handle);
1152	if (channel == NULL) {
1153		return -ENODEV;
1154	}
1155
1156	devAttr = &DMA_gDeviceAttribute[channel->devType];
1157
1158	if (devAttr->config.transferType != transferType) {
1159		return -EINVAL;
1160	}
1161
1162	/* Figure out how many descriptors we need. */
1163
1164	/* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
1165	/*        srcData, dstData, numBytes); */
1166
1167	numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
1168							      (void *)srcData,
1169							      (void *)dstData,
1170							      numBytes);
1171	if (numDescriptors < 0) {
1172		printk(KERN_ERR "%s: dmacHw_calculateDescriptorCount failed\n",
1173		       __func__);
1174		return -EINVAL;
1175	}
1176
1177	/* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
1178	/* a new one. */
1179
1180	ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
1181
1182	/* printk("ringBytesRequired: %d\n", ringBytesRequired); */
1183
1184	if (ringBytesRequired > devAttr->ring.bytesAllocated) {
1185		/* Make sure that this code path is never taken from interrupt context. */
1186		/* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
1187		/* allocation needs to have already been done. */
1188
1189		might_sleep();
1190
1191		/* Free the old descriptor ring and allocate a new one. */
1192
1193		dma_free_descriptor_ring(&devAttr->ring);
1194
1195		/* And allocate a new one. */
1196
1197		rc =
1198		     dma_alloc_descriptor_ring(&devAttr->ring,
1199					       numDescriptors);
1200		if (rc < 0) {
1201			printk(KERN_ERR
1202			       "%s: dma_alloc_descriptor_ring(%d) failed\n",
1203			       __func__, numDescriptors);
1204			return rc;
1205		}
1206		/* Setup the descriptor for this transfer */
1207
1208		if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
1209					  devAttr->ring.physAddr,
1210					  devAttr->ring.bytesAllocated,
1211					  numDescriptors) < 0) {
1212			printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n",
1213			       __func__);
1214			return -EINVAL;
1215		}
1216	} else {
1217		/* We've already got enough ring buffer allocated. All we need to do is reset */
1218		/* any control information, just in case the previous DMA was stopped. */
1219
1220		dmacHw_resetDescriptorControl(devAttr->ring.virtAddr);
1221	}
1222
1223	/* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
1224	/* as last time, then we don't need to call setDataDescriptor again. */
1225
1226	if (dmacHw_setDataDescriptor(&devAttr->config,
1227				     devAttr->ring.virtAddr,
1228				     (void *)srcData,
1229				     (void *)dstData, numBytes) < 0) {
1230		printk(KERN_ERR "%s: dmacHw_setDataDescriptor failed\n",
1231		       __func__);
1232		return -EINVAL;
1233	}
1234
1235	/* Remember the critical information for this transfer so that we can eliminate */
1236	/* another call to dma_alloc_descriptors if the caller reuses the same buffers */
1237
1238	devAttr->prevSrcData = srcData;
1239	devAttr->prevDstData = dstData;
1240	devAttr->prevNumBytes = numBytes;
1241
1242	return 0;
1243}
1244
1245EXPORT_SYMBOL(dma_alloc_descriptors);
1246
1247/****************************************************************************/
1248/**
1249*   Allocates and sets up descriptors for a double buffered circular buffer.
1250*
1251*   This is primarily intended to be used for things like the ingress samples
1252*   from a microphone.
1253*
1254*   @return
1255*       > 0     Number of descriptors actually allocated.
1256*       -EINVAL Invalid device type for this kind of transfer
1257*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
1258*       -ENOMEM Memory exhausted
1259*/
1260/****************************************************************************/
1261
1262int dma_alloc_double_dst_descriptors(DMA_Handle_t handle,	/* DMA Handle */
1263				     dma_addr_t srcData,	/* Physical address of source data */
1264				     dma_addr_t dstData1,	/* Physical address of first destination buffer */
1265				     dma_addr_t dstData2,	/* Physical address of second destination buffer */
1266				     size_t numBytes	/* Number of bytes in each destination buffer */
1267    ) {
1268	DMA_Channel_t *channel;
1269	DMA_DeviceAttribute_t *devAttr;
1270	int numDst1Descriptors;
1271	int numDst2Descriptors;
1272	int numDescriptors;
1273	size_t ringBytesRequired;
1274	int rc = 0;
1275
1276	channel = HandleToChannel(handle);
1277	if (channel == NULL) {
1278		return -ENODEV;
1279	}
1280
1281	devAttr = &DMA_gDeviceAttribute[channel->devType];
1282
1283	/* Figure out how many descriptors we need. */
1284
1285	/* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
1286	/*        srcData, dstData, numBytes); */
1287
1288	numDst1Descriptors =
1289	     dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
1290					     (void *)dstData1, numBytes);
1291	if (numDst1Descriptors < 0) {
1292		return -EINVAL;
1293	}
1294	numDst2Descriptors =
1295	     dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
1296					     (void *)dstData2, numBytes);
1297	if (numDst2Descriptors < 0) {
1298		return -EINVAL;
1299	}
1300	numDescriptors = numDst1Descriptors + numDst2Descriptors;
1301	/* printk("numDescriptors: %d\n", numDescriptors); */
1302
1303	/* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
1304	/* a new one. */
1305
1306	ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
1307
1308	/* printk("ringBytesRequired: %d\n", ringBytesRequired); */
1309
1310	if (ringBytesRequired > devAttr->ring.bytesAllocated) {
1311		/* Make sure that this code path is never taken from interrupt context. */
1312		/* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
1313		/* allocation needs to have already been done. */
1314
1315		might_sleep();
1316
1317		/* Free the old descriptor ring and allocate a new one. */
1318
1319		dma_free_descriptor_ring(&devAttr->ring);
1320
1321		/* And allocate a new one. */
1322
1323		rc =
1324		     dma_alloc_descriptor_ring(&devAttr->ring,
1325					       numDescriptors);
1326		if (rc < 0) {
1327			printk(KERN_ERR
1328			       "%s: dma_alloc_descriptor_ring(%d) failed\n",
1329			       __func__, ringBytesRequired);
1330			return rc;
1331		}
1332	}
1333
1334	/* Setup the descriptor for this transfer. Since this function is used with */
1335	/* CONTINUOUS DMA operations, we need to reinitialize every time, otherwise */
1336	/* setDataDescriptor will keep trying to append onto the end. */
1337
1338	if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
1339				  devAttr->ring.physAddr,
1340				  devAttr->ring.bytesAllocated,
1341				  numDescriptors) < 0) {
1342		printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", __func__);
1343		return -EINVAL;
1344	}
1345
1346	/* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
1347	/* as last time, then we don't need to call setDataDescriptor again. */
1348
1349	if (dmacHw_setDataDescriptor(&devAttr->config,
1350				     devAttr->ring.virtAddr,
1351				     (void *)srcData,
1352				     (void *)dstData1, numBytes) < 0) {
1353		printk(KERN_ERR "%s: dmacHw_setDataDescriptor 1 failed\n",
1354		       __func__);
1355		return -EINVAL;
1356	}
1357	if (dmacHw_setDataDescriptor(&devAttr->config,
1358				     devAttr->ring.virtAddr,
1359				     (void *)srcData,
1360				     (void *)dstData2, numBytes) < 0) {
1361		printk(KERN_ERR "%s: dmacHw_setDataDescriptor 2 failed\n",
1362		       __func__);
1363		return -EINVAL;
1364	}
1365
1366	/* You should use dma_start_transfer rather than dma_transfer_xxx so we don't */
1367	/* try to make the 'prev' variables right. */
1368
1369	devAttr->prevSrcData = 0;
1370	devAttr->prevDstData = 0;
1371	devAttr->prevNumBytes = 0;
1372
1373	return numDescriptors;
1374}
1375
1376EXPORT_SYMBOL(dma_alloc_double_dst_descriptors);
1377
1378/****************************************************************************/
1379/**
1380*   Initiates a transfer when the descriptors have already been setup.
1381*
1382*   This is a special case, and normally, the dma_transfer_xxx functions should
1383*   be used.
1384*
1385*   @return
1386*       0       Transfer was started successfully
1387*       -ENODEV Invalid handle
1388*/
1389/****************************************************************************/
1390
1391int dma_start_transfer(DMA_Handle_t handle)
1392{
1393	DMA_Channel_t *channel;
1394	DMA_DeviceAttribute_t *devAttr;
1395
1396	channel = HandleToChannel(handle);
1397	if (channel == NULL) {
1398		return -ENODEV;
1399	}
1400	devAttr = &DMA_gDeviceAttribute[channel->devType];
1401
1402	dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
1403				devAttr->ring.virtAddr);
1404
1405	/* Since we got this far, everything went successfully */
1406
1407	return 0;
1408}
1409
1410EXPORT_SYMBOL(dma_start_transfer);
1411
1412/****************************************************************************/
1413/**
1414*   Stops a previously started DMA transfer.
1415*
1416*   @return
1417*       0       Transfer was stopped successfully
1418*       -ENODEV Invalid handle
1419*/
1420/****************************************************************************/
1421
1422int dma_stop_transfer(DMA_Handle_t handle)
1423{
1424	DMA_Channel_t *channel;
1425
1426	channel = HandleToChannel(handle);
1427	if (channel == NULL) {
1428		return -ENODEV;
1429	}
1430
1431	dmacHw_stopTransfer(channel->dmacHwHandle);
1432
1433	return 0;
1434}
1435
1436EXPORT_SYMBOL(dma_stop_transfer);
1437
1438/****************************************************************************/
1439/**
1440*   Waits for a DMA to complete by polling. This function is only intended
1441*   to be used for testing. Interrupts should be used for most DMA operations.
1442*/
1443/****************************************************************************/
1444
1445int dma_wait_transfer_done(DMA_Handle_t handle)
1446{
1447	DMA_Channel_t *channel;
1448	dmacHw_TRANSFER_STATUS_e status;
1449
1450	channel = HandleToChannel(handle);
1451	if (channel == NULL) {
1452		return -ENODEV;
1453	}
1454
1455	while ((status =
1456		dmacHw_transferCompleted(channel->dmacHwHandle)) ==
1457	       dmacHw_TRANSFER_STATUS_BUSY) {
1458		;
1459	}
1460
1461	if (status == dmacHw_TRANSFER_STATUS_ERROR) {
1462		printk(KERN_ERR "%s: DMA transfer failed\n", __func__);
1463		return -EIO;
1464	}
1465	return 0;
1466}
1467
1468EXPORT_SYMBOL(dma_wait_transfer_done);
1469
1470/****************************************************************************/
1471/**
1472*   Initiates a DMA, allocating the descriptors as required.
1473*
1474*   @return
1475*       0       Transfer was started successfully
1476*       -EINVAL Invalid device type for this kind of transfer
1477*               (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
1478*/
1479/****************************************************************************/
1480
1481int dma_transfer(DMA_Handle_t handle,	/* DMA Handle */
1482		 dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
1483		 dma_addr_t srcData,	/* Place to get data to write to device */
1484		 dma_addr_t dstData,	/* Pointer to device data address */
1485		 size_t numBytes	/* Number of bytes to transfer to the device */
1486    ) {
1487	DMA_Channel_t *channel;
1488	DMA_DeviceAttribute_t *devAttr;
1489	int rc = 0;
1490
1491	channel = HandleToChannel(handle);
1492	if (channel == NULL) {
1493		return -ENODEV;
1494	}
1495
1496	devAttr = &DMA_gDeviceAttribute[channel->devType];
1497
1498	if (devAttr->config.transferType != transferType) {
1499		return -EINVAL;
1500	}
1501
1502	/* We keep track of the information about the previous request for this */
1503	/* device, and if the attributes match, then we can use the descriptors we setup */
1504	/* the last time, and not have to reinitialize everything. */
1505
1506	{
1507		rc =
1508		     dma_alloc_descriptors(handle, transferType, srcData,
1509					   dstData, numBytes);
1510		if (rc != 0) {
1511			return rc;
1512		}
1513	}
1514
1515	/* And kick off the transfer */
1516
1517	devAttr->numBytes = numBytes;
1518	devAttr->transferStartTime = timer_get_tick_count();
1519
1520	dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
1521				devAttr->ring.virtAddr);
1522
1523	/* Since we got this far, everything went successfully */
1524
1525	return 0;
1526}
1527
1528EXPORT_SYMBOL(dma_transfer);
1529
1530/****************************************************************************/
1531/**
1532*   Set the callback function which will be called when a transfer completes.
1533*   If a NULL callback function is set, then no callback will occur.
1534*
1535*   @note   @a devHandler will be called from IRQ context.
1536*
1537*   @return
1538*       0       - Success
1539*       -ENODEV - Device handed in is invalid.
1540*/
1541/****************************************************************************/
1542
1543int dma_set_device_handler(DMA_Device_t dev,	/* Device to set the callback for. */
1544			   DMA_DeviceHandler_t devHandler,	/* Function to call when the DMA completes */
1545			   void *userData	/* Pointer which will be passed to devHandler. */
1546    ) {
1547	DMA_DeviceAttribute_t *devAttr;
1548	unsigned long flags;
1549
1550	if (!IsDeviceValid(dev)) {
1551		return -ENODEV;
1552	}
1553	devAttr = &DMA_gDeviceAttribute[dev];
1554
1555	local_irq_save(flags);
1556
1557	devAttr->userData = userData;
1558	devAttr->devHandler = devHandler;
1559
1560	local_irq_restore(flags);
1561
1562	return 0;
1563}
1564
1565EXPORT_SYMBOL(dma_set_device_handler);
1566
1567/****************************************************************************/
1568/**
1569*   Initializes a memory mapping structure
1570*/
1571/****************************************************************************/
1572
1573int dma_init_mem_map(DMA_MemMap_t *memMap)
1574{
1575	memset(memMap, 0, sizeof(*memMap));
1576
1577	init_MUTEX(&memMap->lock);
1578
1579	return 0;
1580}
1581
1582EXPORT_SYMBOL(dma_init_mem_map);
1583
1584/****************************************************************************/
1585/**
1586*   Releases any memory currently being held by a memory mapping structure.
1587*/
1588/****************************************************************************/
1589
1590int dma_term_mem_map(DMA_MemMap_t *memMap)
1591{
1592	down(&memMap->lock);	/* Just being paranoid */
1593
1594	/* Free up any allocated memory */
1595
1596	up(&memMap->lock);
1597	memset(memMap, 0, sizeof(*memMap));
1598
1599	return 0;
1600}
1601
1602EXPORT_SYMBOL(dma_term_mem_map);
1603
1604/****************************************************************************/
1605/**
1606*   Looks at a memory address and categorizes it.
1607*
1608*   @return One of the values from the DMA_MemType_t enumeration.
1609*/
1610/****************************************************************************/
1611
1612DMA_MemType_t dma_mem_type(void *addr)
1613{
1614	unsigned long addrVal = (unsigned long)addr;
1615
1616	if (addrVal >= VMALLOC_END) {
1617		/* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
1618
1619		/* dma_alloc_xxx pages are physically and virtually contiguous */
1620
1621		return DMA_MEM_TYPE_DMA;
1622	}
1623
1624	/* Technically, we could add one more classification. Addresses between VMALLOC_END */
1625	/* and the beginning of the DMA virtual address could be considered to be I/O space. */
1626	/* Right now, nobody cares about this particular classification, so we ignore it. */
1627
1628	if (is_vmalloc_addr(addr)) {
1629		/* Address comes from the vmalloc'd region. Pages are virtually */
1630		/* contiguous but NOT physically contiguous */
1631
1632		return DMA_MEM_TYPE_VMALLOC;
1633	}
1634
1635	if (addrVal >= PAGE_OFFSET) {
1636		/* PAGE_OFFSET is typically 0xC0000000 */
1637
1638		/* kmalloc'd pages are physically contiguous */
1639
1640		return DMA_MEM_TYPE_KMALLOC;
1641	}
1642
1643	return DMA_MEM_TYPE_USER;
1644}
1645
1646EXPORT_SYMBOL(dma_mem_type);
1647
1648/****************************************************************************/
1649/**
1650*   Looks at a memory address and determines if we support DMA'ing to/from
1651*   that type of memory.
1652*
1653*   @return boolean -
1654*               return value != 0 means dma supported
1655*               return value == 0 means dma not supported
1656*/
1657/****************************************************************************/
1658
1659int dma_mem_supports_dma(void *addr)
1660{
1661	DMA_MemType_t memType = dma_mem_type(addr);
1662
1663	return (memType == DMA_MEM_TYPE_DMA)
1664#if ALLOW_MAP_OF_KMALLOC_MEMORY
1665	    || (memType == DMA_MEM_TYPE_KMALLOC)
1666#endif
1667	    || (memType == DMA_MEM_TYPE_USER);
1668}
1669
1670EXPORT_SYMBOL(dma_mem_supports_dma);
1671
1672/****************************************************************************/
1673/**
1674*   Maps in a memory region such that it can be used for performing a DMA.
1675*
1676*   @return
1677*/
1678/****************************************************************************/
1679
1680int dma_map_start(DMA_MemMap_t *memMap,	/* Stores state information about the map */
1681		  enum dma_data_direction dir	/* Direction that the mapping will be going */
1682    ) {
1683	int rc;
1684
1685	down(&memMap->lock);
1686
1687	DMA_MAP_PRINT("memMap: %p\n", memMap);
1688
1689	if (memMap->inUse) {
1690		printk(KERN_ERR "%s: memory map %p is already being used\n",
1691		       __func__, memMap);
1692		rc = -EBUSY;
1693		goto out;
1694	}
1695
1696	memMap->inUse = 1;
1697	memMap->dir = dir;
1698	memMap->numRegionsUsed = 0;
1699
1700	rc = 0;
1701
1702out:
1703
1704	DMA_MAP_PRINT("returning %d", rc);
1705
1706	up(&memMap->lock);
1707
1708	return rc;
1709}
1710
1711EXPORT_SYMBOL(dma_map_start);
1712
1713/****************************************************************************/
1714/**
1715*   Adds a segment of memory to a memory map. Each segment is both
1716*   physically and virtually contiguous.
1717*
1718*   @return     0 on success, error code otherwise.
1719*/
1720/****************************************************************************/
1721
1722static int dma_map_add_segment(DMA_MemMap_t *memMap,	/* Stores state information about the map */
1723			       DMA_Region_t *region,	/* Region that the segment belongs to */
1724			       void *virtAddr,	/* Virtual address of the segment being added */
1725			       dma_addr_t physAddr,	/* Physical address of the segment being added */
1726			       size_t numBytes	/* Number of bytes of the segment being added */
1727    ) {
1728	DMA_Segment_t *segment;
1729
1730	DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
1731		      physAddr, numBytes);
1732
1733	/* Sanity check */
1734
1735	if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
1736	    || (((unsigned long)virtAddr + numBytes)) >
1737	    ((unsigned long)region->virtAddr + region->numBytes)) {
1738		printk(KERN_ERR
1739		       "%s: virtAddr %p is outside region @ %p len: %d\n",
1740		       __func__, virtAddr, region->virtAddr, region->numBytes);
1741		return -EINVAL;
1742	}
1743
1744	if (region->numSegmentsUsed > 0) {
1745		/* Check to see if this segment is physically contiguous with the previous one */
1746
1747		segment = &region->segment[region->numSegmentsUsed - 1];
1748
1749		if ((segment->physAddr + segment->numBytes) == physAddr) {
1750			/* It is - just add on to the end */
1751
1752			DMA_MAP_PRINT("appending %d bytes to last segment\n",
1753				      numBytes);
1754
1755			segment->numBytes += numBytes;
1756
1757			return 0;
1758		}
1759	}
1760
1761	/* Reallocate to hold more segments, if required. */
1762
1763	if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
1764		DMA_Segment_t *newSegment;
1765		size_t oldSize =
1766		    region->numSegmentsAllocated * sizeof(*newSegment);
1767		int newAlloc = region->numSegmentsAllocated + 4;
1768		size_t newSize = newAlloc * sizeof(*newSegment);
1769
1770		newSegment = kmalloc(newSize, GFP_KERNEL);
1771		if (newSegment == NULL) {
1772			return -ENOMEM;
1773		}
1774		memcpy(newSegment, region->segment, oldSize);
1775		memset(&((uint8_t *) newSegment)[oldSize], 0,
1776		       newSize - oldSize);
1777		kfree(region->segment);
1778
1779		region->numSegmentsAllocated = newAlloc;
1780		region->segment = newSegment;
1781	}
1782
1783	segment = &region->segment[region->numSegmentsUsed];
1784	region->numSegmentsUsed++;
1785
1786	segment->virtAddr = virtAddr;
1787	segment->physAddr = physAddr;
1788	segment->numBytes = numBytes;
1789
1790	DMA_MAP_PRINT("returning success\n");
1791
1792	return 0;
1793}
1794
1795/****************************************************************************/
1796/**
1797*   Adds a region of memory to a memory map. Each region is virtually
1798*   contiguous, but not necessarily physically contiguous.
1799*
1800*   @return     0 on success, error code otherwise.
1801*/
1802/****************************************************************************/
1803
1804int dma_map_add_region(DMA_MemMap_t *memMap,	/* Stores state information about the map */
1805		       void *mem,	/* Virtual address that we want to get a map of */
1806		       size_t numBytes	/* Number of bytes being mapped */
1807    ) {
1808	unsigned long addr = (unsigned long)mem;
1809	unsigned int offset;
1810	int rc = 0;
1811	DMA_Region_t *region;
1812	dma_addr_t physAddr;
1813
1814	down(&memMap->lock);
1815
1816	DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
1817
1818	if (!memMap->inUse) {
1819		printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
1820		       __func__);
1821		rc = -EINVAL;
1822		goto out;
1823	}
1824
1825	/* Reallocate to hold more regions. */
1826
1827	if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
1828		DMA_Region_t *newRegion;
1829		size_t oldSize =
1830		    memMap->numRegionsAllocated * sizeof(*newRegion);
1831		int newAlloc = memMap->numRegionsAllocated + 4;
1832		size_t newSize = newAlloc * sizeof(*newRegion);
1833
1834		newRegion = kmalloc(newSize, GFP_KERNEL);
1835		if (newRegion == NULL) {
1836			rc = -ENOMEM;
1837			goto out;
1838		}
1839		memcpy(newRegion, memMap->region, oldSize);
1840		memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
1841
1842		kfree(memMap->region);
1843
1844		memMap->numRegionsAllocated = newAlloc;
1845		memMap->region = newRegion;
1846	}
1847
1848	region = &memMap->region[memMap->numRegionsUsed];
1849	memMap->numRegionsUsed++;
1850
1851	offset = addr & ~PAGE_MASK;
1852
1853	region->memType = dma_mem_type(mem);
1854	region->virtAddr = mem;
1855	region->numBytes = numBytes;
1856	region->numSegmentsUsed = 0;
1857	region->numLockedPages = 0;
1858	region->lockedPages = NULL;
1859
1860	switch (region->memType) {
1861	case DMA_MEM_TYPE_VMALLOC:
1862		{
1863			atomic_inc(&gDmaStatMemTypeVmalloc);
1864
1865			/* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
1866
1867			/* vmalloc'd pages are not physically contiguous */
1868
1869			rc = -EINVAL;
1870			break;
1871		}
1872
1873	case DMA_MEM_TYPE_KMALLOC:
1874		{
1875			atomic_inc(&gDmaStatMemTypeKmalloc);
1876
1877			/* kmalloc'd pages are physically contiguous, so they'll have exactly */
1878			/* one segment */
1879
1880#if ALLOW_MAP_OF_KMALLOC_MEMORY
1881			physAddr =
1882			    dma_map_single(NULL, mem, numBytes, memMap->dir);
1883			rc = dma_map_add_segment(memMap, region, mem, physAddr,
1884						 numBytes);
1885#else
1886			rc = -EINVAL;
1887#endif
1888			break;
1889		}
1890
1891	case DMA_MEM_TYPE_DMA:
1892		{
1893			/* dma_alloc_xxx pages are physically contiguous */
1894
1895			atomic_inc(&gDmaStatMemTypeCoherent);
1896
1897			physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
1898
1899			dma_sync_single_for_cpu(NULL, physAddr, numBytes,
1900						memMap->dir);
1901			rc = dma_map_add_segment(memMap, region, mem, physAddr,
1902						 numBytes);
1903			break;
1904		}
1905
1906	case DMA_MEM_TYPE_USER:
1907		{
1908			size_t firstPageOffset;
1909			size_t firstPageSize;
1910			struct page **pages;
1911			struct task_struct *userTask;
1912
1913			atomic_inc(&gDmaStatMemTypeUser);
1914
1915			/* If the pages are user pages, then the dma_mem_map_set_user_task function */
1916			/* must have been previously called. */
1917
1918			if (memMap->userTask == NULL) {
1919				printk(KERN_ERR
1920				       "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
1921				       __func__);
1922				return -EINVAL;
1923			}
1924
1925			/* User pages need to be locked. */
1926
1927			firstPageOffset =
1928			    (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
1929			firstPageSize = PAGE_SIZE - firstPageOffset;
1930
1931			region->numLockedPages = (firstPageOffset
1932						  + region->numBytes +
1933						  PAGE_SIZE - 1) / PAGE_SIZE;
1934			pages =
1935			    kmalloc(region->numLockedPages *
1936				    sizeof(struct page *), GFP_KERNEL);
1937
1938			if (pages == NULL) {
1939				region->numLockedPages = 0;
1940				return -ENOMEM;
1941			}
1942
1943			userTask = memMap->userTask;
1944
1945			down_read(&userTask->mm->mmap_sem);
1946			rc = get_user_pages(userTask,	/* task */
1947					    userTask->mm,	/* mm */
1948					    (unsigned long)region->virtAddr,	/* start */
1949					    region->numLockedPages,	/* len */
1950					    memMap->dir == DMA_FROM_DEVICE,	/* write */
1951					    0,	/* force */
1952					    pages,	/* pages (array of pointers to page) */
1953					    NULL);	/* vmas */
1954			up_read(&userTask->mm->mmap_sem);
1955
1956			if (rc != region->numLockedPages) {
1957				kfree(pages);
1958				region->numLockedPages = 0;
1959
1960				if (rc >= 0) {
1961					rc = -EINVAL;
1962				}
1963			} else {
1964				uint8_t *virtAddr = region->virtAddr;
1965				size_t bytesRemaining;
1966				int pageIdx;
1967
1968				rc = 0;	/* Since get_user_pages returns +ve number */
1969
1970				region->lockedPages = pages;
1971
1972				/* We've locked the user pages. Now we need to walk them and figure */
1973				/* out the physical addresses. */
1974
1975				/* The first page may be partial */
1976
1977				dma_map_add_segment(memMap,
1978						    region,
1979						    virtAddr,
1980						    PFN_PHYS(page_to_pfn
1981							     (pages[0])) +
1982						    firstPageOffset,
1983						    firstPageSize);
1984
1985				virtAddr += firstPageSize;
1986				bytesRemaining =
1987				    region->numBytes - firstPageSize;
1988
1989				for (pageIdx = 1;
1990				     pageIdx < region->numLockedPages;
1991				     pageIdx++) {
1992					size_t bytesThisPage =
1993					    (bytesRemaining >
1994					     PAGE_SIZE ? PAGE_SIZE :
1995					     bytesRemaining);
1996
1997					DMA_MAP_PRINT
1998					    ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
1999					     pageIdx, pages[pageIdx],
2000					     page_to_pfn(pages[pageIdx]),
2001					     PFN_PHYS(page_to_pfn
2002						      (pages[pageIdx])));
2003
2004					dma_map_add_segment(memMap,
2005							    region,
2006							    virtAddr,
2007							    PFN_PHYS(page_to_pfn
2008								     (pages
2009								      [pageIdx])),
2010							    bytesThisPage);
2011
2012					virtAddr += bytesThisPage;
2013					bytesRemaining -= bytesThisPage;
2014				}
2015			}
2016			break;
2017		}
2018
2019	default:
2020		{
2021			printk(KERN_ERR "%s: Unsupported memory type: %d\n",
2022			       __func__, region->memType);
2023
2024			rc = -EINVAL;
2025			break;
2026		}
2027	}
2028
2029	if (rc != 0) {
2030		memMap->numRegionsUsed--;
2031	}
2032
2033out:
2034
2035	DMA_MAP_PRINT("returning %d\n", rc);
2036
2037	up(&memMap->lock);
2038
2039	return rc;
2040}
2041
2042EXPORT_SYMBOL(dma_map_add_segment);
2043
2044/****************************************************************************/
2045/**
2046*   Maps in a memory region such that it can be used for performing a DMA.
2047*
2048*   @return     0 on success, error code otherwise.
2049*/
2050/****************************************************************************/
2051
2052int dma_map_mem(DMA_MemMap_t *memMap,	/* Stores state information about the map */
2053		void *mem,	/* Virtual address that we want to get a map of */
2054		size_t numBytes,	/* Number of bytes being mapped */
2055		enum dma_data_direction dir	/* Direction that the mapping will be going */
2056    ) {
2057	int rc;
2058
2059	rc = dma_map_start(memMap, dir);
2060	if (rc == 0) {
2061		rc = dma_map_add_region(memMap, mem, numBytes);
2062		if (rc < 0) {
2063			/* Since the add fails, this function will fail, and the caller won't */
2064			/* call unmap, so we need to do it here. */
2065
2066			dma_unmap(memMap, 0);
2067		}
2068	}
2069
2070	return rc;
2071}
2072
2073EXPORT_SYMBOL(dma_map_mem);
2074
2075/****************************************************************************/
2076/**
2077*   Setup a descriptor ring for a given memory map.
2078*
2079*   It is assumed that the descriptor ring has already been initialized, and
2080*   this routine will only reallocate a new descriptor ring if the existing
2081*   one is too small.
2082*
2083*   @return     0 on success, error code otherwise.
2084*/
2085/****************************************************************************/
2086
2087int dma_map_create_descriptor_ring(DMA_Device_t dev,	/* DMA device (where the ring is stored) */
2088				   DMA_MemMap_t *memMap,	/* Memory map that will be used */
2089				   dma_addr_t devPhysAddr	/* Physical address of device */
2090    ) {
2091	int rc;
2092	int numDescriptors;
2093	DMA_DeviceAttribute_t *devAttr;
2094	DMA_Region_t *region;
2095	DMA_Segment_t *segment;
2096	dma_addr_t srcPhysAddr;
2097	dma_addr_t dstPhysAddr;
2098	int regionIdx;
2099	int segmentIdx;
2100
2101	devAttr = &DMA_gDeviceAttribute[dev];
2102
2103	down(&memMap->lock);
2104
2105	/* Figure out how many descriptors we need */
2106
2107	numDescriptors = 0;
2108	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2109		region = &memMap->region[regionIdx];
2110
2111		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2112		     segmentIdx++) {
2113			segment = &region->segment[segmentIdx];
2114
2115			if (memMap->dir == DMA_TO_DEVICE) {
2116				srcPhysAddr = segment->physAddr;
2117				dstPhysAddr = devPhysAddr;
2118			} else {
2119				srcPhysAddr = devPhysAddr;
2120				dstPhysAddr = segment->physAddr;
2121			}
2122
2123			rc =
2124			     dma_calculate_descriptor_count(dev, srcPhysAddr,
2125							    dstPhysAddr,
2126							    segment->
2127							    numBytes);
2128			if (rc < 0) {
2129				printk(KERN_ERR
2130				       "%s: dma_calculate_descriptor_count failed: %d\n",
2131				       __func__, rc);
2132				goto out;
2133			}
2134			numDescriptors += rc;
2135		}
2136	}
2137
2138	/* Adjust the size of the ring, if it isn't big enough */
2139
2140	if (numDescriptors > devAttr->ring.descriptorsAllocated) {
2141		dma_free_descriptor_ring(&devAttr->ring);
2142		rc =
2143		     dma_alloc_descriptor_ring(&devAttr->ring,
2144					       numDescriptors);
2145		if (rc < 0) {
2146			printk(KERN_ERR
2147			       "%s: dma_alloc_descriptor_ring failed: %d\n",
2148			       __func__, rc);
2149			goto out;
2150		}
2151	} else {
2152		rc =
2153		     dma_init_descriptor_ring(&devAttr->ring,
2154					      numDescriptors);
2155		if (rc < 0) {
2156			printk(KERN_ERR
2157			       "%s: dma_init_descriptor_ring failed: %d\n",
2158			       __func__, rc);
2159			goto out;
2160		}
2161	}
2162
2163	/* Populate the descriptors */
2164
2165	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2166		region = &memMap->region[regionIdx];
2167
2168		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2169		     segmentIdx++) {
2170			segment = &region->segment[segmentIdx];
2171
2172			if (memMap->dir == DMA_TO_DEVICE) {
2173				srcPhysAddr = segment->physAddr;
2174				dstPhysAddr = devPhysAddr;
2175			} else {
2176				srcPhysAddr = devPhysAddr;
2177				dstPhysAddr = segment->physAddr;
2178			}
2179
2180			rc =
2181			     dma_add_descriptors(&devAttr->ring, dev,
2182						 srcPhysAddr, dstPhysAddr,
2183						 segment->numBytes);
2184			if (rc < 0) {
2185				printk(KERN_ERR
2186				       "%s: dma_add_descriptors failed: %d\n",
2187				       __func__, rc);
2188				goto out;
2189			}
2190		}
2191	}
2192
2193	rc = 0;
2194
2195out:
2196
2197	up(&memMap->lock);
2198	return rc;
2199}
2200
2201EXPORT_SYMBOL(dma_map_create_descriptor_ring);
2202
2203/****************************************************************************/
2204/**
2205*   Maps in a memory region such that it can be used for performing a DMA.
2206*
2207*   @return
2208*/
2209/****************************************************************************/
2210
2211int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
2212	      int dirtied	/* non-zero if any of the pages were modified */
2213    ) {
2214
2215	int rc = 0;
2216	int regionIdx;
2217	int segmentIdx;
2218	DMA_Region_t *region;
2219	DMA_Segment_t *segment;
2220
2221	down(&memMap->lock);
2222
2223	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2224		region = &memMap->region[regionIdx];
2225
2226		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2227		     segmentIdx++) {
2228			segment = &region->segment[segmentIdx];
2229
2230			switch (region->memType) {
2231			case DMA_MEM_TYPE_VMALLOC:
2232				{
2233					printk(KERN_ERR
2234					       "%s: vmalloc'd pages are not yet supported\n",
2235					       __func__);
2236					rc = -EINVAL;
2237					goto out;
2238				}
2239
2240			case DMA_MEM_TYPE_KMALLOC:
2241				{
2242#if ALLOW_MAP_OF_KMALLOC_MEMORY
2243					dma_unmap_single(NULL,
2244							 segment->physAddr,
2245							 segment->numBytes,
2246							 memMap->dir);
2247#endif
2248					break;
2249				}
2250
2251			case DMA_MEM_TYPE_DMA:
2252				{
2253					dma_sync_single_for_cpu(NULL,
2254								segment->
2255								physAddr,
2256								segment->
2257								numBytes,
2258								memMap->dir);
2259					break;
2260				}
2261
2262			case DMA_MEM_TYPE_USER:
2263				{
2264					/* Nothing to do here. */
2265
2266					break;
2267				}
2268
2269			default:
2270				{
2271					printk(KERN_ERR
2272					       "%s: Unsupported memory type: %d\n",
2273					       __func__, region->memType);
2274					rc = -EINVAL;
2275					goto out;
2276				}
2277			}
2278
2279			segment->virtAddr = NULL;
2280			segment->physAddr = 0;
2281			segment->numBytes = 0;
2282		}
2283
2284		if (region->numLockedPages > 0) {
2285			int pageIdx;
2286
2287			/* Some user pages were locked. We need to go and unlock them now. */
2288
2289			for (pageIdx = 0; pageIdx < region->numLockedPages;
2290			     pageIdx++) {
2291				struct page *page =
2292				    region->lockedPages[pageIdx];
2293
2294				if (memMap->dir == DMA_FROM_DEVICE) {
2295					SetPageDirty(page);
2296				}
2297				page_cache_release(page);
2298			}
2299			kfree(region->lockedPages);
2300			region->numLockedPages = 0;
2301			region->lockedPages = NULL;
2302		}
2303
2304		region->memType = DMA_MEM_TYPE_NONE;
2305		region->virtAddr = NULL;
2306		region->numBytes = 0;
2307		region->numSegmentsUsed = 0;
2308	}
2309	memMap->userTask = NULL;
2310	memMap->numRegionsUsed = 0;
2311	memMap->inUse = 0;
2312
2313out:
2314	up(&memMap->lock);
2315
2316	return rc;
2317}
2318
2319EXPORT_SYMBOL(dma_unmap);
2320