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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [cdrom/] [gscd.c] - Blame information for rev 1774

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

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

powered by: WebSVN 2.1.0

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