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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [block/] [rd.c] - Blame information for rev 1626

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * ramdisk.c - Multiple ramdisk driver - gzip-loading version - v. 0.8 beta.
3
 *
4
 * (C) Chad Page, Theodore Ts'o, et. al, 1995.
5
 *
6
 * This ramdisk is designed to have filesystems created on it and mounted
7
 * just like a regular floppy disk.
8
 *
9
 * It also does something suggested by Linus: use the buffer cache as the
10
 * ramdisk data.  This makes it possible to dynamically allocate the ramdisk
11
 * buffer - with some consequences I have to deal with as I write this.
12
 *
13
 * This code is based on the original ramdisk.c, written mostly by
14
 * Theodore Ts'o (TYT) in 1991.  The code was largely rewritten by
15
 * Chad Page to use the buffer cache to store the ramdisk data in
16
 * 1995; Theodore then took over the driver again, and cleaned it up
17
 * for inclusion in the mainline kernel.
18
 *
19
 * The original CRAMDISK code was written by Richard Lyons, and
20
 * adapted by Chad Page to use the new ramdisk interface.  Theodore
21
 * Ts'o rewrote it so that both the compressed ramdisk loader and the
22
 * kernel decompressor uses the same inflate.c codebase.  The ramdisk
23
 * loader now also loads into a dynamic (buffer cache based) ramdisk,
24
 * not the old static ramdisk.  Support for the old static ramdisk has
25
 * been completely removed.
26
 *
27
 * Loadable module support added by Tom Dyas.
28
 *
29
 * Further cleanups by Chad Page (page0588@sundance.sjsu.edu):
30
 *      Cosmetic changes in #ifdef MODULE, code movement, etc...
31
 *      When the ramdisk is rmmod'ed, free the protected buffers
32
 *      Default ramdisk size changed to 2.88MB
33
 *
34
 *  Added initrd: Werner Almesberger & Hans Lermen, Feb '96
35
 *
36
 * 4/25/96 : Made ramdisk size a parameter (default is now 4MB)
37
 *              - Chad Page
38
 *
39
 * Support added for releasing empty (all zero) blocks
40
 *      -- Kenneth Albanowski <kjahds@kjahds.com>
41
 *
42
 */
43
 
44
#include <linux/config.h>
45
#include <linux/sched.h>
46
#include <linux/minix_fs.h>
47
#include <linux/ext2_fs.h>
48
#include <linux/romfs_fs.h>
49
#include <linux/fs.h>
50
#include <linux/kernel.h>
51
#include <linux/string.h>
52
#include <linux/mm.h>
53
#include <linux/mman.h>
54
#include <linux/malloc.h>
55
#include <linux/ioctl.h>
56
#include <linux/fd.h>
57
#include <linux/module.h>
58
 
59
#include <asm/system.h>
60
#include <asm/segment.h>
61
#include <asm/byteorder.h> 
62
 
63
extern void wait_for_keypress(void);
64
 
65
/*
66
 * 35 has been officially registered as the RAMDISK major number, but
67
 * so is the original MAJOR number of 1.  We're using 1 in
68
 * include/linux/major.h for now
69
 */
70
#define MAJOR_NR RAMDISK_MAJOR
71
#include <linux/blk.h>
72
 
73
/* The ramdisk size is now a parameter */
74
#define NUM_RAMDISKS 16         /* This cannot be overridden (yet) */ 
75
 
76
#ifndef MODULE
77
/* We don't have to load ramdisks or gunzip them in a module... */
78
#define RD_LOADER
79
#define BUILD_CRAMDISK
80
 
81
void rd_load(void);
82
static int crd_load(struct file *fp, struct file *outfp);
83
 
84
#ifdef CONFIG_BLK_DEV_INITRD
85
static int initrd_users = 0;
86
#endif
87
#endif
88
 
89
/* Various static variables go here... mostly used within the ramdisk code only. */
90
 
91
static int rd_length[NUM_RAMDISKS];
92
static int rd_hardsec[NUM_RAMDISKS];
93
static int rd_blocksizes[NUM_RAMDISKS];
94
static int rd_kbsize[NUM_RAMDISKS];
95
 
96
/*
97
 * Parameters for the boot-loading of the ramdisk.  These are set by
98
 * init/main.c (from arguments to the kernel command line) or from the
99
 * architecture-specific setup routine (from the stored bootsector
100
 * information).
101
 */
102
int rd_size = 2048;             /* Size of the ramdisks */
103
 
104
#ifndef MODULE
105
int rd_doload = 0;               /* 1 = load ramdisk, 0 = don't load */
106
int rd_prompt = 1;              /* 1 = prompt for ramdisk, 0 = don't prompt */
107
int rd_image_start = 0;          /* starting block # of image */
108
#ifdef CONFIG_BLK_DEV_INITRD
109
unsigned long initrd_start,initrd_end;
110
int mount_initrd = 1;           /* zero if initrd should not be mounted */
111
#endif
112
#endif
113
 
114
/*
115
 *  Basically, my strategy here is to set up a buffer-head which can't be
116
 *  deleted, and make that my Ramdisk.  If the request is outside of the
117
 *  allocated size, we must get rid of it...
118
 *
119
 */
120
static void rd_request(void)
121
{
122
        unsigned int minor;
123
        int offset, len;
124
 
125
repeat:
126
        INIT_REQUEST;
127
 
128
        minor = MINOR(CURRENT->rq_dev);
129
 
130
        if (minor >= NUM_RAMDISKS) {
131
                end_request(0);
132
                goto repeat;
133
        }
134
 
135
        offset = CURRENT->sector << 9;
136
        len = CURRENT->current_nr_sectors << 9;
137
 
138
        if ((offset + len) > rd_length[minor]) {
139
                end_request(0);
140
                goto repeat;
141
        }
142
 
143
        /*
144
         * If we're reading, fill the buffer with 0's.  This is okay since
145
         * we're using protected buffers which should never get freed...
146
         *
147
         * If we're writing, we protect the buffer.
148
         */
149
 
150
#ifndef CONFIG_RD_RELEASE_BLOCKS
151
        if (CURRENT->cmd == READ) {
152
                memset(CURRENT->buffer, 0, len);
153
        }
154
        else
155
                set_bit(BH_Protected, &CURRENT->bh->b_state);
156
#else /* CONFIG_RD_RELEASE_BLOCKS*/
157
 
158
        /* But we'll unprotect it if it's empty. */
159
 
160
        if (CURRENT->cmd == READ) {
161
                memset(CURRENT->buffer, 0, len);
162
        }
163
        else
164
        {
165
                int i=0;
166
 
167
                for(i=0;i<len;i++)
168
                        if (CURRENT->buffer[i] != 0)
169
                                break;
170
 
171
                if (i<len) {
172
                        set_bit(BH_Protected, &CURRENT->bh->b_state);
173
                }
174
                else {
175
                        clear_bit(BH_Protected, &CURRENT->bh->b_state);
176
                }
177
        }
178
#endif /* CONFIG_RD_RELEASE_BLOCKS*/
179
 
180
        end_request(1);
181
        goto repeat;
182
}
183
 
184
static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
185
{
186
        int err;
187
 
188
        if (!inode || !inode->i_rdev)
189
                return -EINVAL;
190
 
191
        switch (cmd) {
192
                case BLKFLSBUF:
193
                        if (!suser()) return -EACCES;
194
                        invalidate_buffers(inode->i_rdev);
195
                        break;
196
                case BLKGETSIZE:   /* Return device size */
197
                        if (!arg)  return -EINVAL;
198
                        err = verify_area(VERIFY_WRITE, (long *) arg,
199
                                          sizeof(long));
200
                        if (err)
201
                                return err;
202
                        put_user(rd_length[MINOR(inode->i_rdev)] / 512,
203
                                 (long *) arg);
204
                        return 0;
205
 
206
                default:
207
                        break;
208
        };
209
 
210
        return 0;
211
}
212
 
213
 
214
#ifdef CONFIG_BLK_DEV_INITRD
215
 
216
static int initrd_read(struct inode *inode,struct file *file,char *buf,
217
    int count)
218
{
219
        int left;
220
 
221
        left = initrd_end-initrd_start-file->f_pos;
222
        if (count > left) count = left;
223
        if (count <= 0) return 0;
224
        memcpy_tofs(buf,(char *) initrd_start+file->f_pos,count);
225
        file->f_pos += count;
226
        return count;
227
}
228
 
229
 
230
static void initrd_release(struct inode *inode,struct file *file)
231
{
232
        unsigned long i;
233
 
234
        if (--initrd_users) return;
235
        for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
236
                free_page(i);
237
        initrd_start = 0;
238
}
239
 
240
 
241
static struct file_operations initrd_fops = {
242
        NULL,           /* lseek */
243
        initrd_read,    /* read */
244
        NULL,           /* write */
245
        NULL,           /* readdir */
246
        NULL,           /* select */
247
        NULL,           /* ioctl */
248
        NULL,           /* mmap */
249
        NULL,           /* open */
250
        initrd_release, /* release */
251
        NULL            /* fsync */
252
};
253
 
254
#endif
255
 
256
 
257
static int rd_open(struct inode * inode, struct file * filp)
258
{
259
#ifdef CONFIG_BLK_DEV_INITRD
260
        if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
261
                if (!initrd_start) return -ENODEV;
262
                initrd_users++;
263
                filp->f_op = &initrd_fops;
264
                return 0;
265
        }
266
#endif
267
 
268
        if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
269
                return -ENXIO;
270
 
271
        MOD_INC_USE_COUNT;
272
 
273
        return 0;
274
}
275
 
276
#ifdef MODULE
277
static void rd_release(struct inode * inode, struct file * filp)
278
{
279
        MOD_DEC_USE_COUNT;
280
}
281
#endif
282
 
283
static struct file_operations fd_fops = {
284
        NULL,           /* lseek - default */
285
        block_read,     /* read - block dev read */
286
        block_write,    /* write - block dev write */
287
        NULL,           /* readdir - not here! */
288
        NULL,           /* select */
289
        rd_ioctl,       /* ioctl */
290
        NULL,           /* mmap */
291
        rd_open,        /* open */
292
#ifndef MODULE
293
        NULL,           /* no special release code... */
294
#else
295
        rd_release,     /* module needs to decrement use count */
296
#endif
297
        block_fsync             /* fsync */
298
};
299
 
300
/* This is the registration and initialization section of the ramdisk driver */
301
int rd_init(void)
302
{
303
        int             i;
304
 
305
        if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
306
                printk("RAMDISK: Could not get major %d", MAJOR_NR);
307
                return -EIO;
308
        }
309
 
310
        blk_dev[MAJOR_NR].request_fn = &rd_request;
311
 
312
        for (i = 0; i < NUM_RAMDISKS; i++) {
313
                rd_length[i] = (rd_size * BLOCK_SIZE);
314
                rd_blocksizes[i] = BLOCK_SIZE;
315
                rd_hardsec[i] = BLOCK_SIZE;
316
                rd_kbsize[i] = rd_size;
317
        }
318
 
319
        blksize_size[MAJOR_NR] = rd_blocksizes;
320
        hardsect_size[MAJOR_NR] = rd_hardsec;
321
        blk_size[MAJOR_NR] = &rd_kbsize[0];
322
 
323
        printk("Ramdisk driver initialized : %d ramdisks of %dK size\n",
324
                                                        NUM_RAMDISKS, rd_size);
325
 
326
        return 0;
327
}
328
 
329
/* loadable module support */
330
 
331
#ifdef MODULE
332
 
333
int init_module(void)
334
{
335
        int error = rd_init();
336
        if (!error)
337
                printk(KERN_INFO "RAMDISK: Loaded as module.\n");
338
        return error;
339
}
340
 
341
/* Before freeing the module, invalidate all of the protected buffers! */
342
void cleanup_module(void)
343
{
344
        int i;
345
 
346
        for (i = 0 ; i < NUM_RAMDISKS; i++)
347
                invalidate_buffers(MKDEV(MAJOR_NR, i));
348
 
349
        unregister_blkdev( MAJOR_NR, "ramdisk" );
350
        blk_dev[MAJOR_NR].request_fn = 0;
351
}
352
 
353
#endif  /* MODULE */
354
 
355
/* End of non-loading portions of the ramdisk driver */
356
 
357
#ifdef RD_LOADER 
358
/*
359
 * This routine tries to a ramdisk image to load, and returns the
360
 * number of blocks to read for a non-compressed image, 0 if the image
361
 * is a compressed image, and -1 if an image with the right magic
362
 * numbers could not be found.
363
 *
364
 * We currently check for the following magic numbers:
365
 *      minix
366
 *      ext2
367
 *      romfs
368
 *      gzip
369
 */
370
int
371
identify_ramdisk_image(kdev_t device, struct file *fp, int start_block)
372
{
373
        const int size = 512;
374
        struct minix_super_block *minixsb;
375
        struct ext2_super_block *ext2sb;
376
        struct romfs_super_block *romfsb;
377
        int nblocks = -1;
378
        int max_blocks;
379
        unsigned char *buf;
380
 
381
        buf = kmalloc(size, GFP_KERNEL);
382
        if (buf == 0)
383
                return -1;
384
 
385
        minixsb = (struct minix_super_block *) buf;
386
        ext2sb = (struct ext2_super_block *) buf;
387
        romfsb = (struct romfs_super_block *) buf;
388
        memset(buf, 0xe5, size);
389
 
390
        /*
391
         * Read block 0 to test for gzipped kernel
392
         */
393
        if (fp->f_op->lseek)
394
                fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
395
        fp->f_pos = start_block * BLOCK_SIZE;
396
 
397
        fp->f_op->read(fp->f_inode, fp, buf, size);
398
 
399
        /*
400
         * If it matches the gzip magic numbers, return -1
401
         */
402
        if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
403
                printk(KERN_NOTICE
404
                       "RAMDISK: Compressed image found at block %d\n",
405
                       start_block);
406
                nblocks = 0;
407
                goto done;
408
        }
409
 
410
        /* romfs is at block zero too */
411
        if (romfsb->word0 == ROMSB_WORD0 &&
412
            romfsb->word1 == ROMSB_WORD1) {
413
                printk(KERN_NOTICE
414
                       "RAMDISK: Romfs filesystem found at block %d\n",
415
                       start_block);
416
                nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
417
                goto done;
418
        }
419
 
420
        /*
421
         * Read block 1 to test for minix and ext2 superblock
422
         */
423
        if (fp->f_op->lseek)
424
                fp->f_op->lseek(fp->f_inode, fp,
425
                                (start_block+1) * BLOCK_SIZE, 0);
426
        fp->f_pos = (start_block+1) * BLOCK_SIZE;
427
 
428
        fp->f_op->read(fp->f_inode, fp, buf, size);
429
 
430
        /* Try minix */
431
        if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
432
            minixsb->s_magic == MINIX_SUPER_MAGIC2) {
433
                printk(KERN_NOTICE
434
                       "RAMDISK: Minix filesystem found at block %d\n",
435
                       start_block);
436
                nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
437
                goto done;
438
        }
439
 
440
        /* Try ext2 */
441
#ifndef __or1k__
442
        if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
443
                printk(KERN_NOTICE
444
                       "RAMDISK: Ext2 filesystem found at block %d\n",
445
                       start_block);
446
                nblocks = ext2sb->s_blocks_count;
447
                goto done;
448
        }
449
#else
450
        if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
451
                printk(KERN_NOTICE
452
                       "RAMDISK: ext2 filesystem found at block %d\n",
453
                       start_block);
454
                nblocks = le32_to_cpu(ext2sb->s_blocks_count);
455
                goto done;
456
        }
457
#endif
458
        printk(KERN_NOTICE
459
               "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n",
460
               start_block);
461
 
462
done:
463
        if (fp->f_op->lseek)
464
                fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
465
        fp->f_pos = start_block * BLOCK_SIZE;
466
 
467
        if ((nblocks > 0) && blk_size[MAJOR(device)]) {
468
                max_blocks = blk_size[MAJOR(device)][MINOR(device)];
469
                max_blocks -= start_block;
470
                if ((nblocks > max_blocks) && (MINOR(device) != INITRD_MINOR)) {
471
                        printk(KERN_NOTICE
472
                               "RAMDISK: Restricting filesystem size "
473
                               "from %d to %d blocks.\n",
474
                               nblocks, max_blocks);
475
                        nblocks = max_blocks;
476
                }
477
        }
478
        kfree(buf);
479
        return nblocks;
480
}
481
 
482
/*
483
 * This routine loads in the ramdisk image.
484
 */
485
static void rd_load_image(kdev_t device,int offset, int unit)
486
{
487
        struct inode inode, out_inode;
488
        struct file infile, outfile;
489
        unsigned short fs;
490
        kdev_t ram_device;
491
        int nblocks, i;
492
        char *buf;
493
        unsigned short rotate = 0;
494
        char rotator[4] = { '|' , '/' , '-' , '\\' };
495
        ram_device = MKDEV(MAJOR_NR, unit);
496
 
497
        memset(&infile, 0, sizeof(infile));
498
        memset(&inode, 0, sizeof(inode));
499
        inode.i_rdev = device;
500
        infile.f_mode = 1; /* read only */
501
        infile.f_inode = &inode;
502
 
503
        memset(&outfile, 0, sizeof(outfile));
504
        memset(&out_inode, 0, sizeof(out_inode));
505
        out_inode.i_rdev = ram_device;
506
        outfile.f_mode = 3; /* read/write */
507
        outfile.f_inode = &out_inode;
508
 
509
        if (blkdev_open(&inode, &infile) != 0) return;
510
        if (blkdev_open(&out_inode, &outfile) != 0) return;
511
 
512
 
513
        fs = get_fs();
514
        set_fs(KERNEL_DS);
515
 
516
        nblocks = identify_ramdisk_image(device, &infile, offset);
517
        if (nblocks < 0)
518
                goto done;
519
 
520
        if (nblocks == 0) {
521
#ifdef BUILD_CRAMDISK
522
                if (crd_load(&infile, &outfile) == 0)
523
                        goto successful_load;
524
#else
525
                printk(KERN_NOTICE
526
                       "RAMDISK: Kernel does not support compressed "
527
                       "ramdisk images\n");
528
#endif
529
                goto done;
530
        }
531
 
532
        if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
533
                printk("RAMDISK: image too big! (%d/%d blocks)\n",
534
                       nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
535
                goto done;
536
        }
537
 
538
        /*
539
         * OK, time to copy in the data
540
         */
541
        buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
542
        if (buf == 0) {
543
                printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
544
                goto done;
545
        }
546
 
547
        printk(KERN_NOTICE "RAMDISK: Loading %d blocks into ram disk... ", nblocks);
548
        for (i=0; i < nblocks; i++) {
549
                infile.f_op->read(infile.f_inode, &infile, buf,
550
                                  BLOCK_SIZE);
551
                outfile.f_op->write(outfile.f_inode, &outfile, buf,
552
                                    BLOCK_SIZE);
553
                if (!(i % 16)) {
554
                        printk("%c\b", rotator[rotate & 0x3]);
555
                        rotate++;
556
                }
557
        }
558
        printk("done.\n");
559
        kfree(buf);
560
 
561
successful_load:
562
        invalidate_buffers(device);
563
        ROOT_DEV = MKDEV(MAJOR_NR,unit);
564
 
565
done:
566
        if (infile.f_op->release)
567
                infile.f_op->release(&inode, &infile);
568
        set_fs(fs);
569
}
570
 
571
 
572
static void rd_load_disk(int n)
573
{
574
#ifdef CONFIG_BLK_DEV_INITRD
575
        extern kdev_t real_root_dev;
576
#endif  
577
 
578
        if (rd_doload == 0)
579
                return;
580
 
581
        if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR
582
#ifdef CONFIG_BLK_DEV_INITRD    
583
                && MAJOR(real_root_dev) != FLOPPY_MAJOR
584
#endif          
585
        )
586
                        return;
587
 
588
        if (rd_prompt) {
589
#ifdef CONFIG_BLK_DEV_FD
590
                floppy_eject();
591
#endif
592
                printk(KERN_NOTICE
593
                       "VFS: Insert root floppy disk to be loaded into ramdisk and press ENTER\n");
594
                wait_for_keypress();
595
        }
596
 
597
        rd_load_image(ROOT_DEV,rd_image_start,n);
598
 
599
}
600
 
601
void rd_load(void)
602
{
603
        rd_load_disk(0);
604
}
605
 
606
void rd_load_secondary(void)
607
{
608
        rd_load_disk(1);
609
}
610
 
611
#ifdef CONFIG_BLK_DEV_INITRD
612
void initrd_load(void)
613
{
614
        rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0,0);
615
}
616
#endif
617
 
618
#endif /* RD_LOADER */
619
 
620
#ifdef BUILD_CRAMDISK
621
 
622
/*
623
 * gzip declarations
624
 */
625
 
626
#define OF(args)  args
627
 
628
#define memzero(s, n)     memset ((s), 0, (n))
629
 
630
 
631
typedef unsigned char  uch;
632
typedef unsigned short ush;
633
typedef unsigned long  ulg;
634
 
635
#define INBUFSIZ 4096
636
#define WSIZE 0x8000    /* window size--must be a power of two, and */
637
                        /*  at least 32K for zip's deflate method */
638
 
639
static uch *inbuf;
640
static uch *window;
641
 
642
static unsigned insize = 0;  /* valid bytes in inbuf */
643
static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
644
static unsigned outcnt = 0;  /* bytes in output buffer */
645
static int exit_code = 0;
646
static long bytes_out = 0;
647
static struct file *crd_infp, *crd_outfp;
648
 
649
#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
650
 
651
/* Diagnostic functions (stubbed out) */
652
#define Assert(cond,msg)
653
#define Trace(x)
654
#define Tracev(x)
655
#define Tracevv(x)
656
#define Tracec(c,x)
657
#define Tracecv(c,x)
658
 
659
#define STATIC static
660
 
661
static int  fill_inbuf(void);
662
static void flush_window(void);
663
static void *malloc(int size);
664
static void free(void *where);
665
static void error(char *m);
666
static void gzip_mark(void **);
667
static void gzip_release(void **);
668
 
669
#include "../../lib/inflate.c"
670
 
671
static void *malloc(int size)
672
{
673
        return kmalloc(size, GFP_KERNEL);
674
}
675
 
676
static void free(void *where)
677
{
678
        kfree(where);
679
}
680
 
681
static void gzip_mark(void **ptr)
682
{
683
}
684
 
685
static void gzip_release(void **ptr)
686
{
687
}
688
 
689
 
690
/* ===========================================================================
691
 * Fill the input buffer. This is called only when the buffer is empty
692
 * and at least one byte is really needed.
693
 */
694
static int fill_inbuf()
695
{
696
        if (exit_code) return -1;
697
 
698
        insize = crd_infp->f_op->read(crd_infp->f_inode, crd_infp,
699
                                      inbuf, INBUFSIZ);
700
        if (insize == 0) return -1;
701
 
702
        inptr = 1;
703
 
704
        return inbuf[0];
705
}
706
 
707
/* ===========================================================================
708
 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
709
 * (Used for the decompressed data only.)
710
 */
711
static void flush_window()
712
{
713
    ulg c = crc;         /* temporary variable */
714
    unsigned n;
715
    uch *in, ch;
716
 
717
    crd_outfp->f_op->write(crd_outfp->f_inode, crd_outfp, window,
718
                           outcnt);
719
    in = window;
720
    for (n = 0; n < outcnt; n++) {
721
            ch = *in++;
722
            c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
723
    }
724
    crc = c;
725
    bytes_out += (ulg)outcnt;
726
    outcnt = 0;
727
}
728
 
729
static void error(char *x)
730
{
731
        printk(KERN_ERR "%s", x);
732
        exit_code = 1;
733
}
734
 
735
static int
736
crd_load(struct file * fp, struct file *outfp)
737
{
738
        int result;
739
 
740
        insize = 0;  /* valid bytes in inbuf */
741
        inptr = 0;   /* index of next byte to be processed in inbuf */
742
        outcnt = 0;  /* bytes in output buffer */
743
        exit_code = 0;
744
        bytes_out = 0;
745
        crc = 0xFFFFFFFF;
746
 
747
        crd_infp = fp;
748
        crd_outfp = outfp;
749
        inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
750
        if (inbuf == 0) {
751
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
752
                return -1;
753
        }
754
        window = kmalloc(WSIZE, GFP_KERNEL);
755
        if (window == 0) {
756
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
757
                kfree(inbuf);
758
                return -1;
759
        }
760
        makecrc();
761
        result = gunzip();
762
        kfree(inbuf);
763
        kfree(window);
764
        return result;
765
}
766
 
767
#endif  /* BUILD_CRAMDISK */
768
 

powered by: WebSVN 2.1.0

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