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