예제 #1
0
파일: trd.c 프로젝트: tridge/junkcode
static int trd_init(void)
{
	int i;

	trd_pages = (TRD_SIZE + (PAGE_SIZE-1)) >> PAGE_SHIFT;

	if (register_blkdev(MAJOR_NR, DEVICE_NAME, &trd_fops)) {
		printk(KERN_ERR DEVICE_NAME ": Unable to register_blkdev(%d)\n", MAJOR_NR);
		return -EBUSY;
	}

	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), trd_make_request);
	for (i=0;i<MAX_DEVS;i++) {
		trd_blocksizes[i] = TRD_BLOCK_SIZE;
		trd_blk_sizes[i] = trd_size;
	}

	blksize_size[MAJOR_NR] = trd_blocksizes;
	blk_size[MAJOR_NR] = trd_blk_sizes;

	printk(KERN_DEBUG DEVICE_NAME ": trd initialised size=%dk\n", 
	       trd_size);

	return 0;
}
예제 #2
0
void __exit mcdx_exit(void)
{
    int i;

	xinfo("cleanup_module called\n");

    for (i = 0; i < MCDX_NDRIVES; i++) {
		struct s_drive_stuff *stuffp;
        	if (unregister_cdrom(&mcdx_info)) {
			printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
			return;
		}
		stuffp = mcdx_stuffp[i];
		if (!stuffp) continue;
		release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
		free_irq(stuffp->irq, NULL);
		if (stuffp->toc) {
			xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc);
			kfree(stuffp->toc);
		}
		xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp);
		mcdx_stuffp[i] = NULL;
		kfree(stuffp);
    }

    if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
        xwarn("cleanup() unregister_blkdev() failed\n");
    }
	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
#if !MCDX_QUIET
	else xinfo("cleanup() succeeded\n");
예제 #3
0
int __init init_mtdblock(void)
{
	int i;

	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
		       MTD_BLOCK_MAJOR);
		return -EAGAIN;
	}
	DEBUG(MTD_DEBUG_LEVEL3,
		"init_mtdblock: allocated major number %d (read only).\n", 
		MTD_BLOCK_MAJOR);
	
	/* We fill it in at open() time. */
	for (i=0; i< MAX_MTD_DEVICES; i++) {
		mtd_sizes[i] = 0;
	}
	
	/* Allow the block size to default to BLOCK_SIZE. */
	blksize_size[MAJOR_NR] = NULL;
	blk_size[MAJOR_NR] = mtd_sizes;
	
	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
	return 0;
}
예제 #4
0
파일: xd.c 프로젝트: SnkBitten/amithlon4
/* xd_init: register the block device number and set up pointer tables */
int __init xd_init(void)
{
	init_timer (&xd_watchdog_int); 
	xd_watchdog_int.function = xd_watchdog;

	if (!xd_dma_buffer)
		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
	if (!xd_dma_buffer)
	{
		printk(KERN_ERR "xd: Out of memory.\n");
		return -ENOMEM;
	}

	if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
		printk(KERN_ERR "xd: Unable to get major number %d\n",MAJOR_NR);
		return -1;
	}
	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
	add_gendisk(&xd_gendisk);
	xd_geninit();

	return 0;
}
예제 #5
0
void sbull_cleanup(void)
{
    int i;

/*
 * Before anything else, get rid of the timer functions.  Set the "usage"
 * flag on each device as well, under lock, so that if the timer fires up
 * just before we delete it, it will either complete or abort.  Otherwise
 * we have nasty race conditions to worry about.
 */
    for (i = 0; i < sbull_devs; i++) {
        Sbull_Dev *dev = sbull_devices + i;
        del_timer(&dev->timer);
        spin_lock(&dev->lock);
        dev->usage++;
        spin_unlock(&dev->lock);
    }

#ifdef DO_RAW_INTERFACE
    sbullr_release();
#endif
    
    /* flush it all and reset all the data structures */


    for (i=0; i<sbull_devs; i++)
        fsync_dev(MKDEV(sbull_major, i)); /* flush the devices */
    unregister_blkdev(major, "sbull");
/*
 * Fix up the request queue(s)
 */
#ifdef SBULL_MULTIQUEUE
    for (i = 0; i < sbull_devs; i++)
            blk_cleanup_queue(&sbull_devices[i].queue);
    blk_dev[major].queue = NULL;
#else
    blk_cleanup_queue(BLK_DEFAULT_QUEUE(major));
#endif   

    /* Clean up the global arrays */
    read_ahead[major] = 0;
    kfree(blk_size[major]);
    blk_size[major] = NULL;
    kfree(blksize_size[major]);
    blksize_size[major] = NULL;
    kfree(hardsect_size[major]);
    hardsect_size[major] = NULL;
    /* FIXME: max_readahead and max_sectors */


    /* finally, the usual cleanup */
    for (i=0; i < sbull_devs; i++) {
        if (sbull_devices[i].data)
            vfree(sbull_devices[i].data);
    }
    kfree(sbull_devices);
}
static int __init radimo_init(void)
{
	int res;
	
	/* block size must be a multiple of sector size */
	if (radimo_soft & ((1 << RADIMO_HARDS_BITS)-1)) {
		MSG(RADIMO_ERROR, "Block size not a multiple of sector size\n");
		return -EINVAL;
	}
	
	/* allocate room for data */
	radimo_storage = (char *) vmalloc(1024*radimo_size);
	if (radimo_storage == NULL) {
		MSG(RADIMO_ERROR, "Not enough memory. Try a smaller size.\n");
		return -ENOMEM;
	}
	memset(radimo_storage, 0, 1024*radimo_size);
	
	/* register block device */
	res = register_blkdev(RADIMO_MAJOR, "radimo", &radimo_fops);
	if (res) {
		MSG(RADIMO_ERROR, "couldn't register block device\n");
		return res;
	}
	
	/* for media change */
	radimo_changed = 0;
	init_timer(&radimo_timer);
	
	/* set hard- and soft blocksize */
	hardsect_size[RADIMO_MAJOR] = &radimo_hard;
	blksize_size[RADIMO_MAJOR] = &radimo_soft;
	blk_size[RADIMO_MAJOR] = &radimo_size;
	
	/* define our request function */
/* Here's another instace where kernel versions really matter.
   The request queue interface changed in the 2.4 series kernels
*/

#if LINUX_VERSION_CODE < 0x20320
	blk_dev[RADIMO_MAJOR].request_fn = &radimo_request;
#else
        blk_init_queue(BLK_DEFAULT_QUEUE(RADIMO_MAJOR), radimo_request);
#endif
	read_ahead[RADIMO_MAJOR] = radimo_readahead;
	
	MSG(RADIMO_INFO, "loaded\n");
	MSG(RADIMO_INFO, "sector size of %d, block size of %d, total size = %dKb\n",
					radimo_hard, radimo_soft, radimo_size);
	
	return 0;
}
예제 #7
0
static void __exit radimo_cleanup(void)
{
	unregister_blkdev(RADIMO_MAJOR, "radimo");
	del_timer(&radimo_timer);

	invalidate_buffers(MKDEV(RADIMO_MAJOR,0));

	/* remove our request function */
        blk_cleanup_queue(BLK_DEFAULT_QUEUE(RADIMO_MAJOR));
	vfree(radimo_storage);

	MSG(RADIMO_INFO, "unloaded\n");
}	
예제 #8
0
파일: rd.c 프로젝트: nhanh0/hah
/* This is the registration and initialization section of the RAM disk driver */
int __init rd_init (void)
{
	int		i;

	if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
	    (rd_blocksize & (rd_blocksize-1)))
	{
		printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",
		       rd_blocksize);
		rd_blocksize = BLOCK_SIZE;
	}

	if (register_blkdev(MAJOR_NR, "ramdisk", &rd_bd_op)) {
		printk("RAMDISK: Could not get major %d", MAJOR_NR);
		return -EIO;
	}

	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), &rd_make_request);

	for (i = 0; i < NUM_RAMDISKS; i++) {
		/* rd_size is given in kB */
		rd_length[i] = rd_size << 10;
		rd_hardsec[i] = rd_blocksize;
		rd_blocksizes[i] = rd_blocksize;
		rd_kbsize[i] = rd_size;
	}
	devfs_handle = devfs_mk_dir (NULL, "rd", NULL);
	devfs_register_series (devfs_handle, "%u", NUM_RAMDISKS,
			       DEVFS_FL_DEFAULT, MAJOR_NR, 0,
			       S_IFBLK | S_IRUSR | S_IWUSR,
			       &rd_bd_op, NULL);

	for (i = 0; i < NUM_RAMDISKS; i++)
		register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &rd_bd_op, rd_size<<1);

#ifdef CONFIG_BLK_DEV_INITRD
	/* We ought to separate initrd operations here */
	register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1);
#endif

	hardsect_size[MAJOR_NR] = rd_hardsec;		/* Size of the RAM disk blocks */
	blksize_size[MAJOR_NR] = rd_blocksizes;		/* Avoid set_blocksize() check */
	blk_size[MAJOR_NR] = rd_kbsize;			/* Size of the RAM disk in kB  */

		/* rd_size is given in kB */
	printk("RAMDISK driver initialized: "
	       "%d RAM disks of %dK size %d blocksize\n",
	       NUM_RAMDISKS, rd_size, rd_blocksize);

	return 0;
}
예제 #9
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" );
}
static void __exit radimo_cleanup(void)
{
	unregister_blkdev(RADIMO_MAJOR, "radimo");
	del_timer(&radimo_timer);

	invalidate_buffers(MKDEV(RADIMO_MAJOR,0));

	/* remove our request function */
#if LINUX_VERSION_CODE < 0x20320
	blk_dev[RADIMO_MAJOR].request_fn = 0;
#else	
        blk_cleanup_queue(BLK_DEFAULT_QUEUE(RADIMO_MAJOR));
#endif
	vfree(radimo_storage);

	MSG(RADIMO_INFO, "unloaded\n");
}	
예제 #11
0
파일: mcd.c 프로젝트: fgeraci/cs518-sched
/* This routine gets called during initialization if things go wrong,
 * and is used in mcd_exit as well. */
static void cleanup(int level)
{
	switch (level) {
	case 3:
		if (unregister_cdrom(&mcd_info)) {
			printk(KERN_WARNING "Can't unregister cdrom mcd\n");
			return;
		}
		free_irq(mcd_irq, NULL);
	case 2:
		release_region(mcd_port, 4);
	case 1:
		if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
			printk(KERN_WARNING "Can't unregister major mcd\n");
			return;
		}
		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
	default:;
	}
}
예제 #12
0
파일: pd.c 프로젝트: TitaniumBoy/lin
int pd_init (void)

{       int i;
	request_queue_t * q; 

	if (disable) return -1;
        if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {
                printk("%s: unable to get major number %d\n",
                        name,major);
                return -1;
        }
	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
	blk_init_queue(q, DEVICE_REQUEST);
        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
        
	pd_gendisk.major = major;
	pd_gendisk.major_name = name;
	add_gendisk(&pd_gendisk);

	for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
	blksize_size[MAJOR_NR] = pd_blocksizes;

	for(i=0;i<PD_DEVS;i++) pd_maxsectors[i] = cluster;
	max_sectors[MAJOR_NR] = pd_maxsectors;

	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
		name,name,PD_VERSION,major,cluster,nice);
	pd_init_units();
	pd_valid = 0;
	pd_gendisk.nr_real = pd_detect();
	pd_valid = 1;

#ifdef MODULE
        if (!pd_gendisk.nr_real) {
		cleanup_module();
		return -1;
	}
#endif
        return 0;
}
예제 #13
0
int sbull_init(void)
{
    int result, i;

    /*
     * Copy the (static) cfg variables to public prefixed ones to allow
     * snoozing with a debugger.
     */

    sbull_major    = major;
    sbull_devs     = devs;
    sbull_rahead   = rahead;
    sbull_size     = size;
    sbull_blksize  = blksize;
    sbull_hardsect = hardsect;

#ifdef LINUX_20
    /* Hardsect can't be changed :( */
    if (hardsect != 512) {
        printk(KERN_ERR "sbull: can't change hardsect size\n");
        hardsect = sbull_hardsect = 512;
    }
#endif
    /*
     * Register your major, and accept a dynamic number
     */
    result = register_blkdev(sbull_major, "sbull", &sbull_fops);
    if (result < 0) {
        printk(KERN_WARNING "sbull: can't get major %d\n",sbull_major);
        return result;
    }
    if (sbull_major == 0) sbull_major = result; /* dynamic */
    major = sbull_major; /* Use `major' later on to save typing */

    /*
     * Assign the other needed values: request, rahead, size, blksize,
     * hardsect. All the minor devices feature the same value.
     * Note that `sbull' defines all of them to allow testing non-default
     * values. A real device could well avoid setting values in global
     * arrays if it uses the default values.
     */

    read_ahead[major] = sbull_rahead;
    result = -ENOMEM; /* for the possible errors */

    sbull_sizes = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_sizes)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same size */
        sbull_sizes[i] = sbull_size;
    blk_size[major]=sbull_sizes;

    sbull_blksizes = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_blksizes)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same blocksize */
        sbull_blksizes[i] = sbull_blksize;
    blksize_size[major]=sbull_blksizes;

    sbull_hardsects = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_hardsects)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same hardsect */
        sbull_hardsects[i] = sbull_hardsect;
    hardsect_size[major]=sbull_hardsects;

    /* FIXME: max_readahead and max_sectors */
    
    /* 
     * allocate the devices -- we can't have them static, as the number
     * can be specified at load time
     */

    sbull_devices = kmalloc(sbull_devs * sizeof (Sbull_Dev), GFP_KERNEL);
    if (!sbull_devices)
        goto fail_malloc;
    memset(sbull_devices, 0, sbull_devs * sizeof (Sbull_Dev));
    for (i=0; i < sbull_devs; i++) {
        /* data and usage remain zeroed */
        sbull_devices[i].size = 1024 * sbull_size;
        init_timer(&(sbull_devices[i].timer));
        sbull_devices[i].timer.data = (unsigned long)(sbull_devices+i);
        sbull_devices[i].timer.function = sbull_expires;
        spin_lock_init(&sbull_devices[i].lock);
    }

    /*
     * Get the queue set up, and register our (nonexistent) partitions.
     */  
#ifdef SBULL_MULTIQUEUE
    for (i = 0; i < sbull_devs; i++) {
        blk_init_queue(&sbull_devices[i].queue, sbull_request);
        blk_queue_headactive(&sbull_devices[i].queue, 0);
        blk_queue_pluggable(&sbull_devices[i].queue, sbull_plug);
    }
    blk_dev[major].queue = sbull_find_queue;
#else
#  ifdef LINUX_24
    if (noqueue)
    {
        blk_init_queue(BLK_DEFAULT_QUEUE(major), sbull_unused_request);
        blk_queue_make_request(BLK_DEFAULT_QUEUE(major), sbull_make_request);
    }
    else
#  endif /* LINUX_24 */
        blk_init_queue(BLK_DEFAULT_QUEUE(major), sbull_request);
#endif
    /* A no-op in 2.4.0, but all drivers seem to do it anyway */
    for (i = 0; i < sbull_devs; i++)
            register_disk(NULL, MKDEV(major, i), 1, &sbull_fops,
                            sbull_size << 1);

#ifndef SBULL_DEBUG
    EXPORT_NO_SYMBOLS; /* otherwise, leave global symbols visible */
#endif

    printk ("<1>sbull: init complete, %d devs, size %d blks %d hs %d\n",
                    sbull_devs, sbull_size, sbull_blksize, sbull_hardsect);
#ifdef SBULL_MULTIQUEUE
    printk ("<1>sbull: Using multiqueue request\n");
#elif defined(LINUX_24)
    if (noqueue)
            printk (KERN_INFO "sbull: using direct make_request\n");
#endif

#ifdef DO_RAW_INTERFACE
    sbullr_init();
#endif
    return 0; /* succeed */

  fail_malloc:
    read_ahead[major] = 0;
    if (sbull_sizes) kfree(sbull_sizes);
    blk_size[major] = NULL;
    if (sbull_blksizes) kfree(sbull_blksizes);
    blksize_size[major] = NULL;
    if (sbull_hardsects) kfree(sbull_hardsects);
    hardsect_size[major] = NULL;
    if (sbull_devices) kfree(sbull_devices);

    unregister_blkdev(major, "sbull");
    return result;
}
static void __exit cleanup_mtdblock(void)
{
	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
	blk_size[MAJOR_NR] = NULL;
	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
}
예제 #15
0
파일: mcd.c 프로젝트: fgeraci/cs518-sched
int __init mcd_init(void)
{
	int count;
	unsigned char result[3];
	char msg[80];

	if (mcd_port <= 0 || mcd_irq <= 0) {
		printk(KERN_INFO "mcd: not probing.\n");
		return -EIO;
	}

	if (devfs_register_blkdev(MAJOR_NR, "mcd", &mcd_bdops) != 0) {
		printk(KERN_ERR "mcd: Unable to get major %d for Mitsumi CD-ROM\n", MAJOR_NR);
		return -EIO;
	}
	if (check_region(mcd_port, 4)) {
		cleanup(1);
		printk(KERN_ERR "mcd: Initialization failed, I/O port (%X) already in use\n", mcd_port);
		return -EIO;
	}

	blksize_size[MAJOR_NR] = mcd_blocksizes;
	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST,
		       &mcd_spinlock);
	read_ahead[MAJOR_NR] = 4;

	/* check for card */

	outb(0, MCDPORT(1));	/* send reset */
	for (count = 0; count < 2000000; count++)
		(void) inb(MCDPORT(1));	/* delay a bit */

	outb(0x40, MCDPORT(0));	/* send get-stat cmd */
	for (count = 0; count < 2000000; count++)
		if (!(inb(MCDPORT(1)) & MFL_STATUS))
			break;

	if (count >= 2000000) {
		printk(KERN_INFO "mcd: initialisation failed - No mcd device at 0x%x irq %d\n",
		       mcd_port, mcd_irq);
		cleanup(1);
		return -EIO;
	}
	count = inb(MCDPORT(0));	/* pick up the status */

	outb(MCMD_GET_VERSION, MCDPORT(0));
	for (count = 0; count < 3; count++)
		if (getValue(result + count)) {
			printk(KERN_ERR "mcd: mitsumi get version failed at 0x%x\n",
			       mcd_port);
			cleanup(1);
			return -EIO;
		}

	if (result[0] == result[1] && result[1] == result[2]) {
		cleanup(1);
		return -EIO;
	}

	mcdVersion = result[2];

	if (mcdVersion >= 4)
		outb(4, MCDPORT(2));	/* magic happens */

	/* don't get the IRQ until we know for sure the drive is there */

	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) {
		printk(KERN_ERR "mcd: Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
		cleanup(1);
		return -EIO;
	}

	if (result[1] == 'D') {
		MCMD_DATA_READ = MCMD_2X_READ;
		/* Added flag to drop to 1x speed if too many errors */
		mcdDouble = 1;
	} else
		mcd_info.speed = 1;
	sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
		" irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
		mcd_port, mcd_irq);

	request_region(mcd_port, 4, "mcd");

	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
	outb(0x02, MCDPORT(0));
	outb(0x00, MCDPORT(0));
	getValue(result);

	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
	outb(0x10, MCDPORT(0));
	outb(0x04, MCDPORT(0));
	getValue(result);

	mcd_invalidate_buffers();
	mcdPresent = 1;

	mcd_info.dev = mk_kdev(MAJOR_NR, 0);

	if (register_cdrom(&mcd_info) != 0) {
		printk(KERN_ERR "mcd: Unable to register Mitsumi CD-ROM.\n");
		cleanup(3);
		return -EIO;
	}
	devfs_plain_cdrom(&mcd_info, &mcd_bdops);
	printk(msg);

	return 0;
}
예제 #16
0
/* 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;
}