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 28#define DEVICE_NAME "Z2RAM" 29 30#include <linux/major.h> 31#include <linux/vmalloc.h> 32#include <linux/init.h> 33#include <linux/module.h> 34#include <linux/blkdev.h> 35#include <linux/bitops.h> 36 37#include <asm/setup.h> 38#include <asm/amigahw.h> 39#include <asm/pgtable.h> 40 41#include <linux/zorro.h> 42 43 44extern int m68k_realnum_memory; 45extern struct mem_info m68k_memory[NUM_MEMINFO]; 46 47#define TRUE (1) 48#define FALSE (0) 49 50#define Z2MINOR_COMBINED (0) 51#define Z2MINOR_Z2ONLY (1) 52#define Z2MINOR_CHIPONLY (2) 53#define Z2MINOR_MEMLIST1 (4) 54#define Z2MINOR_MEMLIST2 (5) 55#define Z2MINOR_MEMLIST3 (6) 56#define Z2MINOR_MEMLIST4 (7) 57#define Z2MINOR_COUNT (8) /* Move this down when adding a new minor */ 58 59#define Z2RAM_CHUNK1024 ( Z2RAM_CHUNKSIZE >> 10 ) 60 61static u_long *z2ram_map = NULL; 62static u_long z2ram_size = 0; 63static int z2_count = 0; 64static int chip_count = 0; 65static int list_count = 0; 66static int current_device = -1; 67 68static DEFINE_SPINLOCK(z2ram_lock); 69 70static struct block_device_operations z2_fops; 71static struct gendisk *z2ram_gendisk; 72 73static void do_z2_request(request_queue_t *q) 74{ 75 struct request *req; 76 while ((req = elv_next_request(q)) != NULL) { 77 unsigned long start = req->sector << 9; 78 unsigned long len = req->current_nr_sectors << 9; 79 80 if (start + len > z2ram_size) { 81 printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n", 82 req->sector, req->current_nr_sectors); 83 end_request(req, 0); 84 continue; 85 } 86 while (len) { 87 unsigned long addr = start & Z2RAM_CHUNKMASK; 88 unsigned long size = Z2RAM_CHUNKSIZE - addr; 89 if (len < size) 90 size = len; 91 addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ]; 92 if (rq_data_dir(req) == READ) 93 memcpy(req->buffer, (char *)addr, size); 94 else 95 memcpy((char *)addr, req->buffer, size); 96 start += size; 97 len -= size; 98 } 99 end_request(req, 1); 100 } 101} 102 103static void 104get_z2ram( void ) 105{ 106 int i; 107 108 for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ ) 109 { 110 if ( test_bit( i, zorro_unused_z2ram ) ) 111 { 112 z2_count++; 113 z2ram_map[ z2ram_size++ ] = 114 ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT ); 115 clear_bit( i, zorro_unused_z2ram ); 116 } 117 } 118 119 return; 120} 121 122static void 123get_chipram( void ) 124{ 125 126 while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) ) 127 { 128 chip_count++; 129 z2ram_map[ z2ram_size ] = 130 (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" ); 131 132 if ( z2ram_map[ z2ram_size ] == 0 ) 133 { 134 break; 135 } 136 137 z2ram_size++; 138 } 139 140 return; 141} 142 143static int 144z2_open( struct inode *inode, struct file *filp ) 145{ 146 int device; 147 int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) * 148 sizeof( z2ram_map[0] ); 149 int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) * 150 sizeof( z2ram_map[0] ); 151 int rc = -ENOMEM; 152 153 device = iminor(inode); 154 155 if ( current_device != -1 && current_device != device ) 156 { 157 rc = -EBUSY; 158 goto err_out; 159 } 160 161 if ( current_device == -1 ) 162 { 163 z2_count = 0; 164 chip_count = 0; 165 list_count = 0; 166 z2ram_size = 0; 167 168 /* Use a specific list entry. */ 169 if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) { 170 int index = device - Z2MINOR_MEMLIST1 + 1; 171 unsigned long size, paddr, vaddr; 172 173 if (index >= m68k_realnum_memory) { 174 printk( KERN_ERR DEVICE_NAME 175 ": no such entry in z2ram_map\n" ); 176 goto err_out; 177 } 178 179 paddr = m68k_memory[index].addr; 180 size = m68k_memory[index].size & ~(Z2RAM_CHUNKSIZE-1); 181 182#ifdef __powerpc__ 183 { 184 vfree(vmalloc (size)); 185 } 186 187 vaddr = (unsigned long) __ioremap (paddr, size, 188 _PAGE_WRITETHRU); 189 190#else 191 vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size); 192#endif 193 z2ram_map = 194 kmalloc((size/Z2RAM_CHUNKSIZE)*sizeof(z2ram_map[0]), 195 GFP_KERNEL); 196 if ( z2ram_map == NULL ) 197 { 198 printk( KERN_ERR DEVICE_NAME 199 ": cannot get mem for z2ram_map\n" ); 200 goto err_out; 201 } 202 203 while (size) { 204 z2ram_map[ z2ram_size++ ] = vaddr; 205 size -= Z2RAM_CHUNKSIZE; 206 vaddr += Z2RAM_CHUNKSIZE; 207 list_count++; 208 } 209 210 if ( z2ram_size != 0 ) 211 printk( KERN_INFO DEVICE_NAME 212 ": using %iK List Entry %d Memory\n", 213 list_count * Z2RAM_CHUNK1024, index ); 214 } else 215 216 switch ( device ) 217 { 218 case Z2MINOR_COMBINED: 219 220 z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL ); 221 if ( z2ram_map == NULL ) 222 { 223 printk( KERN_ERR DEVICE_NAME 224 ": cannot get mem for z2ram_map\n" ); 225 goto err_out; 226 } 227 228 get_z2ram(); 229 get_chipram(); 230 231 if ( z2ram_size != 0 ) 232 printk( KERN_INFO DEVICE_NAME 233 ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n", 234 z2_count * Z2RAM_CHUNK1024, 235 chip_count * Z2RAM_CHUNK1024, 236 ( z2_count + chip_count ) * Z2RAM_CHUNK1024 ); 237 238 break; 239 240 case Z2MINOR_Z2ONLY: 241 z2ram_map = kmalloc( max_z2_map, GFP_KERNEL ); 242 if ( z2ram_map == NULL ) 243 { 244 printk( KERN_ERR DEVICE_NAME 245 ": cannot get mem for z2ram_map\n" ); 246 goto err_out; 247 } 248 249 get_z2ram(); 250 251 if ( z2ram_size != 0 ) 252 printk( KERN_INFO DEVICE_NAME 253 ": using %iK of Zorro II RAM\n", 254 z2_count * Z2RAM_CHUNK1024 ); 255 256 break; 257 258 case Z2MINOR_CHIPONLY: 259 z2ram_map = kmalloc( max_chip_map, GFP_KERNEL ); 260 if ( z2ram_map == NULL ) 261 { 262 printk( KERN_ERR DEVICE_NAME 263 ": cannot get mem for z2ram_map\n" ); 264 goto err_out; 265 } 266 267 get_chipram(); 268 269 if ( z2ram_size != 0 ) 270 printk( KERN_INFO DEVICE_NAME 271 ": using %iK Chip RAM\n", 272 chip_count * Z2RAM_CHUNK1024 ); 273 274 break; 275 276 default: 277 rc = -ENODEV; 278 goto err_out; 279 280 break; 281 } 282 283 if ( z2ram_size == 0 ) 284 { 285 printk( KERN_NOTICE DEVICE_NAME 286 ": no unused ZII/Chip RAM found\n" ); 287 goto err_out_kfree; 288 } 289 290 current_device = device; 291 z2ram_size <<= Z2RAM_CHUNKSHIFT; 292 set_capacity(z2ram_gendisk, z2ram_size >> 9); 293 } 294 295 return 0; 296 297err_out_kfree: 298 kfree(z2ram_map); 299err_out: 300 return rc; 301} 302 303static int 304z2_release( struct inode *inode, struct file *filp ) 305{ 306 if ( current_device == -1 ) 307 return 0; 308 309 310 return 0; 311} 312 313static struct block_device_operations z2_fops = 314{ 315 .owner = THIS_MODULE, 316 .open = z2_open, 317 .release = z2_release, 318}; 319 320static struct kobject *z2_find(dev_t dev, int *part, void *data) 321{ 322 *part = 0; 323 return get_disk(z2ram_gendisk); 324} 325 326static struct request_queue *z2_queue; 327 328static int __init 329z2_init(void) 330{ 331 int ret; 332 333 if (!MACH_IS_AMIGA) 334 return -ENXIO; 335 336 ret = -EBUSY; 337 if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME)) 338 goto err; 339 340 ret = -ENOMEM; 341 z2ram_gendisk = alloc_disk(1); 342 if (!z2ram_gendisk) 343 goto out_disk; 344 345 z2_queue = blk_init_queue(do_z2_request, &z2ram_lock); 346 if (!z2_queue) 347 goto out_queue; 348 349 z2ram_gendisk->major = Z2RAM_MAJOR; 350 z2ram_gendisk->first_minor = 0; 351 z2ram_gendisk->fops = &z2_fops; 352 sprintf(z2ram_gendisk->disk_name, "z2ram"); 353 354 z2ram_gendisk->queue = z2_queue; 355 add_disk(z2ram_gendisk); 356 blk_register_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT, THIS_MODULE, 357 z2_find, NULL, NULL); 358 359 return 0; 360 361out_queue: 362 put_disk(z2ram_gendisk); 363out_disk: 364 unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); 365err: 366 return ret; 367} 368 369static void __exit z2_exit(void) 370{ 371 int i, j; 372 blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); 373 if ( unregister_blkdev( Z2RAM_MAJOR, DEVICE_NAME ) != 0 ) 374 printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n"); 375 376 del_gendisk(z2ram_gendisk); 377 put_disk(z2ram_gendisk); 378 blk_cleanup_queue(z2_queue); 379 380 if ( current_device != -1 ) 381 { 382 i = 0; 383 384 for ( j = 0 ; j < z2_count; j++ ) 385 { 386 set_bit( i++, zorro_unused_z2ram ); 387 } 388 389 for ( j = 0 ; j < chip_count; j++ ) 390 { 391 if ( z2ram_map[ i ] ) 392 { 393 amiga_chip_free( (void *) z2ram_map[ i++ ] ); 394 } 395 } 396 397 if ( z2ram_map != NULL ) 398 { 399 kfree( z2ram_map ); 400 } 401 } 402 403 return; 404} 405 406module_init(z2_init); 407module_exit(z2_exit); 408MODULE_LICENSE("GPL"); 409