OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [block/] [z2ram.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.