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

📄 scsi_dma.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  scsi_dma.c Copyright (C) 2000 Eric Youngdale * *  mid-level SCSI DMA bounce buffer allocator * */#define __NO_VERSION__#include <linux/config.h>#include <linux/module.h>#include <linux/blk.h>#include "scsi.h"#include "hosts.h"#include "constants.h"#ifdef CONFIG_KMOD#include <linux/kmod.h>#endif/* * PAGE_SIZE must be a multiple of the sector size (512).  True * for all reasonably recent architectures (even the VAX...). */#define SECTOR_SIZE		512#define SECTORS_PER_PAGE	(PAGE_SIZE/SECTOR_SIZE)#if SECTORS_PER_PAGE <= 8typedef unsigned char FreeSectorBitmap;#elif SECTORS_PER_PAGE <= 32typedef unsigned int FreeSectorBitmap;#elif SECTORS_PER_PAGE <= 64#if 0typedef unsigned long long FreeSectorBitmap;#elsetypedef struct {	unsigned long l,h;} FreeSectorBitmap;#define LARGE_MALLOC#endif#else#error You lose.#endif/* * Used for access to internal allocator used for DMA safe buffers. */static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED;static FreeSectorBitmap *dma_malloc_freelist = NULL;static int need_isa_bounce_buffers;static unsigned int dma_sectors = 0;unsigned int scsi_dma_free_sectors = 0;unsigned int scsi_need_isa_buffer = 0;static unsigned char **dma_malloc_pages = NULL;/* * Function:    scsi_malloc * * Purpose:     Allocate memory from the DMA-safe pool. * * Arguments:   len       - amount of memory we need. * * Lock status: No locks assumed to be held.  This function is SMP-safe. * * Returns:     Pointer to memory block. * * Notes:       Prior to the new queue code, this function was not SMP-safe. *              This function can only allocate in units of sectors *              (i.e. 512 bytes). * *              We cannot use the normal system allocator becuase we need *              to be able to guarantee that we can process a complete disk *              I/O request without touching the system allocator.  Think *              about it - if the system were heavily swapping, and tried to *              write out a block of memory to disk, and the SCSI code needed *              to allocate more memory in order to be able to write the *              data to disk, you would wedge the system. */#ifndef LARGE_MALLOCvoid *scsi_malloc(unsigned int len){	unsigned int nbits, mask;	unsigned long flags;	int i, j;	if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)		return NULL;	nbits = len >> 9;	mask = (1 << nbits) - 1;	spin_lock_irqsave(&allocator_request_lock, flags);	for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)		for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) {			if ((dma_malloc_freelist[i] & (mask << j)) == 0) {				dma_malloc_freelist[i] |= (mask << j);				scsi_dma_free_sectors -= nbits;#ifdef DEBUG				SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)));				printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9));#endif				spin_unlock_irqrestore(&allocator_request_lock, flags);				return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));			}		}	spin_unlock_irqrestore(&allocator_request_lock, flags);	return NULL;		/* Nope.  No more */}/* * Function:    scsi_free * * Purpose:     Free memory into the DMA-safe pool. * * Arguments:   ptr       - data block we are freeing. *              len       - size of block we are freeing. * * Lock status: No locks assumed to be held.  This function is SMP-safe. * * Returns:     Nothing * * Notes:       This function *must* only be used to free memory *              allocated from scsi_malloc(). * *              Prior to the new queue code, this function was not SMP-safe. *              This function can only allocate in units of sectors *              (i.e. 512 bytes). */int scsi_free(void *obj, unsigned int len){	unsigned int page, sector, nbits, mask;	unsigned long flags;#ifdef DEBUG	unsigned long ret = 0;#ifdef __mips__	__asm__ __volatile__("move\t%0,$31":"=r"(ret));#else	ret = __builtin_return_address(0);#endif	printk("scsi_free %p %d\n", obj, len);	SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len));#endif	spin_lock_irqsave(&allocator_request_lock, flags);	for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {		unsigned long page_addr = (unsigned long) dma_malloc_pages[page];		if ((unsigned long) obj >= page_addr &&		    (unsigned long) obj < page_addr + PAGE_SIZE) {			sector = (((unsigned long) obj) - page_addr) >> 9;			nbits = len >> 9;			mask = (1 << nbits) - 1;			if (sector + nbits > SECTORS_PER_PAGE)				panic("scsi_free:Bad memory alignment");			if ((dma_malloc_freelist[page] &			     (mask << sector)) != (mask << sector)) {#ifdef DEBUG				printk("scsi_free(obj=%p, len=%d) called from %08lx\n",				       obj, len, ret);#endif				panic("scsi_free:Trying to free unused memory");			}			scsi_dma_free_sectors += nbits;			dma_malloc_freelist[page] &= ~(mask << sector);			spin_unlock_irqrestore(&allocator_request_lock, flags);			return 0;		}	}	panic("scsi_free:Bad offset");}#elsevoid *scsi_malloc(unsigned int len){	unsigned int nbits;	unsigned long maskl, maskh, flags;	FreeSectorBitmap *fsb;	int i;	if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)		return NULL;	save_flags_cli (flags);	nbits = len >> 9;	if (nbits < 32) {		maskl = (1 << nbits) - 1;		maskh = 0;	} else {		maskl = (unsigned long)-1;		maskh = (1 << (nbits - 32)) - 1;	}	fsb = dma_malloc_freelist;	for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) {		unsigned long mml, mmh;		int j;		mml = maskl;		mmh = maskh;		j = 0;		do {			if ((fsb->l & mml) == 0 && (fsb->h & mmh) == 0) {				fsb->h |= mmh;				fsb->l |= mml;				restore_flags (flags);				scsi_dma_free_sectors -= nbits;#ifdef DEBUG				printk("SMalloc: %d %p\n",len, dma_malloc_pages[i] + (j << 9));#endif				return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));			}			mmh = (mmh << 1) | (mml >> 31);			mml <<= 1;			j++;		} while (!(mmh & (1 << 31)));		fsb ++;	}	return NULL;  /* Nope.  No more */}int scsi_free(void *obj, unsigned int len){	unsigned int page, sector, nbits;	unsigned long maskl, maskh, flags;#ifdef DEBUG	printk("scsi_free %p %d\n",obj, len);#endif	for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {		unsigned long page_addr = (unsigned long) dma_malloc_pages[page];		if ((unsigned long) obj >= page_addr &&		    (unsigned long) obj < page_addr + PAGE_SIZE) {			sector = (((unsigned long) obj) - page_addr) >> 9;			nbits = len >> 9;			if (nbits < 32) {				maskl = (1 << nbits) - 1;				maskh = 0;			} else {				maskl = (unsigned long)-1;				maskh = (1 << (nbits - 32)) - 1;			}			if ((sector + nbits) > SECTORS_PER_PAGE)				panic ("scsi_free:Bad memory alignment");			maskh = (maskh << sector) | (maskl >> (32 - sector));			maskl = maskl << sector;			save_flags_cli(flags);			if (((dma_malloc_freelist[page].l & maskl) != maskl) ||			    ((dma_malloc_freelist[page].h & maskh) != maskh))				panic("scsi_free:Trying to free unused memory");			scsi_dma_free_sectors += nbits;			dma_malloc_freelist[page].l &= ~maskl;			dma_malloc_freelist[page].h &= ~maskh;			restore_flags(flags);			return 0;		}	}	panic("scsi_free:Bad offset");}#endif/* * Function:    scsi_resize_dma_pool * * Purpose:     Ensure that the DMA pool is sufficiently large to be *              able to guarantee that we can always process I/O requests *              without calling the system allocator.

⌨️ 快捷键说明

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