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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [cdrom/] [gscd.c] - Blame information for rev 1765

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

Line No. Rev Author Line
1 199 simons
#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
2
 
3
/*
4
        linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
5
 
6
        Copyright (C) 1995  Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
7
        based upon pre-works by   Eberhard Moenkeberg <emoenke@gwdg.de>
8
 
9
 
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
13
 
14
 
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.
18
 
19
 
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.
25
 
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.
30
 
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.
34
 
35
*/
36
 
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
/*------------------------*/
43
 
44
#include <linux/module.h>
45
 
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
 
59
#include <asm/system.h>
60
#include <asm/io.h>
61
#include <asm/segment.h>
62
 
63
#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
64
#include <linux/blk.h>
65
#define gscd_port gscd /* for compatible parameter passing with "insmod" */
66
#include <linux/gscd.h>
67
 
68
 
69
static int gscdPresent            = 0;
70
 
71
static unsigned char gscd_buf[2048];    /* buffer for block size conversion */
72
static int   gscd_bn              = -1;
73
static short gscd_port            = GSCD_BASE_ADDR;
74
 
75
/* Kommt spaeter vielleicht noch mal dran ...
76
 *    static struct wait_queue *gscd_waitq = NULL;
77
 */
78
 
79
static void gscd_transfer         (void);
80
static void gscd_read_cmd         (void);
81
static void gscd_hsg2msf          (long hsg, struct msf *msf);
82
static void gscd_bin2bcd          (unsigned char *p);
83
 
84
/* Schnittstellen zum Kern/FS */
85
 
86
static void do_gscd_request       (void);
87
static int  gscd_ioctl            (struct inode *, struct file *, unsigned int, unsigned long);
88
static int  gscd_open             (struct inode *, struct file *);
89
static void gscd_release          (struct inode *, struct file *);
90
static int  check_gscd_med_chg    (kdev_t);
91
 
92
/*      GoldStar Funktionen    */
93
 
94
static void cc_Reset             (void);
95
static int  wait_drv_ready       (void);
96
static int  find_drives          (void);
97
static void cmd_out              (int, char *, char *, int);
98
static void cmd_status           (void);
99
static void cc_Ident             (char *);
100
static void cc_SetSpeed          (void);
101
static void init_cd_drive        (int);
102
 
103
static int  get_status           (void);
104
static void clear_Audio          (void);
105
static void cc_invalidate        (void);
106
 
107
/* some things for the next version */
108
#ifdef FUTURE_WORK
109
static void update_state          (void);
110
static long gscd_msf2hsg          (struct msf *mp);
111
static int  gscd_bcd2bin          (unsigned char bcd);
112
#endif
113
 
114
/*    common GoldStar Initialization    */
115
 
116
static int my_gscd_init (void);
117
 
118
 
119
/*      lo-level cmd-Funktionen    */
120
 
121
static void cmd_info_in          ( char *, int );
122
static void cmd_end              ( void );
123
static void cmd_read_b           ( char *, int, int );
124
static void cmd_read_w           ( char *, int, int );
125
static int  cmd_unit_alive       ( void );
126
static void cmd_write_cmd        ( char * );
127
 
128
 
129
/*      GoldStar Variablen     */
130
 
131
static int  curr_drv_state;
132
static int  drv_states[]       = {0,0,0,0,0,0,0,0};
133
static int  drv_mode;
134
static int  disk_state;
135
static int  speed;
136
static int  ndrives;
137
 
138
static unsigned char drv_num_read;
139
static unsigned char f_dsk_valid;
140
static unsigned char current_drive;
141
static unsigned char f_drv_ok;
142
 
143
 
144
static char f_AudioPlay;
145
static char f_AudioPause;
146
static int  AudioStart_m;
147
static int  AudioStart_f;
148
static int  AudioEnd_m;
149
static int  AudioEnd_f;
150
 
151
 
152
static struct file_operations gscd_fops = {
153
        NULL,                   /* lseek - default */
154
        block_read,             /* read - general block-dev read */
155
        block_write,            /* write - general block-dev write */
156
        NULL,                   /* readdir - bad */
157
        NULL,                   /* select */
158
        gscd_ioctl,             /* ioctl */
159
        NULL,                   /* mmap */
160
        gscd_open,              /* open */
161
        gscd_release,           /* release */
162
        NULL,                   /* fsync */
163
        NULL,                   /* fasync*/
164
        check_gscd_med_chg,     /* media change */
165
        NULL                    /* revalidate */
166
};
167
 
168
/*
169
 * Checking if the media has been changed
170
 * (not yet implemented)
171
 */
172
static int check_gscd_med_chg (kdev_t full_dev)
173
{
174
   int target;
175
 
176
 
177
   target = MINOR(full_dev);
178
 
179
   if (target > 0)
180
   {
181
      printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
182
      return 0;
183
   }
184
 
185
   #ifdef GSCD_DEBUG
186
   printk ("gscd: check_med_change\n");
187
   #endif
188
 
189
  return 0;
190
}
191
 
192
 
193
void gscd_setup (char *str, int *ints)
194
{
195
  if (ints[0] > 0)
196
  {
197
     gscd_port = ints[1];
198
  }
199
}
200
 
201
 
202
static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
203
{
204
unsigned char to_do[10];
205
unsigned char dummy;
206
 
207
 
208
    switch (cmd)
209
    {
210
       case CDROMSTART:     /* Spin up the drive */
211
                /* Don't think we can do this.  Even if we could,
212
                 * I think the drive times out and stops after a while
213
                 * anyway.  For now, ignore it.
214
                 */
215
            return 0;
216
 
217
       case CDROMRESUME:   /* keine Ahnung was das ist */
218
            return 0;
219
 
220
 
221
       case CDROMEJECT:
222
            cmd_status ();
223
            to_do[0] = CMD_TRAY_CTL;
224
            cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
225
 
226
            return 0;
227
 
228
       default:
229
            return -EINVAL;
230
    }
231
 
232
}
233
 
234
 
235
/*
236
 * Take care of the different block sizes between cdrom and Linux.
237
 * When Linux gets variable block sizes this will probably go away.
238
 */
239
 
240
static void gscd_transfer (void)
241
{
242
long offs;
243
 
244
        while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
245
        {
246
                offs = (CURRENT -> sector & 3) * 512;
247
                memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
248
                CURRENT -> nr_sectors--;
249
                CURRENT -> sector++;
250
                CURRENT -> buffer += 512;
251
        }
252
}
253
 
254
 
255
/*
256
 * I/O request routine called from Linux kernel.
257
 */
258
 
259
static void do_gscd_request (void)
260
{
261
unsigned int block,dev;
262
unsigned int nsect;
263
 
264
repeat:
265
        if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) return;
266
        INIT_REQUEST;
267
        dev = MINOR(CURRENT->rq_dev);
268
        block = CURRENT->sector;
269
        nsect = CURRENT->nr_sectors;
270
 
271
        if (CURRENT == NULL || CURRENT -> sector == -1)
272
                return;
273
 
274
        if (CURRENT -> cmd != READ)
275
        {
276
                printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
277
                end_request(0);
278
                goto repeat;
279
        }
280
 
281
        if (MINOR(CURRENT -> rq_dev) != 0)
282
        {
283
                printk("GSCD: this version supports only one device\n");
284
                end_request(0);
285
                goto repeat;
286
        }
287
 
288
        gscd_transfer();
289
 
290
        /* if we satisfied the request from the buffer, we're done. */
291
 
292
        if (CURRENT -> nr_sectors == 0)
293
        {
294
                end_request(1);
295
                goto repeat;
296
        }
297
 
298
#ifdef GSCD_DEBUG
299
        printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
300
#endif
301
 
302
        gscd_read_cmd ();
303
}
304
 
305
 
306
 
307
/*
308
 * Check the result of the set-mode command.  On success, send the
309
 * read-data command.
310
 */
311
 
312
static void
313
gscd_read_cmd (void)
314
{
315
long   block;
316
struct gscd_Play_msf gscdcmd;
317
char   cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
318
 
319
 
320
 
321
        cmd_status ();
322
        if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
323
        {
324
           printk ( "GSCD: no disk or door open\n" );
325
           end_request (0);
326
        }
327
        else
328
        {
329
           if ( disk_state & ST_INVALID )
330
           {
331
              printk ( "GSCD: disk invalid\n" );
332
              end_request (0);
333
           }
334
           else
335
           {
336
              gscd_bn = -1;             /* purge our buffer */
337
              block = CURRENT -> sector / 4;
338
              gscd_hsg2msf(block, &gscdcmd.start);      /* cvt to msf format */
339
 
340
              cmd[2] = gscdcmd.start.min;
341
              cmd[3] = gscdcmd.start.sec;
342
              cmd[4] = gscdcmd.start.frame;
343
 
344
#ifdef GSCD_DEBUG
345
              printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] );
346
#endif 
347
              cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
348
 
349
              gscd_bn = CURRENT -> sector / 4;
350
              gscd_transfer();
351
              end_request(1);
352
           }
353
        }
354
        SET_TIMER(do_gscd_request, 1);
355
}
356
 
357
 
358
/*
359
 * Open the device special file.  Check that a disk is in.
360
 */
361
 
362
static int gscd_open (struct inode *ip, struct file *fp)
363
{
364
int   st;
365
 
366
#ifdef GSCD_DEBUG
367
printk ( "GSCD: open\n" );
368
#endif
369
 
370
        if (gscdPresent == 0)
371
                return -ENXIO;                  /* no hardware */
372
 
373
        MOD_INC_USE_COUNT;
374
 
375
        get_status ();
376
        st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
377
        if ( st )
378
        {
379
           printk ( "GSCD: no disk or door open\n" );
380
           MOD_DEC_USE_COUNT;
381
           return -ENXIO;
382
        }
383
 
384
/*      if (updateToc() < 0)
385
                return -EIO;
386
*/
387
 
388
        return 0;
389
}
390
 
391
 
392
/*
393
 * On close, we flush all gscd blocks from the buffer cache.
394
 */
395
 
396
static void gscd_release (struct inode * inode, struct file * file)
397
{
398
 
399
#ifdef GSCD_DEBUG
400
printk ( "GSCD: release\n" );
401
#endif
402
 
403
        gscd_bn = -1;
404
        sync_dev(inode->i_rdev);
405
        invalidate_buffers(inode -> i_rdev);
406
 
407
        MOD_DEC_USE_COUNT;
408
}
409
 
410
 
411
int get_status (void)
412
{
413
int  status;
414
 
415
    cmd_status ();
416
    status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
417
 
418
    if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
419
    {
420
       cc_invalidate ();
421
       return 1;
422
    }
423
    else
424
    {
425
       return 0;
426
    }
427
}
428
 
429
 
430
void cc_invalidate (void)
431
{
432
   drv_num_read  = 0xFF;
433
   f_dsk_valid   = 0xFF;
434
   current_drive = 0xFF;
435
   f_drv_ok      = 0xFF;
436
 
437
   clear_Audio ();
438
 
439
}
440
 
441
void clear_Audio (void)
442
{
443
 
444
   f_AudioPlay = 0;
445
   f_AudioPause = 0;
446
   AudioStart_m = 0;
447
   AudioStart_f = 0;
448
   AudioEnd_m   = 0;
449
   AudioEnd_f   = 0;
450
 
451
}
452
 
453
/*
454
 *   waiting ?
455
 */
456
 
457
int wait_drv_ready (void)
458
{
459
int found, read;
460
 
461
   do
462
   {
463
       found = inb ( GSCDPORT(0) );
464
       found &= 0x0f;
465
       read  = inb ( GSCDPORT(0) );
466
       read  &= 0x0f;
467
   } while ( read != found );
468
 
469
#ifdef GSCD_DEBUG
470
printk ( "Wait for: %d\n", read );
471
#endif   
472
 
473
   return read;
474
}
475
 
476
void cc_Ident (char * respons)
477
{
478
char to_do [] = {CMD_IDENT, 0, 0};
479
 
480
    cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
481
 
482
}
483
 
484
void cc_SetSpeed (void)
485
{
486
char to_do [] = {CMD_SETSPEED, 0, 0};
487
char dummy;
488
 
489
    if ( speed > 0 )
490
    {
491
       to_do[1] = speed & 0x0F;
492
       cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
493
    }
494
}
495
 
496
 
497
void cc_Reset (void)
498
{
499
char to_do [] = {CMD_RESET, 0};
500
char dummy;
501
 
502
   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
503
}
504
 
505
 
506
 
507
void cmd_status (void)
508
{
509
char to_do [] = {CMD_STATUS, 0};
510
char dummy;
511
 
512
   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
513
 
514
#ifdef GSCD_DEBUG
515
printk ("GSCD: Status: %d\n", disk_state );
516
#endif
517
 
518
}
519
 
520
void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
521
{
522
int        result;
523
 
524
 
525
       result = wait_drv_ready ();
526
       if ( result != drv_mode )
527
       {
528
       unsigned long test_loops = 0xFFFF;
529
       int           i,dummy;
530
 
531
          outb ( curr_drv_state, GSCDPORT(0));
532
 
533
          /* LOCLOOP_170 */
534
          do
535
          {
536
             result = wait_drv_ready ();
537
             test_loops--;
538
          } while ( (result != drv_mode) && (test_loops > 0) );
539
 
540
          if ( result != drv_mode )
541
          {
542
             disk_state = ST_x08 | ST_x04 | ST_INVALID;
543
             return;
544
          }
545
 
546
          /* ...and waiting */
547
          for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
548
          {
549
             dummy *= i;
550
          }
551
       }
552
 
553
       /* LOC_172 */
554
       /* check the unit */
555
       /* and wake it up */
556
       if ( cmd_unit_alive () != 0x08 )
557
       {
558
          /* LOC_174 */
559
          /* game over for this unit */
560
          disk_state = ST_x08 | ST_x04 | ST_INVALID;
561
          return;
562
       }
563
 
564
       /* LOC_176 */
565
       #ifdef GSCD_DEBUG
566
        printk ("LOC_176 ");
567
       #endif       
568
       if ( drv_mode == 0x09 )
569
       {
570
          /* magic... */
571
          printk ("GSCD: magic ...\n");
572
          outb ( result, GSCDPORT(2));
573
       }
574
 
575
       /* write the command to the drive */
576
       cmd_write_cmd (cmd);
577
 
578
       /* LOC_178 */
579
       for (;;)
580
       {
581
          result = wait_drv_ready ();
582
          if ( result != drv_mode )
583
          {
584
             /* LOC_179 */
585
             if ( result == 0x04 )                  /* Mode 4 */
586
             {
587
                /* LOC_205 */
588
                #ifdef GSCD_DEBUG
589
                printk ("LOC_205 ");
590
                #endif
591
                disk_state = inb ( GSCDPORT (2));
592
 
593
                do
594
                {
595
                   result = wait_drv_ready ();
596
                } while ( result != drv_mode );
597
                return;
598
 
599
             }
600
             else
601
             {
602
                if ( result == 0x06 )               /* Mode 6 */
603
                {
604
                   /* LOC_181 */
605
                   #ifdef GSCD_DEBUG
606
                    printk ("LOC_181 ");
607
                   #endif
608
 
609
                   if (cmd_type == TYPE_DATA)
610
                   {
611
                      /* read data */
612
                      /* LOC_184 */
613
                      if ( drv_mode == 9 )
614
                      {
615
                         /* read the data to the buffer (word) */
616
 
617
                         /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
618
                         cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
619
                         return;
620
                      }
621
                      else
622
                      {
623
                         /* read the data to the buffer (byte) */
624
 
625
                         /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
626
                         cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
627
                         return;
628
                      }
629
                   }
630
                   else
631
                   {
632
                      /* read the info to the buffer */
633
                      cmd_info_in ( respo_buf, respo_count );
634
                      return;
635
                   }
636
 
637
                   return;
638
                }
639
             }
640
 
641
          }
642
          else
643
          {
644
             disk_state = ST_x08 | ST_x04 | ST_INVALID;
645
             return;
646
          }
647
       } /* for (;;) */
648
 
649
 
650
#ifdef GSCD_DEBUG
651
printk ("\n");
652
#endif    
653
}
654
 
655
 
656
static void cmd_write_cmd ( char *pstr )
657
{
658
int  i,j;
659
 
660
    /* LOC_177 */
661
    #ifdef GSCD_DEBUG
662
     printk ("LOC_177 ");
663
    #endif
664
 
665
    /* calculate the number of parameter */
666
    j = *pstr & 0x0F;
667
 
668
    /* shift it out */
669
    for ( i=0 ; i<j ; i++ )
670
    {
671
       outb ( *pstr, GSCDPORT(2) );
672
       pstr++;
673
    }
674
}
675
 
676
 
677
static int cmd_unit_alive ( void )
678
{
679
int            result;
680
unsigned long  max_test_loops;
681
 
682
 
683
    /* LOC_172 */
684
    #ifdef GSCD_DEBUG
685
     printk ("LOC_172 ");
686
    #endif
687
 
688
    outb ( curr_drv_state, GSCDPORT(0));
689
    max_test_loops = 0xFFFF;
690
 
691
    do
692
    {
693
       result = wait_drv_ready ();
694
       max_test_loops--;
695
    } while ( (result != 0x08) && (max_test_loops > 0) );
696
 
697
    return result;
698
}
699
 
700
 
701
static void cmd_info_in ( char *pb, int count )
702
{
703
int   result;
704
char  read;
705
 
706
 
707
        /* read info */
708
        /* LOC_182 */
709
        #ifdef GSCD_DEBUG
710
         printk ("LOC_182 ");
711
        #endif
712
 
713
        do
714
        {
715
           read = inb (GSCDPORT(2));
716
           if ( count > 0 )
717
           {
718
              *pb = read;
719
              pb++;
720
              count--;
721
           }
722
 
723
           /* LOC_183 */
724
           do
725
           {
726
              result = wait_drv_ready ();
727
           } while ( result == 0x0E );
728
        } while ( result == 6 );
729
 
730
        cmd_end ();
731
        return;
732
}
733
 
734
 
735
static void cmd_read_b ( char *pb, int count, int size )
736
{
737
int  result;
738
int  i;
739
 
740
 
741
       /* LOC_188 */
742
       /* LOC_189 */
743
       #ifdef GSCD_DEBUG
744
        printk ("LOC_189 ");
745
       #endif
746
 
747
       do
748
       {
749
          do
750
          {
751
             result = wait_drv_ready ();
752
          } while ( result != 6 || result == 0x0E );
753
 
754
          if ( result != 6 )
755
          {
756
             cmd_end ();
757
             return;
758
          }
759
 
760
          #ifdef GSCD_DEBUG
761
           printk ("LOC_191 ");
762
          #endif
763
 
764
          for ( i=0 ; i< size ; i++ )
765
          {
766
             *pb = inb (GSCDPORT(2));
767
             pb++;
768
          }
769
          count--;
770
       } while ( count > 0 );
771
 
772
       cmd_end ();
773
       return;
774
}
775
 
776
 
777
static void cmd_end (void)
778
{
779
int   result;
780
 
781
 
782
      /* LOC_204 */
783
      #ifdef GSCD_DEBUG
784
       printk ("LOC_204 ");
785
      #endif
786
 
787
      do
788
      {
789
         result = wait_drv_ready ();
790
         if ( result == drv_mode )
791
         {
792
            return;
793
         }
794
      } while ( result != 4 );
795
 
796
      /* LOC_205 */
797
      #ifdef GSCD_DEBUG
798
       printk ("LOC_205 ");
799
      #endif
800
 
801
      disk_state = inb ( GSCDPORT (2));
802
 
803
      do
804
      {
805
         result = wait_drv_ready ();
806
      } while ( result != drv_mode );
807
      return;
808
 
809
}
810
 
811
 
812
static void cmd_read_w ( char *pb, int count, int size )
813
{
814
int  result;
815
int  i;
816
 
817
 
818
    #ifdef GSCD_DEBUG
819
     printk ("LOC_185 ");
820
    #endif
821
 
822
    do
823
    {
824
       /* LOC_185 */
825
       do
826
       {
827
          result = wait_drv_ready ();
828
       } while ( result != 6 || result == 0x0E );
829
 
830
       if ( result != 6 )
831
       {
832
          cmd_end ();
833
          return;
834
       }
835
 
836
       for ( i=0 ; i<size ; i++ )
837
       {
838
           /* na, hier muss ich noch mal drueber nachdenken */
839
           *pb = inw(GSCDPORT(2));
840
           pb++;
841
        }
842
        count--;
843
     } while ( count > 0 );
844
 
845
     cmd_end ();
846
     return;
847
}
848
 
849
int find_drives (void)
850
{
851
int *pdrv;
852
int drvnum;
853
int subdrv;
854
int i;
855
 
856
    speed           = 0;
857
    pdrv            = (int *)&drv_states;
858
    curr_drv_state  = 0xFE;
859
    subdrv          = 0;
860
    drvnum          = 0;
861
 
862
    for ( i=0 ; i<8 ; i++ )
863
    {
864
       subdrv++;
865
       cmd_status ();
866
       disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
867
       if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
868
       {
869
          /* LOC_240 */
870
          *pdrv = curr_drv_state;
871
          init_cd_drive (drvnum);
872
          pdrv++;
873
          drvnum++;
874
       }
875
       else
876
       {
877
          if ( subdrv < 2 )
878
          {
879
             continue;
880
          }
881
          else
882
          {
883
             subdrv = 0;
884
          }
885
       }
886
 
887
/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */
888
/* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
889
         curr_drv_state *= 2;
890
         curr_drv_state |= 1;
891
#ifdef GSCD_DEBUG
892
         printk ("DriveState: %d\n", curr_drv_state );
893
#endif
894
    }
895
 
896
    ndrives = drvnum;
897
    return drvnum;
898
}
899
 
900
void init_cd_drive ( int num )
901
{
902
char resp [50];
903
int  i;
904
 
905
   printk ("GSCD: init unit %d\n", num );
906
   cc_Ident ((char *)&resp);
907
 
908
   printk ("GSCD: identification: ");
909
   for ( i=0 ; i<0x1E; i++ )
910
   {
911
      printk ( "%c", resp[i] );
912
   }
913
   printk ("\n");
914
 
915
   cc_SetSpeed ();
916
 
917
}
918
 
919
#ifdef FUTURE_WORK
920
/* return_done */
921
static void update_state ( void )
922
{
923
unsigned int AX;
924
 
925
 
926
    if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
927
    {
928
       if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
929
       {
930
          AX = ST_INVALID;
931
       }
932
 
933
       if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
934
       {
935
          invalidate ();
936
          f_drv_ok = 0;
937
       }
938
 
939
       AX |= 0x8000;
940
    }
941
 
942
    if ( disk_state & ST_PLAYING )
943
    {
944
       AX |= 0x200;
945
    }
946
 
947
    AX |= 0x100;
948
    /* pkt_esbx = AX; */
949
 
950
    disk_state = 0;
951
 
952
}
953
#endif
954
 
955
#ifdef MODULE
956
/* Init for the Module-Version */
957
int init_module (void)
958
{
959
long err;
960
 
961
 
962
     /* call the GoldStar-init */
963
     err = my_gscd_init ( );
964
 
965
     if ( err < 0 )
966
     {
967
         return err;
968
     }
969
     else
970
     {
971
        printk (KERN_INFO "Happy GoldStar !\n" );
972
        return 0;
973
     }
974
}
975
 
976
void cleanup_module (void)
977
{
978
 
979
   if ((unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
980
   {
981
      printk("What's that: can't unregister GoldStar-module\n" );
982
      return;
983
   }
984
 
985
   release_region (gscd_port,4);
986
   printk(KERN_INFO "GoldStar-module released.\n" );
987
}
988
#endif
989
 
990
 
991
/* Test for presence of drive and initialize it.  Called only at boot time. */
992
int gscd_init (void)
993
{
994
   return my_gscd_init ();
995
}
996
 
997
 
998
/* This is the common initialisation for the GoldStar drive. */
999
/* It is called at boot time AND for module init.           */
1000
int my_gscd_init (void)
1001
{
1002
int i;
1003
int result;
1004
 
1005
        printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
1006
        printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
1007
 
1008
        if (check_region(gscd_port, 4))
1009
        {
1010
          printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
1011
          return -EIO;
1012
        }
1013
 
1014
 
1015
        /* check for card */
1016
        result = wait_drv_ready ();
1017
        if ( result == 0x09 )
1018
        {
1019
           printk ("GSCD: DMA kann ich noch nicht!\n" );
1020
           return -EIO;
1021
        }
1022
 
1023
        if ( result == 0x0b )
1024
        {
1025
           drv_mode = result;
1026
           i = find_drives ();
1027
           if ( i == 0 )
1028
           {
1029
              printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
1030
              return -EIO;
1031
           }
1032
        }
1033
 
1034
        if ( (result != 0x0b) && (result != 0x09) )
1035
        {
1036
              printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
1037
              return -EIO;
1038
        }
1039
 
1040
        /* reset all drives */
1041
        i = 0;
1042
        while ( drv_states[i] != 0 )
1043
        {
1044
           curr_drv_state = drv_states[i];
1045
           printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
1046
           cc_Reset ();
1047
           printk ( "done\n" );
1048
           i++;
1049
        }
1050
 
1051
        if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
1052
        {
1053
                printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
1054
                       MAJOR_NR);
1055
                return -EIO;
1056
        }
1057
 
1058
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1059
        read_ahead[MAJOR_NR] = 4;
1060
 
1061
        disk_state = 0;
1062
        gscdPresent = 1;
1063
 
1064
        request_region(gscd_port, 4, "gscd");
1065
 
1066
        printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
1067
        return 0;
1068
}
1069
 
1070
static void gscd_hsg2msf (long hsg, struct msf *msf)
1071
{
1072
        hsg += CD_BLOCK_OFFSET;
1073
        msf -> min = hsg / (CD_FRAMES*CD_SECS);
1074
        hsg %= CD_FRAMES*CD_SECS;
1075
        msf -> sec = hsg / CD_FRAMES;
1076
        msf -> frame = hsg % CD_FRAMES;
1077
 
1078
        gscd_bin2bcd(&msf -> min);              /* convert to BCD */
1079
        gscd_bin2bcd(&msf -> sec);
1080
        gscd_bin2bcd(&msf -> frame);
1081
}
1082
 
1083
 
1084
static void gscd_bin2bcd (unsigned char *p)
1085
{
1086
int u, t;
1087
 
1088
        u = *p % 10;
1089
        t = *p / 10;
1090
        *p = u | (t << 4);
1091
}
1092
 
1093
 
1094
#ifdef FUTURE_WORK
1095
static long gscd_msf2hsg (struct msf *mp)
1096
{
1097
        return gscd_bcd2bin(mp -> frame)
1098
                + gscd_bcd2bin(mp -> sec) * CD_FRAMES
1099
                + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
1100
                - CD_BLOCK_OFFSET;
1101
}
1102
 
1103
static int gscd_bcd2bin (unsigned char bcd)
1104
{
1105
        return (bcd >> 4) * 10 + (bcd & 0xF);
1106
}
1107
#endif
1108
 
1109
 

powered by: WebSVN 2.1.0

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