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

📄 stram.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* * free a reserved region in ST-RAM swap space */static void free_stram_region( unsigned long offset, unsigned long n_pages ){	unsigned short *map = stram_swap_info->swap_map;	DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );	if (offset < 1 || offset + n_pages > stram_swap_info->max) {		printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );		return;	}	swap_list_lock();	swap_device_lock(stram_swap_info);	/* un-reserve the freed pages */	for( ; n_pages > 0; ++offset, --n_pages ) {		if (map[offset] != SWAP_MAP_BAD)			printk( KERN_ERR "free_stram_region: Swap page %lu was not "					"reserved\n", offset );		map[offset] = 0;	}	/* update swapping meta-data */	if (offset < stram_swap_info->lowest_bit)		stram_swap_info->lowest_bit = offset;	if (offset+n_pages-1 > stram_swap_info->highest_bit)		stram_swap_info->highest_bit = offset+n_pages-1;	if (stram_swap_info->prio > swap_info[swap_list.next].prio)		swap_list.next = swap_list.head;	nr_swap_pages += n_pages;	swap_device_unlock(stram_swap_info);	swap_list_unlock();}/* ------------------------------------------------------------------------ *//*						Utility Functions for Swapping						*//* ------------------------------------------------------------------------ *//* is addr in some of the allocated regions? */static int in_some_region(void *addr){	BLOCK *p;		for( p = alloc_list; p; p = p->next ) {		if (p->start <= addr && addr < p->start + p->size)			return( 1 );	}	return( 0 );}static unsigned long find_free_region(unsigned long n_pages,				      unsigned long *total_free,				      unsigned long *region_free){	unsigned short *map = stram_swap_info->swap_map;	unsigned long max = stram_swap_info->max;	unsigned long head, tail, max_start;	long nfree, max_free;	/* first scan the swap space for a suitable place for the allocation */	head = 1;	max_start = 0;	max_free = -1;	*total_free = 0;  start_over:	/* increment tail until final window size reached, and count free pages */	nfree = 0;	for( tail = head; tail-head < n_pages && tail < max; ++tail ) {		if (map[tail] == SWAP_MAP_BAD) {			head = tail+1;			goto start_over;		}		if (!map[tail]) {			++nfree;			++*total_free;		}	}	if (tail-head < n_pages)		goto out;	if (nfree > max_free) {		max_start = head;		max_free  = nfree;		if (max_free >= n_pages)			/* don't need more free pages... :-) */			goto out;	}		/* now shift the window and look for the area where as much pages as	 * possible are free */	while( tail < max ) {		nfree -= (map[head++] == 0);		if (map[tail] == SWAP_MAP_BAD) {			head = tail+1;			goto start_over;		}		if (!map[tail]) {			++nfree;			++*total_free;		}		++tail;		if (nfree > max_free) {			max_start = head;			max_free  = nfree;			if (max_free >= n_pages)				/* don't need more free pages... :-) */				goto out;		}	}  out:	if (max_free < 0) {		printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "				"-- can't allocate %lu pages\n", n_pages );		return( 0 );	}	*region_free = max_free;	return( max_start );}/* setup parameters from command line */void __init stram_swap_setup(char *str, int *ints){	if (ints[0] >= 1)		max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;}/* ------------------------------------------------------------------------ *//*								ST-RAM device								*//* ------------------------------------------------------------------------ */static int stram_blocksizes[14] = {	0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 4096 };static int stram_sizes[14] = {	0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0 };static int refcnt = 0;static void do_stram_request(request_queue_t *q){	void *start;	unsigned long len;	while (1) {		INIT_REQUEST;				start = swap_start + (CURRENT->sector << 9);		len   = CURRENT->current_nr_sectors << 9;		if ((start + len) > swap_end) {			printk( KERN_ERR "stram: bad access beyond end of device: "					"block=%ld, count=%ld\n",					CURRENT->sector,					CURRENT->current_nr_sectors );			end_request( 0 );			continue;		}		if (CURRENT->cmd == READ) {			memcpy(CURRENT->buffer, start, len);#ifdef DO_PROC			stat_swap_read += N_PAGES(len);#endif		}		else {			memcpy(start, CURRENT->buffer, len);#ifdef DO_PROC			stat_swap_write += N_PAGES(len);#endif		}		end_request( 1 );	}}static int stram_open( struct inode *inode, struct file *filp ){	if (filp != MAGIC_FILE_P) {		printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );		return( -EPERM );	}	if (MINOR(inode->i_rdev) != STRAM_MINOR)		return( -ENXIO );	if (refcnt)		return( -EBUSY );	++refcnt;	return( 0 );}static int stram_release( struct inode *inode, struct file *filp ){	if (filp != MAGIC_FILE_P) {		printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );		return( -EPERM );	}	if (refcnt > 0)		--refcnt;	return( 0 );}static struct block_device_operations stram_fops = {	open:		stram_open,	release:	stram_release,};int __init stram_device_init(void){    if (!MACH_IS_ATARI)    	/* no point in initializing this, I hope */	return( -ENXIO );    if (!max_swap_size)	/* swapping not enabled */	return( -ENXIO );	    if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) {	printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );	return( -ENXIO );    }    blk_init_queue(BLK_DEFAULT_QUEUE(STRAM_MAJOR), do_stram_request);    blksize_size[STRAM_MAJOR] = stram_blocksizes;	stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;    blk_size[STRAM_MAJOR] = stram_sizes;	register_disk(NULL, MKDEV(STRAM_MAJOR, STRAM_MINOR), 1, &stram_fops,			(swap_end-swap_start)>>9);	return( 0 );}/* ------------------------------------------------------------------------ *//*							Misc Utility Functions							*//* ------------------------------------------------------------------------ *//* reserve a range of pages */static void reserve_region(void *start, void *end){	reserve_bootmem (virt_to_phys(start), end - start);}#endif /* CONFIG_STRAM_SWAP *//* ------------------------------------------------------------------------ *//*							  Region Management								*//* ------------------------------------------------------------------------ *//* insert a region into the alloced list (sorted) */static BLOCK *add_region( void *addr, unsigned long size ){	BLOCK **p, *n = NULL;	int i;	for( i = 0; i < N_STATIC_BLOCKS; ++i ) {		if (static_blocks[i].flags & BLOCK_FREE) {			n = &static_blocks[i];			n->flags = 0;			break;		}	}	if (!n && mem_init_done) {		/* if statics block pool exhausted and we can call kmalloc() already		 * (after mem_init()), try that */		n = kmalloc( sizeof(BLOCK), GFP_KERNEL );		if (n)			n->flags = BLOCK_KMALLOCED;	}	if (!n) {		printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );		return( NULL );	}	n->start = addr;	n->size  = size;	for( p = &alloc_list; *p; p = &((*p)->next) )		if ((*p)->start > addr) break;	n->next = *p;	*p = n;	return( n );}/* find a region (by start addr) in the alloced list */static BLOCK *find_region( void *addr ){	BLOCK *p;		for( p = alloc_list; p; p = p->next ) {		if (p->start == addr)			return( p );		if (p->start > addr)			break;	}	return( NULL );}/* remove a block from the alloced list */static int remove_region( BLOCK *block ){	BLOCK **p;		for( p = &alloc_list; *p; p = &((*p)->next) )		if (*p == block) break;	if (!*p)		return( 0 );	*p = block->next;	if (block->flags & BLOCK_KMALLOCED)		kfree( block );	else		block->flags |= BLOCK_FREE;	return( 1 );}/* ------------------------------------------------------------------------ *//*						 /proc statistics file stuff						*//* ------------------------------------------------------------------------ */#ifdef DO_PROC#define	PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )int get_stram_list( char *buf ){	int len = 0;	BLOCK *p;#ifdef CONFIG_STRAM_SWAP	int i;	unsigned short *map = stram_swap_info->swap_map;	unsigned long max = stram_swap_info->max;	unsigned free = 0, used = 0, rsvd = 0;#endif#ifdef CONFIG_STRAM_SWAP	if (max_swap_size) {		for( i = 1; i < max; ++i ) {			if (!map[i])				++free;			else if (map[i] == SWAP_MAP_BAD)				++rsvd;			else				++used;		}		PRINT_PROC(			"Total ST-RAM:      %8u kB\n"			"Total ST-RAM swap: %8lu kB\n"			"Free swap:         %8u kB\n"			"Used swap:         %8u kB\n"			"Allocated swap:    %8u kB\n"			"Swap Reads:        %8u\n"			"Swap Writes:       %8u\n"			"Swap Forced Reads: %8u\n",			(stram_end - stram_start) >> 10,			(max-1) << (PAGE_SHIFT-10),			free << (PAGE_SHIFT-10),			used << (PAGE_SHIFT-10),			rsvd << (PAGE_SHIFT-10),			stat_swap_read,			stat_swap_write,			stat_swap_force );	}	else {#endif		PRINT_PROC( "ST-RAM swapping disabled\n" );		PRINT_PROC("Total ST-RAM:      %8u kB\n",			   (stram_end - stram_start) >> 10);#ifdef CONFIG_STRAM_SWAP	}#endif	PRINT_PROC( "Allocated regions:\n" );	for( p = alloc_list; p; p = p->next ) {		if (len + 50 >= PAGE_SIZE)			break;		PRINT_PROC("0x%08lx-0x%08lx: %s (",			   virt_to_phys(p->start),			   virt_to_phys(p->start+p->size-1),			   p->owner);		if (p->flags & BLOCK_GFP)			PRINT_PROC( "page-alloced)\n" );		else if (p->flags & BLOCK_INSWAP)			PRINT_PROC( "in swap)\n" );		else			PRINT_PROC( "??)\n" );	}	return( len );}#endif/* * Local variables: *  c-indent-level: 4 *  tab-width: 4 * End: */

⌨️ 快捷键说明

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