z2ram.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

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