z2ram.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. ** z2ram - Amiga pseudo-driver to access 16bit-RAM in ZorroII space
  3. **         as a block device, to be used as a RAM disk or swap space
  4. ** 
  5. ** Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
  6. **
  7. ** ++Geert: support for zorro_unused_z2ram, better range checking
  8. ** ++roman: translate accesses via an array
  9. ** ++Milan: support for ChipRAM usage
  10. ** ++yambo: converted to 2.0 kernel
  11. ** ++yambo: modularized and support added for 3 minor devices including:
  12. **          MAJOR  MINOR  DESCRIPTION
  13. **          -----  -----  ----------------------------------------------
  14. **          37     0       Use Zorro II and Chip ram
  15. **          37     1       Use only Zorro II ram
  16. **          37     2       Use only Chip ram
  17. **          37     4-7     Use memory list entry 1-4 (first is 0)
  18. ** ++jskov: support for 1-4th memory list entry.
  19. **
  20. ** Permission to use, copy, modify, and distribute this software and its
  21. ** documentation for any purpose and without fee is hereby granted, provided
  22. ** that the above copyright notice appear in all copies and that both that
  23. ** copyright notice and this permission notice appear in supporting
  24. ** documentation.  This software is provided "as is" without express or
  25. ** implied warranty.
  26. */
  27. #define MAJOR_NR    Z2RAM_MAJOR
  28. #include <linux/major.h>
  29. #include <linux/slab.h>
  30. #include <linux/vmalloc.h>
  31. #include <linux/blk.h>
  32. #include <linux/init.h>
  33. #include <linux/module.h>
  34. #include <asm/setup.h>
  35. #include <asm/bitops.h>
  36. #include <asm/amigahw.h>
  37. #include <asm/pgtable.h>
  38. #include <linux/zorro.h>
  39. extern int m68k_realnum_memory;
  40. extern struct mem_info m68k_memory[NUM_MEMINFO];
  41. #define TRUE                  (1)
  42. #define FALSE                 (0)
  43. #define Z2MINOR_COMBINED      (0)
  44. #define Z2MINOR_Z2ONLY        (1)
  45. #define Z2MINOR_CHIPONLY      (2)
  46. #define Z2MINOR_MEMLIST1      (4)
  47. #define Z2MINOR_MEMLIST2      (5)
  48. #define Z2MINOR_MEMLIST3      (6)
  49. #define Z2MINOR_MEMLIST4      (7)
  50. #define Z2MINOR_COUNT         (8) /* Move this down when adding a new minor */
  51. #define Z2RAM_CHUNK1024       ( Z2RAM_CHUNKSIZE >> 10 )
  52. static u_long *z2ram_map    = NULL;
  53. static u_long z2ram_size    = 0;
  54. static int z2_blocksizes[Z2MINOR_COUNT];
  55. static int z2_sizes[Z2MINOR_COUNT];
  56. static int z2_count         = 0;
  57. static int chip_count       = 0;
  58. static int list_count       = 0;
  59. static int current_device   = -1;
  60. static void
  61. do_z2_request( request_queue_t * q )
  62. {
  63.     u_long start, len, addr, size;
  64.     while ( TRUE )
  65.     {
  66. INIT_REQUEST;
  67. start = CURRENT->sector << 9;
  68. len  = CURRENT->current_nr_sectors << 9;
  69. if ( ( start + len ) > z2ram_size )
  70. {
  71.     printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ldn",
  72. CURRENT->sector,
  73. CURRENT->current_nr_sectors);
  74.     end_request( FALSE );
  75.     continue;
  76. }
  77. if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) )
  78. {
  79.     printk( KERN_ERR DEVICE_NAME ": bad command: %dn", CURRENT->cmd );
  80.     end_request( FALSE );
  81.     continue;
  82. }
  83. while ( len ) 
  84. {
  85.     addr = start & Z2RAM_CHUNKMASK;
  86.     size = Z2RAM_CHUNKSIZE - addr;
  87.     if ( len < size )
  88. size = len;
  89.     addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
  90.     if ( CURRENT->cmd == READ )
  91. memcpy( CURRENT->buffer, (char *)addr, size );
  92.     else
  93. memcpy( (char *)addr, CURRENT->buffer, size );
  94.     start += size;
  95.     len -= size;
  96. }
  97. end_request( TRUE );
  98.     }
  99. }
  100. static void
  101. get_z2ram( void )
  102. {
  103.     int i;
  104.     for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ )
  105.     {
  106. if ( test_bit( i, zorro_unused_z2ram ) )
  107. {
  108.     z2_count++;
  109.     z2ram_map[ z2ram_size++ ] = 
  110. ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
  111.     clear_bit( i, zorro_unused_z2ram );
  112. }
  113.     }
  114.     return;
  115. }
  116. static void
  117. get_chipram( void )
  118. {
  119.     while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) )
  120.     {
  121. chip_count++;
  122. z2ram_map[ z2ram_size ] =
  123.     (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" );
  124. if ( z2ram_map[ z2ram_size ] == 0 )
  125. {
  126.     break;
  127. }
  128. z2ram_size++;
  129.     }
  130.     return;
  131. }
  132. static int
  133. z2_open( struct inode *inode, struct file *filp )
  134. {
  135.     int device;
  136.     int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
  137. sizeof( z2ram_map[0] );
  138.     int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
  139. sizeof( z2ram_map[0] );
  140.     int rc = -ENOMEM;
  141.     device = DEVICE_NR( inode->i_rdev );
  142.     if ( current_device != -1 && current_device != device )
  143.     {
  144. rc = -EBUSY;
  145. goto err_out;
  146.     }
  147.     if ( current_device == -1 )
  148.     {
  149. z2_count   = 0;
  150. chip_count = 0;
  151. list_count = 0;
  152. z2ram_size = 0;
  153. /* Use a specific list entry. */
  154. if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) {
  155. int index = device - Z2MINOR_MEMLIST1 + 1;
  156. unsigned long size, paddr, vaddr;
  157. if (index >= m68k_realnum_memory) {
  158. printk( KERN_ERR DEVICE_NAME
  159. ": no such entry in z2ram_mapn" );
  160.         goto err_out;
  161. }
  162. paddr = m68k_memory[index].addr;
  163. size = m68k_memory[index].size & ~(Z2RAM_CHUNKSIZE-1);
  164. #ifdef __powerpc__
  165. /* FIXME: ioremap doesn't build correct memory tables. */
  166. {
  167. vfree(vmalloc (size));
  168. }
  169. vaddr = (unsigned long) __ioremap (paddr, size, 
  170.    _PAGE_WRITETHRU);
  171. #else
  172. vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size);
  173. #endif
  174. z2ram_map = 
  175. kmalloc((size/Z2RAM_CHUNKSIZE)*sizeof(z2ram_map[0]),
  176. GFP_KERNEL);
  177. if ( z2ram_map == NULL )
  178. {
  179.     printk( KERN_ERR DEVICE_NAME
  180. ": cannot get mem for z2ram_mapn" );
  181.     goto err_out;
  182. }
  183. while (size) {
  184. z2ram_map[ z2ram_size++ ] = vaddr;
  185. size -= Z2RAM_CHUNKSIZE;
  186. vaddr += Z2RAM_CHUNKSIZE;
  187. list_count++;
  188. }
  189. if ( z2ram_size != 0 )
  190.     printk( KERN_INFO DEVICE_NAME
  191. ": using %iK List Entry %d Memoryn",
  192. list_count * Z2RAM_CHUNK1024, index );
  193. } else
  194. switch ( device )
  195. {
  196.     case Z2MINOR_COMBINED:
  197. z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
  198. if ( z2ram_map == NULL )
  199. {
  200.     printk( KERN_ERR DEVICE_NAME
  201. ": cannot get mem for z2ram_mapn" );
  202.     goto err_out;
  203. }
  204. get_z2ram();
  205. get_chipram();
  206. if ( z2ram_size != 0 )
  207.     printk( KERN_INFO DEVICE_NAME 
  208. ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)n",
  209. z2_count * Z2RAM_CHUNK1024,
  210. chip_count * Z2RAM_CHUNK1024,
  211. ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
  212.     break;
  213.          case Z2MINOR_Z2ONLY:
  214. z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
  215. if ( z2ram_map == NULL )
  216. {
  217.     printk( KERN_ERR DEVICE_NAME
  218. ": cannot get mem for z2ram_mapn" );
  219.     goto err_out;
  220. }
  221. get_z2ram();
  222. if ( z2ram_size != 0 )
  223.     printk( KERN_INFO DEVICE_NAME 
  224. ": using %iK of Zorro II RAMn",
  225. z2_count * Z2RAM_CHUNK1024 );
  226.     break;
  227.     case Z2MINOR_CHIPONLY:
  228. z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
  229. if ( z2ram_map == NULL )
  230. {
  231.     printk( KERN_ERR DEVICE_NAME
  232. ": cannot get mem for z2ram_mapn" );
  233.     goto err_out;
  234. }
  235. get_chipram();
  236. if ( z2ram_size != 0 )
  237.     printk( KERN_INFO DEVICE_NAME 
  238. ": using %iK Chip RAMn",
  239. chip_count * Z2RAM_CHUNK1024 );
  240.     
  241.     break;
  242.     default:
  243. rc = -ENODEV;
  244. goto err_out;
  245.     break;
  246. }
  247. if ( z2ram_size == 0 )
  248. {
  249.     printk( KERN_NOTICE DEVICE_NAME
  250. ": no unused ZII/Chip RAM foundn" );
  251.     goto err_out_kfree;
  252. }
  253. current_device = device;
  254. z2ram_size <<= Z2RAM_CHUNKSHIFT;
  255. z2_sizes[ device ] = z2ram_size >> 10;
  256. blk_size[ MAJOR_NR ] = z2_sizes;
  257.     }
  258.     return 0;
  259. err_out_kfree:
  260.     kfree( z2ram_map );
  261. err_out:
  262.     return rc;
  263. }
  264. static int
  265. z2_release( struct inode *inode, struct file *filp )
  266. {
  267.     if ( current_device == -1 )
  268. return 0;     
  269.     /*
  270.      * FIXME: unmap memory
  271.      */
  272.     return 0;
  273. }
  274. static struct block_device_operations z2_fops =
  275. {
  276. owner: THIS_MODULE,
  277. open: z2_open,
  278. release: z2_release,
  279. };
  280. int __init 
  281. z2_init( void )
  282. {
  283.     if ( !MACH_IS_AMIGA )
  284. return -ENXIO;
  285.     if ( register_blkdev( MAJOR_NR, DEVICE_NAME, &z2_fops ) )
  286.     {
  287. printk( KERN_ERR DEVICE_NAME ": Unable to get major %dn",
  288.     MAJOR_NR );
  289. return -EBUSY;
  290.     }
  291.     {
  292.     /* Initialize size arrays. */
  293.     int i;
  294.     for (i = 0; i < Z2MINOR_COUNT; i++) {
  295.     z2_blocksizes[ i ] = 1024;
  296.     z2_sizes[ i ] = 0;
  297.     }
  298.     }    
  299.    
  300.     blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
  301.     blksize_size[ MAJOR_NR ] = z2_blocksizes;
  302.     blk_size[ MAJOR_NR ] = z2_sizes;
  303.     return 0;
  304. }
  305. #if defined(MODULE)
  306. MODULE_LICENSE("GPL");
  307. int
  308. init_module( void )
  309. {
  310.     int error;
  311.     
  312.     error = z2_init();
  313.     if ( error == 0 )
  314.     {
  315. printk( KERN_INFO DEVICE_NAME ": loaded as modulen" );
  316.     }
  317.     
  318.     return error;
  319. }
  320. void
  321. cleanup_module( void )
  322. {
  323.     int i, j;
  324.     if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
  325. printk( KERN_ERR DEVICE_NAME ": unregister of device failedn");
  326.     blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
  327.     if ( current_device != -1 )
  328.     {
  329. i = 0;
  330. for ( j = 0 ; j < z2_count; j++ )
  331. {
  332.     set_bit( i++, zorro_unused_z2ram ); 
  333. }
  334. for ( j = 0 ; j < chip_count; j++ )
  335. {
  336.     if ( z2ram_map[ i ] )
  337.     {
  338. amiga_chip_free( (void *) z2ram_map[ i++ ] );
  339.     }
  340. }
  341. if ( z2ram_map != NULL )
  342. {
  343.     kfree( z2ram_map );
  344. }
  345.     }
  346.     return;
  347. #endif