Revert last change. Bug noticed by Linus.
[linux-2.6/linux-mips.git] / drivers / cdrom / gscd.c
blobdc887049131467752609bd02f00c3585adc6379b
1 #define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
3 /*
4 linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
6 Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
7 based upon pre-works by Eberhard Moenkeberg <emoenke@gwdg.de>
10 For all kind of other information about the GoldStar CDROM
11 and this Linux device driver I installed a WWW-URL:
12 http://linux.rz.fh-hannover.de/~raupach
15 If you are the editor of a Linux CD, you should
16 enable gscd.c within your boot floppy kernel and
17 send me one of your CDs for free.
20 --------------------------------------------------------------------
21 This program is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 2, or (at your option)
24 any later version.
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
31 You should have received a copy of the GNU General Public License
32 along with this program; if not, write to the Free Software
33 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 --------------------------------------------------------------------
37 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
38 Removed init_module & cleanup_module in favor of
39 module_init & module_exit.
40 Torben Mathiasen <tmm@image.dk>
44 /* These settings are for various debug-level. Leave they untouched ... */
45 #define NO_GSCD_DEBUG
46 #define NO_IOCTL_DEBUG
47 #define NO_MODULE_DEBUG
48 #define NO_FUTURE_WORK
49 /*------------------------*/
51 #include <linux/module.h>
53 #include <linux/malloc.h>
54 #include <linux/errno.h>
55 #include <linux/signal.h>
56 #include <linux/sched.h>
57 #include <linux/timer.h>
58 #include <linux/fs.h>
59 #include <linux/mm.h>
60 #include <linux/kernel.h>
61 #include <linux/cdrom.h>
62 #include <linux/ioport.h>
63 #include <linux/major.h>
64 #include <linux/string.h>
65 #include <linux/init.h>
66 #include <linux/devfs_fs_kernel.h>
68 #include <asm/system.h>
69 #include <asm/io.h>
70 #include <asm/uaccess.h>
72 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
73 #include <linux/blk.h>
74 #define gscd_port gscd /* for compatible parameter passing with "insmod" */
75 #include "gscd.h"
77 static int gscd_blocksizes[1] = {512};
79 static int gscdPresent = 0;
81 static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
82 static int gscd_bn = -1;
83 static short gscd_port = GSCD_BASE_ADDR;
84 MODULE_PARM(gscd, "h");
86 /* Kommt spaeter vielleicht noch mal dran ...
87 * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
88 */
90 static void gscd_transfer (void);
91 static void gscd_read_cmd (void);
92 static void gscd_hsg2msf (long hsg, struct msf *msf);
93 static void gscd_bin2bcd (unsigned char *p);
95 /* Schnittstellen zum Kern/FS */
97 static void do_gscd_request (request_queue_t *);
98 static void __do_gscd_request (unsigned long dummy);
99 static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
100 static int gscd_open (struct inode *, struct file *);
101 static int gscd_release (struct inode *, struct file *);
102 static int check_gscd_med_chg (kdev_t);
104 /* GoldStar Funktionen */
106 static void cc_Reset (void);
107 static int wait_drv_ready (void);
108 static int find_drives (void);
109 static void cmd_out (int, char *, char *, int);
110 static void cmd_status (void);
111 static void cc_Ident (char *);
112 static void cc_SetSpeed (void);
113 static void init_cd_drive (int);
115 static int get_status (void);
116 static void clear_Audio (void);
117 static void cc_invalidate (void);
119 /* some things for the next version */
120 #ifdef FUTURE_WORK
121 static void update_state (void);
122 static long gscd_msf2hsg (struct msf *mp);
123 static int gscd_bcd2bin (unsigned char bcd);
124 #endif
126 /* common GoldStar Initialization */
128 static int my_gscd_init (void);
131 /* lo-level cmd-Funktionen */
133 static void cmd_info_in ( char *, int );
134 static void cmd_end ( void );
135 static void cmd_read_b ( char *, int, int );
136 static void cmd_read_w ( char *, int, int );
137 static int cmd_unit_alive ( void );
138 static void cmd_write_cmd ( char * );
141 /* GoldStar Variablen */
143 static int curr_drv_state;
144 static int drv_states[] = {0,0,0,0,0,0,0,0};
145 static int drv_mode;
146 static int disk_state;
147 static int speed;
148 static int ndrives;
150 static unsigned char drv_num_read;
151 static unsigned char f_dsk_valid;
152 static unsigned char current_drive;
153 static unsigned char f_drv_ok;
156 static char f_AudioPlay;
157 static char f_AudioPause;
158 static int AudioStart_m;
159 static int AudioStart_f;
160 static int AudioEnd_m;
161 static int AudioEnd_f;
163 static struct timer_list gscd_timer;
165 static struct block_device_operations gscd_fops = {
166 open: gscd_open,
167 release: gscd_release,
168 ioctl: gscd_ioctl,
169 check_media_change: check_gscd_med_chg,
173 * Checking if the media has been changed
174 * (not yet implemented)
176 static int check_gscd_med_chg (kdev_t full_dev)
178 int target;
181 target = MINOR(full_dev);
183 if (target > 0)
185 printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
186 return 0;
189 #ifdef GSCD_DEBUG
190 printk ("gscd: check_med_change\n");
191 #endif
193 return 0;
197 #ifndef MODULE
198 /* Using new interface for kernel-parameters */
200 static int __init gscd_setup (char *str)
202 int ints[2];
203 (void)get_options(str, ARRAY_SIZE(ints), ints);
205 if (ints[0] > 0)
207 gscd_port = ints[1];
209 return 1;
212 __setup("gscd=", gscd_setup);
214 #endif
216 static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
218 unsigned char to_do[10];
219 unsigned char dummy;
222 switch (cmd)
224 case CDROMSTART: /* Spin up the drive */
225 /* Don't think we can do this. Even if we could,
226 * I think the drive times out and stops after a while
227 * anyway. For now, ignore it.
229 return 0;
231 case CDROMRESUME: /* keine Ahnung was das ist */
232 return 0;
235 case CDROMEJECT:
236 cmd_status ();
237 to_do[0] = CMD_TRAY_CTL;
238 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
240 return 0;
242 default:
243 return -EINVAL;
250 * Take care of the different block sizes between cdrom and Linux.
251 * When Linux gets variable block sizes this will probably go away.
254 static void gscd_transfer (void)
256 long offs;
258 while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
260 offs = (CURRENT -> sector & 3) * 512;
261 memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
262 CURRENT -> nr_sectors--;
263 CURRENT -> sector++;
264 CURRENT -> buffer += 512;
270 * I/O request routine called from Linux kernel.
273 static void do_gscd_request (request_queue_t * q)
275 __do_gscd_request(0);
278 static void __do_gscd_request (unsigned long dummy)
280 unsigned int block,dev;
281 unsigned int nsect;
283 repeat:
284 if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
285 goto out;
286 INIT_REQUEST;
287 dev = MINOR(CURRENT->rq_dev);
288 block = CURRENT->sector;
289 nsect = CURRENT->nr_sectors;
291 if (QUEUE_EMPTY || CURRENT -> sector == -1)
292 goto out;
294 if (CURRENT -> cmd != READ)
296 printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
297 end_request(0);
298 goto repeat;
301 if (MINOR(CURRENT -> rq_dev) != 0)
303 printk("GSCD: this version supports only one device\n");
304 end_request(0);
305 goto repeat;
308 gscd_transfer();
310 /* if we satisfied the request from the buffer, we're done. */
312 if (CURRENT -> nr_sectors == 0)
314 end_request(1);
315 goto repeat;
318 #ifdef GSCD_DEBUG
319 printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
320 #endif
322 gscd_read_cmd ();
323 out:
324 return;
330 * Check the result of the set-mode command. On success, send the
331 * read-data command.
334 static void
335 gscd_read_cmd (void)
337 long block;
338 struct gscd_Play_msf gscdcmd;
339 char cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
343 cmd_status ();
344 if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
346 printk ( "GSCD: no disk or door open\n" );
347 end_request (0);
349 else
351 if ( disk_state & ST_INVALID )
353 printk ( "GSCD: disk invalid\n" );
354 end_request (0);
356 else
358 gscd_bn = -1; /* purge our buffer */
359 block = CURRENT -> sector / 4;
360 gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
362 cmd[2] = gscdcmd.start.min;
363 cmd[3] = gscdcmd.start.sec;
364 cmd[4] = gscdcmd.start.frame;
366 #ifdef GSCD_DEBUG
367 printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] );
368 #endif
369 cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
371 gscd_bn = CURRENT -> sector / 4;
372 gscd_transfer();
373 end_request(1);
376 SET_TIMER(__do_gscd_request, 1);
381 * Open the device special file. Check that a disk is in.
384 static int gscd_open (struct inode *ip, struct file *fp)
386 int st;
388 #ifdef GSCD_DEBUG
389 printk ( "GSCD: open\n" );
390 #endif
392 if (gscdPresent == 0)
393 return -ENXIO; /* no hardware */
395 MOD_INC_USE_COUNT;
397 get_status ();
398 st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
399 if ( st )
401 printk ( "GSCD: no disk or door open\n" );
402 MOD_DEC_USE_COUNT;
403 return -ENXIO;
406 /* if (updateToc() < 0)
407 return -EIO;
410 return 0;
415 * On close, we flush all gscd blocks from the buffer cache.
418 static int gscd_release (struct inode * inode, struct file * file)
421 #ifdef GSCD_DEBUG
422 printk ( "GSCD: release\n" );
423 #endif
425 gscd_bn = -1;
427 MOD_DEC_USE_COUNT;
428 return 0;
432 int get_status (void)
434 int status;
436 cmd_status ();
437 status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
439 if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
441 cc_invalidate ();
442 return 1;
444 else
446 return 0;
451 void cc_invalidate (void)
453 drv_num_read = 0xFF;
454 f_dsk_valid = 0xFF;
455 current_drive = 0xFF;
456 f_drv_ok = 0xFF;
458 clear_Audio ();
462 void clear_Audio (void)
465 f_AudioPlay = 0;
466 f_AudioPause = 0;
467 AudioStart_m = 0;
468 AudioStart_f = 0;
469 AudioEnd_m = 0;
470 AudioEnd_f = 0;
475 * waiting ?
478 int wait_drv_ready (void)
480 int found, read;
484 found = inb ( GSCDPORT(0) );
485 found &= 0x0f;
486 read = inb ( GSCDPORT(0) );
487 read &= 0x0f;
488 } while ( read != found );
490 #ifdef GSCD_DEBUG
491 printk ( "Wait for: %d\n", read );
492 #endif
494 return read;
497 void cc_Ident (char * respons)
499 char to_do [] = {CMD_IDENT, 0, 0};
501 cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
505 void cc_SetSpeed (void)
507 char to_do [] = {CMD_SETSPEED, 0, 0};
508 char dummy;
510 if ( speed > 0 )
512 to_do[1] = speed & 0x0F;
513 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
518 void cc_Reset (void)
520 char to_do [] = {CMD_RESET, 0};
521 char dummy;
523 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
528 void cmd_status (void)
530 char to_do [] = {CMD_STATUS, 0};
531 char dummy;
533 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
535 #ifdef GSCD_DEBUG
536 printk ("GSCD: Status: %d\n", disk_state );
537 #endif
541 void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
543 int result;
546 result = wait_drv_ready ();
547 if ( result != drv_mode )
549 unsigned long test_loops = 0xFFFF;
550 int i,dummy;
552 outb ( curr_drv_state, GSCDPORT(0));
554 /* LOCLOOP_170 */
557 result = wait_drv_ready ();
558 test_loops--;
559 } while ( (result != drv_mode) && (test_loops > 0) );
561 if ( result != drv_mode )
563 disk_state = ST_x08 | ST_x04 | ST_INVALID;
564 return;
567 /* ...and waiting */
568 for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
570 dummy *= i;
574 /* LOC_172 */
575 /* check the unit */
576 /* and wake it up */
577 if ( cmd_unit_alive () != 0x08 )
579 /* LOC_174 */
580 /* game over for this unit */
581 disk_state = ST_x08 | ST_x04 | ST_INVALID;
582 return;
585 /* LOC_176 */
586 #ifdef GSCD_DEBUG
587 printk ("LOC_176 ");
588 #endif
589 if ( drv_mode == 0x09 )
591 /* magic... */
592 printk ("GSCD: magic ...\n");
593 outb ( result, GSCDPORT(2));
596 /* write the command to the drive */
597 cmd_write_cmd (cmd);
599 /* LOC_178 */
600 for (;;)
602 result = wait_drv_ready ();
603 if ( result != drv_mode )
605 /* LOC_179 */
606 if ( result == 0x04 ) /* Mode 4 */
608 /* LOC_205 */
609 #ifdef GSCD_DEBUG
610 printk ("LOC_205 ");
611 #endif
612 disk_state = inb ( GSCDPORT (2));
616 result = wait_drv_ready ();
617 } while ( result != drv_mode );
618 return;
621 else
623 if ( result == 0x06 ) /* Mode 6 */
625 /* LOC_181 */
626 #ifdef GSCD_DEBUG
627 printk ("LOC_181 ");
628 #endif
630 if (cmd_type == TYPE_DATA)
632 /* read data */
633 /* LOC_184 */
634 if ( drv_mode == 9 )
636 /* read the data to the buffer (word) */
638 /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
639 cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
640 return;
642 else
644 /* read the data to the buffer (byte) */
646 /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
647 cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
648 return;
651 else
653 /* read the info to the buffer */
654 cmd_info_in ( respo_buf, respo_count );
655 return;
658 return;
663 else
665 disk_state = ST_x08 | ST_x04 | ST_INVALID;
666 return;
668 } /* for (;;) */
671 #ifdef GSCD_DEBUG
672 printk ("\n");
673 #endif
677 static void cmd_write_cmd ( char *pstr )
679 int i,j;
681 /* LOC_177 */
682 #ifdef GSCD_DEBUG
683 printk ("LOC_177 ");
684 #endif
686 /* calculate the number of parameter */
687 j = *pstr & 0x0F;
689 /* shift it out */
690 for ( i=0 ; i<j ; i++ )
692 outb ( *pstr, GSCDPORT(2) );
693 pstr++;
698 static int cmd_unit_alive ( void )
700 int result;
701 unsigned long max_test_loops;
704 /* LOC_172 */
705 #ifdef GSCD_DEBUG
706 printk ("LOC_172 ");
707 #endif
709 outb ( curr_drv_state, GSCDPORT(0));
710 max_test_loops = 0xFFFF;
714 result = wait_drv_ready ();
715 max_test_loops--;
716 } while ( (result != 0x08) && (max_test_loops > 0) );
718 return result;
722 static void cmd_info_in ( char *pb, int count )
724 int result;
725 char read;
728 /* read info */
729 /* LOC_182 */
730 #ifdef GSCD_DEBUG
731 printk ("LOC_182 ");
732 #endif
736 read = inb (GSCDPORT(2));
737 if ( count > 0 )
739 *pb = read;
740 pb++;
741 count--;
744 /* LOC_183 */
747 result = wait_drv_ready ();
748 } while ( result == 0x0E );
749 } while ( result == 6 );
751 cmd_end ();
752 return;
756 static void cmd_read_b ( char *pb, int count, int size )
758 int result;
759 int i;
762 /* LOC_188 */
763 /* LOC_189 */
764 #ifdef GSCD_DEBUG
765 printk ("LOC_189 ");
766 #endif
772 result = wait_drv_ready ();
773 } while ( result != 6 || result == 0x0E );
775 if ( result != 6 )
777 cmd_end ();
778 return;
781 #ifdef GSCD_DEBUG
782 printk ("LOC_191 ");
783 #endif
785 for ( i=0 ; i< size ; i++ )
787 *pb = inb (GSCDPORT(2));
788 pb++;
790 count--;
791 } while ( count > 0 );
793 cmd_end ();
794 return;
798 static void cmd_end (void)
800 int result;
803 /* LOC_204 */
804 #ifdef GSCD_DEBUG
805 printk ("LOC_204 ");
806 #endif
810 result = wait_drv_ready ();
811 if ( result == drv_mode )
813 return;
815 } while ( result != 4 );
817 /* LOC_205 */
818 #ifdef GSCD_DEBUG
819 printk ("LOC_205 ");
820 #endif
822 disk_state = inb ( GSCDPORT (2));
826 result = wait_drv_ready ();
827 } while ( result != drv_mode );
828 return;
833 static void cmd_read_w ( char *pb, int count, int size )
835 int result;
836 int i;
839 #ifdef GSCD_DEBUG
840 printk ("LOC_185 ");
841 #endif
845 /* LOC_185 */
848 result = wait_drv_ready ();
849 } while ( result != 6 || result == 0x0E );
851 if ( result != 6 )
853 cmd_end ();
854 return;
857 for ( i=0 ; i<size ; i++ )
859 /* na, hier muss ich noch mal drueber nachdenken */
860 *pb = inw(GSCDPORT(2));
861 pb++;
863 count--;
864 } while ( count > 0 );
866 cmd_end ();
867 return;
870 int __init find_drives (void)
872 int *pdrv;
873 int drvnum;
874 int subdrv;
875 int i;
877 speed = 0;
878 pdrv = (int *)&drv_states;
879 curr_drv_state = 0xFE;
880 subdrv = 0;
881 drvnum = 0;
883 for ( i=0 ; i<8 ; i++ )
885 subdrv++;
886 cmd_status ();
887 disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
888 if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
890 /* LOC_240 */
891 *pdrv = curr_drv_state;
892 init_cd_drive (drvnum);
893 pdrv++;
894 drvnum++;
896 else
898 if ( subdrv < 2 )
900 continue;
902 else
904 subdrv = 0;
908 /* curr_drv_state<<1; <-- das geht irgendwie nicht */
909 /* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
910 curr_drv_state *= 2;
911 curr_drv_state |= 1;
912 #ifdef GSCD_DEBUG
913 printk ("DriveState: %d\n", curr_drv_state );
914 #endif
917 ndrives = drvnum;
918 return drvnum;
921 void __init init_cd_drive ( int num )
923 char resp [50];
924 int i;
926 printk ("GSCD: init unit %d\n", num );
927 cc_Ident ((char *)&resp);
929 printk ("GSCD: identification: ");
930 for ( i=0 ; i<0x1E; i++ )
932 printk ( "%c", resp[i] );
934 printk ("\n");
936 cc_SetSpeed ();
940 #ifdef FUTURE_WORK
941 /* return_done */
942 static void update_state ( void )
944 unsigned int AX;
947 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
949 if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
951 AX = ST_INVALID;
954 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
956 invalidate ();
957 f_drv_ok = 0;
960 AX |= 0x8000;
963 if ( disk_state & ST_PLAYING )
965 AX |= 0x200;
968 AX |= 0x100;
969 /* pkt_esbx = AX; */
971 disk_state = 0;
974 #endif
976 /* Init for the Module-Version */
977 int init_gscd(void)
979 long err;
982 /* call the GoldStar-init */
983 err = my_gscd_init ( );
985 if ( err < 0 )
987 return err;
989 else
991 printk (KERN_INFO "Happy GoldStar !\n" );
992 return 0;
996 void __exit exit_gscd(void)
999 del_timer_async(&gscd_timer);
1001 devfs_unregister(devfs_find_handle(NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK,
1002 0));
1003 if ((devfs_unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
1005 printk("What's that: can't unregister GoldStar-module\n" );
1006 return;
1008 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1009 release_region (gscd_port,4);
1010 printk(KERN_INFO "GoldStar-module released.\n" );
1013 #ifdef MODULE
1014 module_init(init_gscd);
1015 #endif
1016 module_exit(exit_gscd);
1019 /* Test for presence of drive and initialize it. Called only at boot time. */
1020 int __init gscd_init (void)
1022 return my_gscd_init ();
1026 /* This is the common initialisation for the GoldStar drive. */
1027 /* It is called at boot time AND for module init. */
1028 int __init my_gscd_init (void)
1030 int i;
1031 int result;
1033 printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
1034 printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
1036 if (check_region(gscd_port, 4))
1038 printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
1039 return -EIO;
1043 /* check for card */
1044 result = wait_drv_ready ();
1045 if ( result == 0x09 )
1047 printk ("GSCD: DMA kann ich noch nicht!\n" );
1048 return -EIO;
1051 if ( result == 0x0b )
1053 drv_mode = result;
1054 i = find_drives ();
1055 if ( i == 0 )
1057 printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
1058 return -EIO;
1062 if ( (result != 0x0b) && (result != 0x09) )
1064 printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
1065 return -EIO;
1068 /* reset all drives */
1069 i = 0;
1070 while ( drv_states[i] != 0 )
1072 curr_drv_state = drv_states[i];
1073 printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
1074 cc_Reset ();
1075 printk ( "done\n" );
1076 i++;
1079 if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
1081 printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
1082 MAJOR_NR);
1083 return -EIO;
1085 devfs_register (NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
1086 S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
1088 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1089 blksize_size[MAJOR_NR] = gscd_blocksizes;
1090 read_ahead[MAJOR_NR] = 4;
1092 disk_state = 0;
1093 gscdPresent = 1;
1095 request_region(gscd_port, 4, "gscd");
1096 register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &gscd_fops, 0);
1098 printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
1099 return 0;
1102 static void gscd_hsg2msf (long hsg, struct msf *msf)
1104 hsg += CD_MSF_OFFSET;
1105 msf -> min = hsg / (CD_FRAMES*CD_SECS);
1106 hsg %= CD_FRAMES*CD_SECS;
1107 msf -> sec = hsg / CD_FRAMES;
1108 msf -> frame = hsg % CD_FRAMES;
1110 gscd_bin2bcd(&msf -> min); /* convert to BCD */
1111 gscd_bin2bcd(&msf -> sec);
1112 gscd_bin2bcd(&msf -> frame);
1116 static void gscd_bin2bcd (unsigned char *p)
1118 int u, t;
1120 u = *p % 10;
1121 t = *p / 10;
1122 *p = u | (t << 4);
1126 #ifdef FUTURE_WORK
1127 static long gscd_msf2hsg (struct msf *mp)
1129 return gscd_bcd2bin(mp -> frame)
1130 + gscd_bcd2bin(mp -> sec) * CD_FRAMES
1131 + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
1132 - CD_MSF_OFFSET;
1135 static int gscd_bcd2bin (unsigned char bcd)
1137 return (bcd >> 4) * 10 + (bcd & 0xF);
1139 #endif