!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/cdrom/   drwxr-xr-x
Free 318.35 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     gscd.c (19.86 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"

/*
    linux/drivers/block/gscd.c - GoldStar R420 CDROM driver

        Copyright (C) 1995  Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
        based upon pre-works by   Eberhard Moenkeberg <emoenke@gwdg.de>
        

        For all kind of other information about the GoldStar CDROM
        and this Linux device driver I installed a WWW-URL:
        http://linux.rz.fh-hannover.de/~raupach        


             If you are the editor of a Linux CD, you should
             enable gscd.c within your boot floppy kernel and
             send me one of your CDs for free.


        --------------------------------------------------------------------
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
    --------------------------------------------------------------------
    
    9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
                       Removed init_module & cleanup_module in favor of 
                  module_init & module_exit.
               Torben Mathiasen <tmm@image.dk>

*/

/* These settings are for various debug-level. Leave they untouched ... */
#define  NO_GSCD_DEBUG
#define  NO_IOCTL_DEBUG
#define  NO_MODULE_DEBUG
#define  NO_FUTURE_WORK
/*------------------------*/

#include <linux/module.h>

#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/cdrom.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
#include <linux/blk.h>
#define gscd_port gscd        /* for compatible parameter passing with "insmod" */
#include "gscd.h"

static int gscd_blocksizes[1] = { 512 };

static int gscdPresent = 0;

static unsigned char gscd_buf[2048];    /* buffer for block size conversion */
static int gscd_bn = -1;
static short gscd_port = GSCD_BASE_ADDR;
MODULE_PARM(gscd, "h");

/* Kommt spaeter vielleicht noch mal dran ...
 *    static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
 */

static void gscd_transfer(void);
static void gscd_read_cmd(void);
static void gscd_hsg2msf(long hsg, struct msf *msf);
static void gscd_bin2bcd(unsigned char *p);

/* Schnittstellen zum Kern/FS */

static void do_gscd_request(request_queue_t *);
static void __do_gscd_request(unsigned long dummy);
static int gscd_ioctl(struct inode *, struct file *, unsigned int,
              unsigned long);
static int gscd_open(struct inode *, struct file *);
static int gscd_release(struct inode *, struct file *);
static int check_gscd_med_chg(kdev_t);

/*      GoldStar Funktionen    */

static void cc_Reset(void);
static int wait_drv_ready(void);
static int find_drives(void);
static void cmd_out(int, char *, char *, int);
static void cmd_status(void);
static void cc_Ident(char *);
static void cc_SetSpeed(void);
static void init_cd_drive(int);

static int get_status(void);
static void clear_Audio(void);
static void cc_invalidate(void);

/* some things for the next version */
#ifdef FUTURE_WORK
static void update_state(void);
static long gscd_msf2hsg(struct msf *mp);
static int gscd_bcd2bin(unsigned char bcd);
#endif

/*    common GoldStar Initialization    */

static int my_gscd_init(void);


/*      lo-level cmd-Funktionen    */

static void cmd_info_in(char *, int);
static void cmd_end(void);
static void cmd_read_b(char *, int, int);
static void cmd_read_w(char *, int, int);
static int cmd_unit_alive(void);
static void cmd_write_cmd(char *);


/*      GoldStar Variablen     */

static int curr_drv_state;
static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
static int drv_mode;
static int disk_state;
static int speed;
static int ndrives;

static unsigned char drv_num_read;
static unsigned char f_dsk_valid;
static unsigned char current_drive;
static unsigned char f_drv_ok;


static char f_AudioPlay;
static char f_AudioPause;
static int AudioStart_m;
static int AudioStart_f;
static int AudioEnd_m;
static int AudioEnd_f;

static struct timer_list gscd_timer;

static struct block_device_operations gscd_fops = {
    owner:THIS_MODULE,
    open:gscd_open,
    release:gscd_release,
    ioctl:gscd_ioctl,
    check_media_change:check_gscd_med_chg,
};

/* 
 * Checking if the media has been changed
 * (not yet implemented)
 */
static int check_gscd_med_chg(kdev_t full_dev)
{
    int target;


    target = MINOR(full_dev);

    if (target > 0) {
        printk
            ("GSCD: GoldStar CD-ROM request error: invalid device.\n");
        return 0;
    }
#ifdef GSCD_DEBUG
    printk("gscd: check_med_change\n");
#endif

    return 0;
}


#ifndef MODULE
/* Using new interface for kernel-parameters */

static int __init gscd_setup(char *str)
{
    int ints[2];
    (void) get_options(str, ARRAY_SIZE(ints), ints);

    if (ints[0] > 0) {
        gscd_port = ints[1];
    }
    return 1;
}

__setup("gscd=", gscd_setup);

#endif

static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
              unsigned long arg)
{
    unsigned char to_do[10];
    unsigned char dummy;


    switch (cmd) {
    case CDROMSTART:    /* Spin up the drive */
        /* Don't think we can do this.  Even if we could,
         * I think the drive times out and stops after a while
         * anyway.  For now, ignore it.
         */
        return 0;

    case CDROMRESUME:    /* keine Ahnung was das ist */
        return 0;


    case CDROMEJECT:
        cmd_status();
        to_do[0] = CMD_TRAY_CTL;
        cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);

        return 0;

    default:
        return -EINVAL;
    }

}


/*
 * Take care of the different block sizes between cdrom and Linux.
 * When Linux gets variable block sizes this will probably go away.
 */

static void gscd_transfer(void)
{
    long offs;

    while (CURRENT->nr_sectors > 0 && gscd_bn == CURRENT->sector / 4) {
        offs = (CURRENT->sector & 3) * 512;
        memcpy(CURRENT->buffer, gscd_buf + offs, 512);
        CURRENT->nr_sectors--;
        CURRENT->sector++;
        CURRENT->buffer += 512;
    }
}


/*
 * I/O request routine called from Linux kernel.
 */

static void do_gscd_request(request_queue_t * q)
{
    __do_gscd_request(0);
}

static void __do_gscd_request(unsigned long dummy)
{
    unsigned int block, dev;
    unsigned int nsect;

      repeat:
    if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
        goto out;
    INIT_REQUEST;
    dev = MINOR(CURRENT->rq_dev);
    block = CURRENT->sector;
    nsect = CURRENT->nr_sectors;

    if (QUEUE_EMPTY || CURRENT->sector == -1)
        goto out;

    if (CURRENT->cmd != READ) {
        printk("GSCD: bad cmd %d\n", CURRENT->cmd);
        end_request(0);
        goto repeat;
    }

    if (MINOR(CURRENT->rq_dev) != 0) {
        printk("GSCD: this version supports only one device\n");
        end_request(0);
        goto repeat;
    }

    gscd_transfer();

    /* if we satisfied the request from the buffer, we're done. */

    if (CURRENT->nr_sectors == 0) {
        end_request(1);
        goto repeat;
    }
#ifdef GSCD_DEBUG
    printk("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect);
#endif

    gscd_read_cmd();
      out:
    return;
}



/*
 * Check the result of the set-mode command.  On success, send the
 * read-data command.
 */

static void gscd_read_cmd(void)
{
    long block;
    struct gscd_Play_msf gscdcmd;
    char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 };    /* cmd mode M-S-F secth sectl */



    cmd_status();
    if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
        printk("GSCD: no disk or door open\n");
        end_request(0);
    } else {
        if (disk_state & ST_INVALID) {
            printk("GSCD: disk invalid\n");
            end_request(0);
        } else {
            gscd_bn = -1;    /* purge our buffer */
            block = CURRENT->sector / 4;
            gscd_hsg2msf(block, &gscdcmd.start);    /* cvt to msf format */

            cmd[2] = gscdcmd.start.min;
            cmd[3] = gscdcmd.start.sec;
            cmd[4] = gscdcmd.start.frame;

#ifdef GSCD_DEBUG
            printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
                   cmd[4]);
#endif
            cmd_out(TYPE_DATA, (char *) &cmd,
                (char *) &gscd_buf[0], 1);

            gscd_bn = CURRENT->sector / 4;
            gscd_transfer();
            end_request(1);
        }
    }
    SET_TIMER(__do_gscd_request, 1);
}


/*
 * Open the device special file.  Check that a disk is in.
 */

static int gscd_open(struct inode *ip, struct file *fp)
{
    int st;

#ifdef GSCD_DEBUG
    printk("GSCD: open\n");
#endif

    if (gscdPresent == 0)
        return -ENXIO;    /* no hardware */

    get_status();
    st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
    if (st) {
        printk("GSCD: no disk or door open\n");
        return -ENXIO;
    }

/*    if (updateToc() < 0)
        return -EIO;
*/

    return 0;
}


/*
 * On close, we flush all gscd blocks from the buffer cache.
 */

static int gscd_release(struct inode *inode, struct file *file)
{

#ifdef GSCD_DEBUG
    printk("GSCD: release\n");
#endif

    gscd_bn = -1;

    return 0;
}


int get_status(void)
{
    int status;

    cmd_status();
    status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);

    if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
        cc_invalidate();
        return 1;
    } else {
        return 0;
    }
}


void cc_invalidate(void)
{
    drv_num_read = 0xFF;
    f_dsk_valid = 0xFF;
    current_drive = 0xFF;
    f_drv_ok = 0xFF;

    clear_Audio();

}

void clear_Audio(void)
{

    f_AudioPlay = 0;
    f_AudioPause = 0;
    AudioStart_m = 0;
    AudioStart_f = 0;
    AudioEnd_m = 0;
    AudioEnd_f = 0;

}

/*
 *   waiting ?  
 */

int wait_drv_ready(void)
{
    int found, read;

    do {
        found = inb(GSCDPORT(0));
        found &= 0x0f;
        read = inb(GSCDPORT(0));
        read &= 0x0f;
    } while (read != found);

#ifdef GSCD_DEBUG
    printk("Wait for: %d\n", read);
#endif

    return read;
}

void cc_Ident(char *respons)
{
    char to_do[] = { CMD_IDENT, 0, 0 };

    cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);

}

void cc_SetSpeed(void)
{
    char to_do[] = { CMD_SETSPEED, 0, 0 };
    char dummy;

    if (speed > 0) {
        to_do[1] = speed & 0x0F;
        cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
    }
}


void cc_Reset(void)
{
    char to_do[] = { CMD_RESET, 0 };
    char dummy;

    cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
}



void cmd_status(void)
{
    char to_do[] = { CMD_STATUS, 0 };
    char dummy;

    cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);

#ifdef GSCD_DEBUG
    printk("GSCD: Status: %d\n", disk_state);
#endif

}

void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
{
    int result;


    result = wait_drv_ready();
    if (result != drv_mode) {
        unsigned long test_loops = 0xFFFF;
        int i, dummy;

        outb(curr_drv_state, GSCDPORT(0));

        /* LOCLOOP_170 */
        do {
            result = wait_drv_ready();
            test_loops--;
        } while ((result != drv_mode) && (test_loops > 0));

        if (result != drv_mode) {
            disk_state = ST_x08 | ST_x04 | ST_INVALID;
            return;
        }

        /* ...and waiting */
        for (i = 1, dummy = 1; i < 0xFFFF; i++) {
            dummy *= i;
        }
    }

    /* LOC_172 */
    /* check the unit */
    /* and wake it up */
    if (cmd_unit_alive() != 0x08) {
        /* LOC_174 */
        /* game over for this unit */
        disk_state = ST_x08 | ST_x04 | ST_INVALID;
        return;
    }

    /* LOC_176 */
#ifdef GSCD_DEBUG
    printk("LOC_176 ");
#endif
    if (drv_mode == 0x09) {
        /* magic... */
        printk("GSCD: magic ...\n");
        outb(result, GSCDPORT(2));
    }

    /* write the command to the drive */
    cmd_write_cmd(cmd);

    /* LOC_178 */
    for (;;) {
        result = wait_drv_ready();
        if (result != drv_mode) {
            /* LOC_179 */
            if (result == 0x04) {    /* Mode 4 */
                /* LOC_205 */
#ifdef GSCD_DEBUG
                printk("LOC_205 ");
#endif
                disk_state = inb(GSCDPORT(2));

                do {
                    result = wait_drv_ready();
                } while (result != drv_mode);
                return;

            } else {
                if (result == 0x06) {    /* Mode 6 */
                    /* LOC_181 */
#ifdef GSCD_DEBUG
                    printk("LOC_181 ");
#endif

                    if (cmd_type == TYPE_DATA) {
                        /* read data */
                        /* LOC_184 */
                        if (drv_mode == 9) {
                            /* read the data to the buffer (word) */

                            /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
                            cmd_read_w
                                (respo_buf,
                                 respo_count,
                                 CD_FRAMESIZE /
                                 2);
                            return;
                        } else {
                            /* read the data to the buffer (byte) */

                            /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
                            cmd_read_b
                                (respo_buf,
                                 respo_count,
                                 CD_FRAMESIZE);
                            return;
                        }
                    } else {
                        /* read the info to the buffer */
                        cmd_info_in(respo_buf,
                                respo_count);
                        return;
                    }

                    return;
                }
            }

        } else {
            disk_state = ST_x08 | ST_x04 | ST_INVALID;
            return;
        }
    }            /* for (;;) */


#ifdef GSCD_DEBUG
    printk("\n");
#endif
}


static void cmd_write_cmd(char *pstr)
{
    int i, j;

    /* LOC_177 */
#ifdef GSCD_DEBUG
    printk("LOC_177 ");
#endif

    /* calculate the number of parameter */
    j = *pstr & 0x0F;

    /* shift it out */
    for (i = 0; i < j; i++) {
        outb(*pstr, GSCDPORT(2));
        pstr++;
    }
}


static int cmd_unit_alive(void)
{
    int result;
    unsigned long max_test_loops;


    /* LOC_172 */
#ifdef GSCD_DEBUG
    printk("LOC_172 ");
#endif

    outb(curr_drv_state, GSCDPORT(0));
    max_test_loops = 0xFFFF;

    do {
        result = wait_drv_ready();
        max_test_loops--;
    } while ((result != 0x08) && (max_test_loops > 0));

    return result;
}


static void cmd_info_in(char *pb, int count)
{
    int result;
    char read;


    /* read info */
    /* LOC_182 */
#ifdef GSCD_DEBUG
    printk("LOC_182 ");
#endif

    do {
        read = inb(GSCDPORT(2));
        if (count > 0) {
            *pb = read;
            pb++;
            count--;
        }

        /* LOC_183 */
        do {
            result = wait_drv_ready();
        } while (result == 0x0E);
    } while (result == 6);

    cmd_end();
    return;
}


static void cmd_read_b(char *pb, int count, int size)
{
    int result;
    int i;


    /* LOC_188 */
    /* LOC_189 */
#ifdef GSCD_DEBUG
    printk("LOC_189 ");
#endif

    do {
        do {
            result = wait_drv_ready();
        } while (result != 6 || result == 0x0E);

        if (result != 6) {
            cmd_end();
            return;
        }
#ifdef GSCD_DEBUG
        printk("LOC_191 ");
#endif

        for (i = 0; i < size; i++) {
            *pb = inb(GSCDPORT(2));
            pb++;
        }
        count--;
    } while (count > 0);

    cmd_end();
    return;
}


static void cmd_end(void)
{
    int result;


    /* LOC_204 */
#ifdef GSCD_DEBUG
    printk("LOC_204 ");
#endif

    do {
        result = wait_drv_ready();
        if (result == drv_mode) {
            return;
        }
    } while (result != 4);

    /* LOC_205 */
#ifdef GSCD_DEBUG
    printk("LOC_205 ");
#endif

    disk_state = inb(GSCDPORT(2));

    do {
        result = wait_drv_ready();
    } while (result != drv_mode);
    return;

}


static void cmd_read_w(char *pb, int count, int size)
{
    int result;
    int i;


#ifdef GSCD_DEBUG
    printk("LOC_185 ");
#endif

    do {
        /* LOC_185 */
        do {
            result = wait_drv_ready();
        } while (result != 6 || result == 0x0E);

        if (result != 6) {
            cmd_end();
            return;
        }

        for (i = 0; i < size; i++) {
            /* na, hier muss ich noch mal drueber nachdenken */
            *pb = inw(GSCDPORT(2));
            pb++;
        }
        count--;
    } while (count > 0);

    cmd_end();
    return;
}

int __init find_drives(void)
{
    int *pdrv;
    int drvnum;
    int subdrv;
    int i;

    speed = 0;
    pdrv = (int *) &drv_states;
    curr_drv_state = 0xFE;
    subdrv = 0;
    drvnum = 0;

    for (i = 0; i < 8; i++) {
        subdrv++;
        cmd_status();
        disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
        if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
            /* LOC_240 */
            *pdrv = curr_drv_state;
            init_cd_drive(drvnum);
            pdrv++;
            drvnum++;
        } else {
            if (subdrv < 2) {
                continue;
            } else {
                subdrv = 0;
            }
        }

/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */
/* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
        curr_drv_state *= 2;
        curr_drv_state |= 1;
#ifdef GSCD_DEBUG
        printk("DriveState: %d\n", curr_drv_state);
#endif
    }

    ndrives = drvnum;
    return drvnum;
}

void __init init_cd_drive(int num)
{
    char resp[50];
    int i;

    printk("GSCD: init unit %d\n", num);
    cc_Ident((char *) &resp);

    printk("GSCD: identification: ");
    for (i = 0; i < 0x1E; i++) {
        printk("%c", resp[i]);
    }
    printk("\n");

    cc_SetSpeed();

}

#ifdef FUTURE_WORK
/* return_done */
static void update_state(void)
{
    unsigned int AX;


    if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
        if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
            AX = ST_INVALID;
        }

        if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
            == 0) {
            invalidate();
            f_drv_ok = 0;
        }

        AX |= 0x8000;
    }

    if (disk_state & ST_PLAYING) {
        AX |= 0x200;
    }

    AX |= 0x100;
    /* pkt_esbx = AX; */

    disk_state = 0;

}
#endif

/* Init for the Module-Version */
int init_gscd(void)
{
    long err;


    /* call the GoldStar-init */
    err = my_gscd_init();

    if (err < 0) {
        return err;
    } else {
        printk(KERN_INFO "Happy GoldStar !\n");
        return 0;
    }
}

void __exit exit_gscd(void)
{
    CLEAR_TIMER;

    devfs_unregister(devfs_find_handle
             (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0));
    if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
        printk("What's that: can't unregister GoldStar-module\n");
        return;
    }
    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
    release_region(gscd_port, 4);
    printk(KERN_INFO "GoldStar-module released.\n");
}

#ifdef MODULE
module_init(init_gscd);
#endif
module_exit(exit_gscd);


/* Test for presence of drive and initialize it.  Called only at boot time. */
int __init gscd_init(void)
{
    return my_gscd_init();
}


/* This is the common initialisation for the GoldStar drive. */
/* It is called at boot time AND for module init.           */
int __init my_gscd_init(void)
{
    int i;
    int result;

    printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
    printk(KERN_INFO
           "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
           gscd_port);

    if (check_region(gscd_port, 4)) {
        printk
            ("GSCD: Init failed, I/O port (%X) already in use.\n",
             gscd_port);
        return -EIO;
    }


    /* check for card */
    result = wait_drv_ready();
    if (result == 0x09) {
        printk("GSCD: DMA kann ich noch nicht!\n");
        return -EIO;
    }

    if (result == 0x0b) {
        drv_mode = result;
        i = find_drives();
        if (i == 0) {
            printk
                ("GSCD: GoldStar CD-ROM Drive is not found.\n");
            return -EIO;
        }
    }

    if ((result != 0x0b) && (result != 0x09)) {
        printk
            ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n");
        return -EIO;
    }

    /* reset all drives */
    i = 0;
    while (drv_states[i] != 0) {
        curr_drv_state = drv_states[i];
        printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
        cc_Reset();
        printk("done\n");
        i++;
    }

    if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {
        printk
            ("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
             MAJOR_NR);
        return -EIO;
    }
    devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
               S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);

    blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
    blksize_size[MAJOR_NR] = gscd_blocksizes;
    read_ahead[MAJOR_NR] = 4;

    disk_state = 0;
    gscdPresent = 1;

    request_region(gscd_port, 4, "gscd");
    register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0);

    printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
    return 0;
}

static void gscd_hsg2msf(long hsg, struct msf *msf)
{
    hsg += CD_MSF_OFFSET;
    msf->min = hsg / (CD_FRAMES * CD_SECS);
    hsg %= CD_FRAMES * CD_SECS;
    msf->sec = hsg / CD_FRAMES;
    msf->frame = hsg % CD_FRAMES;

    gscd_bin2bcd(&msf->min);    /* convert to BCD */
    gscd_bin2bcd(&msf->sec);
    gscd_bin2bcd(&msf->frame);
}


static void gscd_bin2bcd(unsigned char *p)
{
    int u, t;

    u = *p % 10;
    t = *p / 10;
    *p = u | (t << 4);
}


#ifdef FUTURE_WORK
static long gscd_msf2hsg(struct msf *mp)
{
    return gscd_bcd2bin(mp->frame)
        + gscd_bcd2bin(mp->sec) * CD_FRAMES
        + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
}

static int gscd_bcd2bin(unsigned char bcd)
{
    return (bcd >> 4) * 10 + (bcd & 0xF);
}
#endif

MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0096 ]--