Import 2.3.12pre2
[davej-history.git] / drivers / cdrom / gscd.c
blob07c36f51b3ca04ca963d3b883112f5190587e107
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.
37 /* These settings are for various debug-level. Leave they untouched ... */
38 #define NO_GSCD_DEBUG
39 #define NO_IOCTL_DEBUG
40 #define NO_MODULE_DEBUG
41 #define NO_FUTURE_WORK
42 /*------------------------*/
44 #include <linux/module.h>
46 #include <linux/malloc.h>
47 #include <linux/errno.h>
48 #include <linux/signal.h>
49 #include <linux/sched.h>
50 #include <linux/timer.h>
51 #include <linux/fs.h>
52 #include <linux/mm.h>
53 #include <linux/kernel.h>
54 #include <linux/cdrom.h>
55 #include <linux/ioport.h>
56 #include <linux/major.h>
57 #include <linux/string.h>
58 #include <linux/init.h>
60 #include <asm/system.h>
61 #include <asm/io.h>
62 #include <asm/uaccess.h>
64 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
65 #include <linux/blk.h>
66 #define gscd_port gscd /* for compatible parameter passing with "insmod" */
67 #include "gscd.h"
69 static int gscd_blocksizes[1] = {512};
71 static int gscdPresent = 0;
73 static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
74 static int gscd_bn = -1;
75 static short gscd_port = GSCD_BASE_ADDR;
76 MODULE_PARM(gscd, "h");
78 /* Kommt spaeter vielleicht noch mal dran ...
79 * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
80 */
82 static void gscd_transfer (void);
83 static void gscd_read_cmd (void);
84 static void gscd_hsg2msf (long hsg, struct msf *msf);
85 static void gscd_bin2bcd (unsigned char *p);
87 /* Schnittstellen zum Kern/FS */
89 static void do_gscd_request (void);
90 static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
91 static int gscd_open (struct inode *, struct file *);
92 static int gscd_release (struct inode *, struct file *);
93 static int check_gscd_med_chg (kdev_t);
95 /* GoldStar Funktionen */
97 static void cc_Reset (void);
98 static int wait_drv_ready (void);
99 static int find_drives (void);
100 static void cmd_out (int, char *, char *, int);
101 static void cmd_status (void);
102 static void cc_Ident (char *);
103 static void cc_SetSpeed (void);
104 static void init_cd_drive (int);
106 static int get_status (void);
107 static void clear_Audio (void);
108 static void cc_invalidate (void);
110 /* some things for the next version */
111 #ifdef FUTURE_WORK
112 static void update_state (void);
113 static long gscd_msf2hsg (struct msf *mp);
114 static int gscd_bcd2bin (unsigned char bcd);
115 #endif
117 /* common GoldStar Initialization */
119 static int my_gscd_init (void);
122 /* lo-level cmd-Funktionen */
124 static void cmd_info_in ( char *, int );
125 static void cmd_end ( void );
126 static void cmd_read_b ( char *, int, int );
127 static void cmd_read_w ( char *, int, int );
128 static int cmd_unit_alive ( void );
129 static void cmd_write_cmd ( char * );
132 /* GoldStar Variablen */
134 static int curr_drv_state;
135 static int drv_states[] = {0,0,0,0,0,0,0,0};
136 static int drv_mode;
137 static int disk_state;
138 static int speed;
139 static int ndrives;
141 static unsigned char drv_num_read;
142 static unsigned char f_dsk_valid;
143 static unsigned char current_drive;
144 static unsigned char f_drv_ok;
147 static char f_AudioPlay;
148 static char f_AudioPause;
149 static int AudioStart_m;
150 static int AudioStart_f;
151 static int AudioEnd_m;
152 static int AudioEnd_f;
155 static struct file_operations gscd_fops = {
156 NULL, /* lseek - default */
157 block_read, /* read - general block-dev read */
158 block_write, /* write - general block-dev write */
159 NULL, /* readdir - bad */
160 NULL, /* poll */
161 gscd_ioctl, /* ioctl */
162 NULL, /* mmap */
163 gscd_open, /* open */
164 NULL, /* flush */
165 gscd_release, /* release */
166 NULL, /* fsync */
167 NULL, /* fasync*/
168 check_gscd_med_chg, /* media change */
169 NULL /* revalidate */
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 void __init gscd_setup (char *str, int *ints)
199 if (ints[0] > 0)
201 gscd_port = ints[1];
206 static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
208 unsigned char to_do[10];
209 unsigned char dummy;
212 switch (cmd)
214 case CDROMSTART: /* Spin up the drive */
215 /* Don't think we can do this. Even if we could,
216 * I think the drive times out and stops after a while
217 * anyway. For now, ignore it.
219 return 0;
221 case CDROMRESUME: /* keine Ahnung was das ist */
222 return 0;
225 case CDROMEJECT:
226 cmd_status ();
227 to_do[0] = CMD_TRAY_CTL;
228 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
230 return 0;
232 default:
233 return -EINVAL;
240 * Take care of the different block sizes between cdrom and Linux.
241 * When Linux gets variable block sizes this will probably go away.
244 static void gscd_transfer (void)
246 long offs;
248 while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
250 offs = (CURRENT -> sector & 3) * 512;
251 memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
252 CURRENT -> nr_sectors--;
253 CURRENT -> sector++;
254 CURRENT -> buffer += 512;
260 * I/O request routine called from Linux kernel.
263 static void do_gscd_request (void)
265 unsigned int block,dev;
266 unsigned int nsect;
268 repeat:
269 if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) return;
270 INIT_REQUEST;
271 dev = MINOR(CURRENT->rq_dev);
272 block = CURRENT->sector;
273 nsect = CURRENT->nr_sectors;
275 if (CURRENT == NULL || CURRENT -> sector == -1)
276 return;
278 if (CURRENT -> cmd != READ)
280 printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
281 end_request(0);
282 goto repeat;
285 if (MINOR(CURRENT -> rq_dev) != 0)
287 printk("GSCD: this version supports only one device\n");
288 end_request(0);
289 goto repeat;
292 gscd_transfer();
294 /* if we satisfied the request from the buffer, we're done. */
296 if (CURRENT -> nr_sectors == 0)
298 end_request(1);
299 goto repeat;
302 #ifdef GSCD_DEBUG
303 printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
304 #endif
306 gscd_read_cmd ();
312 * Check the result of the set-mode command. On success, send the
313 * read-data command.
316 static void
317 gscd_read_cmd (void)
319 long block;
320 struct gscd_Play_msf gscdcmd;
321 char cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
325 cmd_status ();
326 if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
328 printk ( "GSCD: no disk or door open\n" );
329 end_request (0);
331 else
333 if ( disk_state & ST_INVALID )
335 printk ( "GSCD: disk invalid\n" );
336 end_request (0);
338 else
340 gscd_bn = -1; /* purge our buffer */
341 block = CURRENT -> sector / 4;
342 gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
344 cmd[2] = gscdcmd.start.min;
345 cmd[3] = gscdcmd.start.sec;
346 cmd[4] = gscdcmd.start.frame;
348 #ifdef GSCD_DEBUG
349 printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] );
350 #endif
351 cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
353 gscd_bn = CURRENT -> sector / 4;
354 gscd_transfer();
355 end_request(1);
358 SET_TIMER(do_gscd_request, 1);
363 * Open the device special file. Check that a disk is in.
366 static int gscd_open (struct inode *ip, struct file *fp)
368 int st;
370 #ifdef GSCD_DEBUG
371 printk ( "GSCD: open\n" );
372 #endif
374 if (gscdPresent == 0)
375 return -ENXIO; /* no hardware */
377 MOD_INC_USE_COUNT;
379 get_status ();
380 st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
381 if ( st )
383 printk ( "GSCD: no disk or door open\n" );
384 MOD_DEC_USE_COUNT;
385 return -ENXIO;
388 /* if (updateToc() < 0)
389 return -EIO;
392 return 0;
397 * On close, we flush all gscd blocks from the buffer cache.
400 static int gscd_release (struct inode * inode, struct file * file)
403 #ifdef GSCD_DEBUG
404 printk ( "GSCD: release\n" );
405 #endif
407 gscd_bn = -1;
408 sync_dev(inode->i_rdev);
409 invalidate_buffers(inode -> i_rdev);
411 MOD_DEC_USE_COUNT;
412 return 0;
416 int get_status (void)
418 int status;
420 cmd_status ();
421 status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
423 if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
425 cc_invalidate ();
426 return 1;
428 else
430 return 0;
435 void cc_invalidate (void)
437 drv_num_read = 0xFF;
438 f_dsk_valid = 0xFF;
439 current_drive = 0xFF;
440 f_drv_ok = 0xFF;
442 clear_Audio ();
446 void clear_Audio (void)
449 f_AudioPlay = 0;
450 f_AudioPause = 0;
451 AudioStart_m = 0;
452 AudioStart_f = 0;
453 AudioEnd_m = 0;
454 AudioEnd_f = 0;
459 * waiting ?
462 int wait_drv_ready (void)
464 int found, read;
468 found = inb ( GSCDPORT(0) );
469 found &= 0x0f;
470 read = inb ( GSCDPORT(0) );
471 read &= 0x0f;
472 } while ( read != found );
474 #ifdef GSCD_DEBUG
475 printk ( "Wait for: %d\n", read );
476 #endif
478 return read;
481 void cc_Ident (char * respons)
483 char to_do [] = {CMD_IDENT, 0, 0};
485 cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
489 void cc_SetSpeed (void)
491 char to_do [] = {CMD_SETSPEED, 0, 0};
492 char dummy;
494 if ( speed > 0 )
496 to_do[1] = speed & 0x0F;
497 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
502 void cc_Reset (void)
504 char to_do [] = {CMD_RESET, 0};
505 char dummy;
507 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
512 void cmd_status (void)
514 char to_do [] = {CMD_STATUS, 0};
515 char dummy;
517 cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
519 #ifdef GSCD_DEBUG
520 printk ("GSCD: Status: %d\n", disk_state );
521 #endif
525 void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
527 int result;
530 result = wait_drv_ready ();
531 if ( result != drv_mode )
533 unsigned long test_loops = 0xFFFF;
534 int i,dummy;
536 outb ( curr_drv_state, GSCDPORT(0));
538 /* LOCLOOP_170 */
541 result = wait_drv_ready ();
542 test_loops--;
543 } while ( (result != drv_mode) && (test_loops > 0) );
545 if ( result != drv_mode )
547 disk_state = ST_x08 | ST_x04 | ST_INVALID;
548 return;
551 /* ...and waiting */
552 for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
554 dummy *= i;
558 /* LOC_172 */
559 /* check the unit */
560 /* and wake it up */
561 if ( cmd_unit_alive () != 0x08 )
563 /* LOC_174 */
564 /* game over for this unit */
565 disk_state = ST_x08 | ST_x04 | ST_INVALID;
566 return;
569 /* LOC_176 */
570 #ifdef GSCD_DEBUG
571 printk ("LOC_176 ");
572 #endif
573 if ( drv_mode == 0x09 )
575 /* magic... */
576 printk ("GSCD: magic ...\n");
577 outb ( result, GSCDPORT(2));
580 /* write the command to the drive */
581 cmd_write_cmd (cmd);
583 /* LOC_178 */
584 for (;;)
586 result = wait_drv_ready ();
587 if ( result != drv_mode )
589 /* LOC_179 */
590 if ( result == 0x04 ) /* Mode 4 */
592 /* LOC_205 */
593 #ifdef GSCD_DEBUG
594 printk ("LOC_205 ");
595 #endif
596 disk_state = inb ( GSCDPORT (2));
600 result = wait_drv_ready ();
601 } while ( result != drv_mode );
602 return;
605 else
607 if ( result == 0x06 ) /* Mode 6 */
609 /* LOC_181 */
610 #ifdef GSCD_DEBUG
611 printk ("LOC_181 ");
612 #endif
614 if (cmd_type == TYPE_DATA)
616 /* read data */
617 /* LOC_184 */
618 if ( drv_mode == 9 )
620 /* read the data to the buffer (word) */
622 /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
623 cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
624 return;
626 else
628 /* read the data to the buffer (byte) */
630 /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
631 cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
632 return;
635 else
637 /* read the info to the buffer */
638 cmd_info_in ( respo_buf, respo_count );
639 return;
642 return;
647 else
649 disk_state = ST_x08 | ST_x04 | ST_INVALID;
650 return;
652 } /* for (;;) */
655 #ifdef GSCD_DEBUG
656 printk ("\n");
657 #endif
661 static void cmd_write_cmd ( char *pstr )
663 int i,j;
665 /* LOC_177 */
666 #ifdef GSCD_DEBUG
667 printk ("LOC_177 ");
668 #endif
670 /* calculate the number of parameter */
671 j = *pstr & 0x0F;
673 /* shift it out */
674 for ( i=0 ; i<j ; i++ )
676 outb ( *pstr, GSCDPORT(2) );
677 pstr++;
682 static int cmd_unit_alive ( void )
684 int result;
685 unsigned long max_test_loops;
688 /* LOC_172 */
689 #ifdef GSCD_DEBUG
690 printk ("LOC_172 ");
691 #endif
693 outb ( curr_drv_state, GSCDPORT(0));
694 max_test_loops = 0xFFFF;
698 result = wait_drv_ready ();
699 max_test_loops--;
700 } while ( (result != 0x08) && (max_test_loops > 0) );
702 return result;
706 static void cmd_info_in ( char *pb, int count )
708 int result;
709 char read;
712 /* read info */
713 /* LOC_182 */
714 #ifdef GSCD_DEBUG
715 printk ("LOC_182 ");
716 #endif
720 read = inb (GSCDPORT(2));
721 if ( count > 0 )
723 *pb = read;
724 pb++;
725 count--;
728 /* LOC_183 */
731 result = wait_drv_ready ();
732 } while ( result == 0x0E );
733 } while ( result == 6 );
735 cmd_end ();
736 return;
740 static void cmd_read_b ( char *pb, int count, int size )
742 int result;
743 int i;
746 /* LOC_188 */
747 /* LOC_189 */
748 #ifdef GSCD_DEBUG
749 printk ("LOC_189 ");
750 #endif
756 result = wait_drv_ready ();
757 } while ( result != 6 || result == 0x0E );
759 if ( result != 6 )
761 cmd_end ();
762 return;
765 #ifdef GSCD_DEBUG
766 printk ("LOC_191 ");
767 #endif
769 for ( i=0 ; i< size ; i++ )
771 *pb = inb (GSCDPORT(2));
772 pb++;
774 count--;
775 } while ( count > 0 );
777 cmd_end ();
778 return;
782 static void cmd_end (void)
784 int result;
787 /* LOC_204 */
788 #ifdef GSCD_DEBUG
789 printk ("LOC_204 ");
790 #endif
794 result = wait_drv_ready ();
795 if ( result == drv_mode )
797 return;
799 } while ( result != 4 );
801 /* LOC_205 */
802 #ifdef GSCD_DEBUG
803 printk ("LOC_205 ");
804 #endif
806 disk_state = inb ( GSCDPORT (2));
810 result = wait_drv_ready ();
811 } while ( result != drv_mode );
812 return;
817 static void cmd_read_w ( char *pb, int count, int size )
819 int result;
820 int i;
823 #ifdef GSCD_DEBUG
824 printk ("LOC_185 ");
825 #endif
829 /* LOC_185 */
832 result = wait_drv_ready ();
833 } while ( result != 6 || result == 0x0E );
835 if ( result != 6 )
837 cmd_end ();
838 return;
841 for ( i=0 ; i<size ; i++ )
843 /* na, hier muss ich noch mal drueber nachdenken */
844 *pb = inw(GSCDPORT(2));
845 pb++;
847 count--;
848 } while ( count > 0 );
850 cmd_end ();
851 return;
854 int __init find_drives (void)
856 int *pdrv;
857 int drvnum;
858 int subdrv;
859 int i;
861 speed = 0;
862 pdrv = (int *)&drv_states;
863 curr_drv_state = 0xFE;
864 subdrv = 0;
865 drvnum = 0;
867 for ( i=0 ; i<8 ; i++ )
869 subdrv++;
870 cmd_status ();
871 disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
872 if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
874 /* LOC_240 */
875 *pdrv = curr_drv_state;
876 init_cd_drive (drvnum);
877 pdrv++;
878 drvnum++;
880 else
882 if ( subdrv < 2 )
884 continue;
886 else
888 subdrv = 0;
892 /* curr_drv_state<<1; <-- das geht irgendwie nicht */
893 /* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
894 curr_drv_state *= 2;
895 curr_drv_state |= 1;
896 #ifdef GSCD_DEBUG
897 printk ("DriveState: %d\n", curr_drv_state );
898 #endif
901 ndrives = drvnum;
902 return drvnum;
905 void __init init_cd_drive ( int num )
907 char resp [50];
908 int i;
910 printk ("GSCD: init unit %d\n", num );
911 cc_Ident ((char *)&resp);
913 printk ("GSCD: identification: ");
914 for ( i=0 ; i<0x1E; i++ )
916 printk ( "%c", resp[i] );
918 printk ("\n");
920 cc_SetSpeed ();
924 #ifdef FUTURE_WORK
925 /* return_done */
926 static void update_state ( void )
928 unsigned int AX;
931 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
933 if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
935 AX = ST_INVALID;
938 if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
940 invalidate ();
941 f_drv_ok = 0;
944 AX |= 0x8000;
947 if ( disk_state & ST_PLAYING )
949 AX |= 0x200;
952 AX |= 0x100;
953 /* pkt_esbx = AX; */
955 disk_state = 0;
958 #endif
960 #ifdef MODULE
961 /* Init for the Module-Version */
962 int init_module (void)
964 long err;
967 /* call the GoldStar-init */
968 err = my_gscd_init ( );
970 if ( err < 0 )
972 return err;
974 else
976 printk (KERN_INFO "Happy GoldStar !\n" );
977 return 0;
981 void cleanup_module (void)
984 if ((unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
986 printk("What's that: can't unregister GoldStar-module\n" );
987 return;
990 release_region (gscd_port,4);
991 printk(KERN_INFO "GoldStar-module released.\n" );
993 #endif
996 /* Test for presence of drive and initialize it. Called only at boot time. */
997 int __init gscd_init (void)
999 return my_gscd_init ();
1003 /* This is the common initialisation for the GoldStar drive. */
1004 /* It is called at boot time AND for module init. */
1005 int __init my_gscd_init (void)
1007 int i;
1008 int result;
1010 printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
1011 printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
1013 if (check_region(gscd_port, 4))
1015 printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
1016 return -EIO;
1020 /* check for card */
1021 result = wait_drv_ready ();
1022 if ( result == 0x09 )
1024 printk ("GSCD: DMA kann ich noch nicht!\n" );
1025 return -EIO;
1028 if ( result == 0x0b )
1030 drv_mode = result;
1031 i = find_drives ();
1032 if ( i == 0 )
1034 printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
1035 return -EIO;
1039 if ( (result != 0x0b) && (result != 0x09) )
1041 printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
1042 return -EIO;
1045 /* reset all drives */
1046 i = 0;
1047 while ( drv_states[i] != 0 )
1049 curr_drv_state = drv_states[i];
1050 printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
1051 cc_Reset ();
1052 printk ( "done\n" );
1053 i++;
1056 if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
1058 printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
1059 MAJOR_NR);
1060 return -EIO;
1063 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1064 blksize_size[MAJOR_NR] = gscd_blocksizes;
1065 read_ahead[MAJOR_NR] = 4;
1067 disk_state = 0;
1068 gscdPresent = 1;
1070 request_region(gscd_port, 4, "gscd");
1072 printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
1073 return 0;
1076 static void gscd_hsg2msf (long hsg, struct msf *msf)
1078 hsg += CD_MSF_OFFSET;
1079 msf -> min = hsg / (CD_FRAMES*CD_SECS);
1080 hsg %= CD_FRAMES*CD_SECS;
1081 msf -> sec = hsg / CD_FRAMES;
1082 msf -> frame = hsg % CD_FRAMES;
1084 gscd_bin2bcd(&msf -> min); /* convert to BCD */
1085 gscd_bin2bcd(&msf -> sec);
1086 gscd_bin2bcd(&msf -> frame);
1090 static void gscd_bin2bcd (unsigned char *p)
1092 int u, t;
1094 u = *p % 10;
1095 t = *p / 10;
1096 *p = u | (t << 4);
1100 #ifdef FUTURE_WORK
1101 static long gscd_msf2hsg (struct msf *mp)
1103 return gscd_bcd2bin(mp -> frame)
1104 + gscd_bcd2bin(mp -> sec) * CD_FRAMES
1105 + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
1106 - CD_MSF_OFFSET;
1109 static int gscd_bcd2bin (unsigned char bcd)
1111 return (bcd >> 4) * 10 + (bcd & 0xF);
1113 #endif