1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179#define REVISION "$Revision: 1.5 $"
180
181#include <linux/module.h>
182
183#include <linux/errno.h>
184#include <linux/delay.h>
185#include <linux/string.h>
186#include <linux/sched.h>
187#include <linux/interrupt.h>
188#include <linux/timer.h>
189#include <linux/cdrom.h>
190#include <linux/devfs_fs_kernel.h>
191#include <linux/ioport.h>
192#include <linux/mm.h>
193#include <linux/slab.h>
194#include <linux/init.h>
195
196
197
198#include <asm/io.h>
199
200#define MAJOR_NR CM206_CDROM_MAJOR
201#include <linux/blk.h>
202
203#undef DEBUG
204#define STATISTICS
205#define AUTO_PROBE_MODULE
206#define USE_INSW
207
208#include "cm206.h"
209
210
211
212
213
214static int auto_probe = 1;
215
216static int cm206_base = CM206_BASE;
217static int cm206_irq = CM206_IRQ;
218#ifdef MODULE
219static int cm206[2] = { 0, 0 };
220#endif
221
222MODULE_PARM(cm206_base, "i");
223MODULE_PARM(cm206_irq, "i");
224MODULE_PARM(cm206, "1-2i");
225MODULE_PARM(auto_probe, "i");
226MODULE_LICENSE("GPL");
227
228#define POLLOOP 100
229#define READ_AHEAD 1
230#define BACK_AHEAD 1
231#define DATA_TIMEOUT (3*HZ)
232#define UART_TIMEOUT (5*HZ/100)
233#define DSB_TIMEOUT (7*HZ)
234#define UR_SIZE 4
235
236#define LINUX_BLOCK_SIZE 512
237#define RAW_SECTOR_SIZE 2352
238#define ISO_SECTOR_SIZE 2048
239#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)
240#define CD_SYNC_HEAD 16
241
242#ifdef STATISTICS
243#define stats(i) { ++cd->stats[st_ ## i]; \
244 cd->last_stat[st_ ## i] = cd->stat_counter++; \
245 }
246#else
247#define stats(i) (void) 0;
248#endif
249
250#define Debug(a) {printk (KERN_DEBUG); printk a;}
251#ifdef DEBUG
252#define debug(a) Debug(a)
253#else
254#define debug(a) (void) 0;
255#endif
256
257typedef unsigned char uch;
258typedef unsigned short ush;
259
260struct toc_struct {
261 uch track, fsm[3], q0;
262};
263
264static int cm206_blocksizes[1] = { 2048 };
265
266struct cm206_struct {
267 volatile ush intr_ds;
268 volatile ush intr_ls;
269 volatile uch ur[UR_SIZE];
270 volatile uch ur_w, ur_r;
271 volatile uch dsb, cc;
272 int command;
273 int openfiles;
274 ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];
275 int sector_first, sector_last;
276 wait_queue_head_t uart;
277 wait_queue_head_t data;
278 struct timer_list timer;
279 char timed_out;
280 signed char max_sectors;
281 char wait_back;
282 char background;
283 int adapter_first;
284 int adapter_last;
285 char fifo_overflowed;
286 uch disc_status[7];
287#ifdef STATISTICS
288 int stats[NR_STATS];
289 int last_stat[NR_STATS];
290 int stat_counter;
291#endif
292 struct toc_struct toc[101];
293 uch q[10];
294 uch audio_status[5];
295 uch media_changed;
296};
297
298#define DISC_STATUS cd->disc_status[0]
299#define FIRST_TRACK cd->disc_status[1]
300#define LAST_TRACK cd->disc_status[2]
301#define PAUSED cd->audio_status[0]
302#define PLAY_TO cd->toc[0]
303
304static struct cm206_struct *cd;
305
306
307
308
309void send_command_polled(int command)
310{
311 int loop = POLLOOP;
312 while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
313 && loop > 0) {
314 mdelay(1);
315 --loop;
316 }
317 outw(command, r_uart_transmit);
318}
319
320uch receive_echo_polled(void)
321{
322 int loop = POLLOOP;
323 while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
324 mdelay(1);
325 --loop;
326 }
327 return ((uch) inw(r_uart_receive));
328}
329
330uch send_receive_polled(int command)
331{
332 send_command_polled(command);
333 return receive_echo_polled();
334}
335
336inline void clear_ur(void)
337{
338 if (cd->ur_r != cd->ur_w) {
339 debug(("Deleting bytes from fifo:"));
340 for (; cd->ur_r != cd->ur_w;
341 cd->ur_r++, cd->ur_r %= UR_SIZE)
342 debug((" 0x%x", cd->ur[cd->ur_r]));
343 debug(("\n"));
344 }
345}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360static void cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
361
362{
363 volatile ush fool;
364 cd->intr_ds = inw(r_data_status);
365
366
367 cd->intr_ls = inw(r_line_status);
368 debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
369 cd->background));
370 if (cd->intr_ls & ls_attention)
371 stats(attention);
372
373 if (cd->intr_ls & ls_receive_buffer_full) {
374 cd->ur[cd->ur_w] = inb(r_uart_receive);
375 cd->intr_ls = inw(r_line_status);
376 debug(("receiving #%d: 0x%x\n", cd->ur_w,
377 cd->ur[cd->ur_w]));
378 cd->ur_w++;
379 cd->ur_w %= UR_SIZE;
380 if (cd->ur_w == cd->ur_r)
381 debug(("cd->ur overflow!\n"));
382 if (waitqueue_active(&cd->uart) && cd->background < 2) {
383 del_timer(&cd->timer);
384 wake_up_interruptible(&cd->uart);
385 }
386 }
387
388 else if (cd->intr_ds & ds_data_ready) {
389 if (cd->background)
390 ++cd->adapter_last;
391 if (waitqueue_active(&cd->data)
392 && (cd->wait_back || !cd->background)) {
393 del_timer(&cd->timer);
394 wake_up_interruptible(&cd->data);
395 }
396 stats(data_ready);
397 }
398
399 else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
400 outw(dc_normal | (inw(r_data_status) & 0x7f),
401 r_data_control);
402 outw(cd->command, r_uart_transmit);
403 cd->command = 0;
404 if (!cd->background)
405 wake_up_interruptible(&cd->uart);
406 }
407
408 else if (cd->intr_ds & ds_fifo_overflow) {
409 debug(("Fifo overflow at sectors 0x%x\n",
410 cd->sector_first));
411 fool = inw(r_fifo_output_buffer);
412 cd->fifo_overflowed = 1;
413 stats(fifo_overflow);
414 } else if (cd->intr_ds & ds_data_error) {
415 debug(("Data error at sector 0x%x\n", cd->sector_first));
416 stats(data_error);
417 } else if (cd->intr_ds & ds_crc_error) {
418 debug(("CRC error at sector 0x%x\n", cd->sector_first));
419 stats(crc_error);
420 } else if (cd->intr_ds & ds_sync_error) {
421 debug(("Sync at sector 0x%x\n", cd->sector_first));
422 stats(sync_error);
423 } else if (cd->intr_ds & ds_toc_ready) {
424
425 }
426
427 else {
428 outw(dc_normal | READ_AHEAD, r_data_control);
429 stats(lost_intr);
430 }
431 if (cd->background
432 && (cd->adapter_last - cd->adapter_first == cd->max_sectors
433 || cd->fifo_overflowed))
434 mark_bh(CM206_BH);
435 stats(interrupt);
436}
437
438
439void cm206_timeout(unsigned long who)
440{
441 cd->timed_out = 1;
442 debug(("Timing out\n"));
443 wake_up_interruptible((wait_queue_head_t *) who);
444}
445
446
447
448int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
449{
450 cd->timed_out = 0;
451 cd->timer.data = (unsigned long) wait;
452 cd->timer.expires = jiffies + timeout;
453 add_timer(&cd->timer);
454 debug(("going to sleep\n"));
455 interruptible_sleep_on(wait);
456 del_timer(&cd->timer);
457 if (cd->timed_out) {
458 cd->timed_out = 0;
459 return 1;
460 } else
461 return 0;
462}
463
464void cm206_delay(int nr_jiffies)
465{
466 DECLARE_WAIT_QUEUE_HEAD(wait);
467 sleep_or_timeout(&wait, nr_jiffies);
468}
469
470void send_command(int command)
471{
472 debug(("Sending 0x%x\n", command));
473 if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
474 cd->command = command;
475 cli();
476 outw(dc_mask_sync_error | dc_no_stop_on_error |
477 (inw(r_data_status) & 0x7f), r_data_control);
478
479 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
480 debug(("Time out on write-buffer\n"));
481 stats(write_timeout);
482 outw(command, r_uart_transmit);
483 }
484 debug(("Write commmand delayed\n"));
485 } else
486 outw(command, r_uart_transmit);
487}
488
489uch receive_byte(int timeout)
490{
491 uch ret;
492 cli();
493 debug(("cli\n"));
494 ret = cd->ur[cd->ur_r];
495 if (cd->ur_r != cd->ur_w) {
496 sti();
497 debug(("returning #%d: 0x%x\n", cd->ur_r,
498 cd->ur[cd->ur_r]));
499 cd->ur_r++;
500 cd->ur_r %= UR_SIZE;
501 return ret;
502 } else if (sleep_or_timeout(&cd->uart, timeout)) {
503 debug(("Time out on receive-buffer\n"));
504#ifdef STATISTICS
505 if (timeout == UART_TIMEOUT)
506 stats(receive_timeout)
507 else
508 stats(dsb_timeout);
509#endif
510 return 0xda;
511 }
512 ret = cd->ur[cd->ur_r];
513 debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
514 cd->ur[cd->ur_r]));
515 cd->ur_r++;
516 cd->ur_r %= UR_SIZE;
517 return ret;
518}
519
520inline uch receive_echo(void)
521{
522 return receive_byte(UART_TIMEOUT);
523}
524
525inline uch send_receive(int command)
526{
527 send_command(command);
528 return receive_echo();
529}
530
531inline uch wait_dsb(void)
532{
533 return receive_byte(DSB_TIMEOUT);
534}
535
536int type_0_command(int command, int expect_dsb)
537{
538 int e;
539 clear_ur();
540 if (command != (e = send_receive(command))) {
541 debug(("command 0x%x echoed as 0x%x\n", command, e));
542 stats(echo);
543 return -1;
544 }
545 if (expect_dsb) {
546 cd->dsb = wait_dsb();
547 }
548 return 0;
549}
550
551int type_1_command(int command, int bytes, uch * status)
552{
553 int i;
554 if (type_0_command(command, 0))
555 return -1;
556 for (i = 0; i < bytes; i++)
557 status[i] = send_receive(c_gimme);
558 return 0;
559}
560
561
562
563void reset_cm260(void)
564{
565 outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
566 udelay(10);
567 outw(dc_normal | READ_AHEAD, r_data_control);
568}
569
570
571void fsm(int lba, uch * fsm)
572{
573 fsm[0] = lba % 75;
574 lba /= 75;
575 lba += 2;
576 fsm[1] = lba % 60;
577 fsm[2] = lba / 60;
578}
579
580inline int fsm2lba(uch * fsm)
581{
582 return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
583}
584
585inline int f_s_m2lba(uch f, uch s, uch m)
586{
587 return f + 75 * (s - 2 + 60 * m);
588}
589
590int start_read(int start)
591{
592 uch read_sector[4] = { c_read_data, };
593 int i, e;
594
595 fsm(start, &read_sector[1]);
596 clear_ur();
597 for (i = 0; i < 4; i++)
598 if (read_sector[i] != (e = send_receive(read_sector[i]))) {
599 debug(("read_sector: %x echoes %x\n",
600 read_sector[i], e));
601 stats(echo);
602 if (e == 0xff) {
603 e = receive_echo();
604 debug(("Second try %x\n", e));
605 if (e != read_sector[i])
606 return -1;
607 }
608 }
609 return 0;
610}
611
612int stop_read(void)
613{
614 int e;
615 type_0_command(c_stop, 0);
616 if ((e = receive_echo()) != 0xff) {
617 debug(("c_stop didn't send 0xff, but 0x%x\n", e));
618 stats(stop_0xff);
619 return -1;
620 }
621 return 0;
622}
623
624
625
626
627
628
629int read_background(int start, int reading)
630{
631 if (cd->background)
632 return -1;
633 outw(dc_normal | BACK_AHEAD, r_data_control);
634 if (!reading && start_read(start))
635 return -2;
636 cd->adapter_first = cd->adapter_last = start;
637 cd->background = 1;
638 return 0;
639}
640
641#ifdef USE_INSW
642#define transport_data insw
643#else
644
645
646void transport_data(int port, ush * dest, int count)
647{
648 int i;
649 ush *d;
650 for (i = 0, d = dest; i < count; i++, d++)
651 *d = inw(port);
652}
653#endif
654
655
656#define MAX_TRIES 100
657int read_sector(int start)
658{
659 int tries = 0;
660 if (cd->background) {
661 cd->background = 0;
662 cd->adapter_last = -1;
663 stop_read();
664 }
665 cd->fifo_overflowed = 0;
666 reset_cm260();
667 if (start_read(start))
668 return -1;
669 do {
670 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
671 debug(("Read timed out sector 0x%x\n", start));
672 stats(read_timeout);
673 stop_read();
674 return -3;
675 }
676 tries++;
677 } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
678 if (tries > 1)
679 debug(("Took me some tries\n"))
680 else
681 if (tries == MAX_TRIES)
682 debug(("MAX_TRIES tries for read sector\n"));
683 transport_data(r_fifo_output_buffer, cd->sector,
684 READ_AHEAD * RAW_SECTOR_SIZE / 2);
685 if (read_background(start + READ_AHEAD, 1))
686 stats(read_background);
687 cd->sector_first = start;
688 cd->sector_last = start + READ_AHEAD;
689 stats(read_restarted);
690 return 0;
691}
692
693
694
695
696
697
698
699
700
701
702
703void cm206_bh(void)
704{
705 debug(("bh: %d\n", cd->background));
706 switch (cd->background) {
707 case 1:
708 stats(bh);
709 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
710 cd->command = c_stop;
711 outw(dc_mask_sync_error | dc_no_stop_on_error |
712 (inw(r_data_status) & 0x7f), r_data_control);
713 cd->background = 2;
714 break;
715 } else
716 outw(c_stop, r_uart_transmit);
717
718 case 2:
719
720 cd->background = 3;
721 break;
722 case 3:
723 if (cd->ur_r != cd->ur_w) {
724 if (cd->ur[cd->ur_r] != c_stop) {
725 debug(("cm206_bh: c_stop echoed 0x%x\n",
726 cd->ur[cd->ur_r]));
727 stats(echo);
728 }
729 cd->ur_r++;
730 cd->ur_r %= UR_SIZE;
731 }
732 cd->background++;
733 break;
734 case 4:
735 if (cd->ur_r != cd->ur_w) {
736 if (cd->ur[cd->ur_r] != 0xff) {
737 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
738 stats(stop_0xff);
739 }
740 cd->ur_r++;
741 cd->ur_r %= UR_SIZE;
742 }
743 cd->background = 0;
744 }
745}
746
747
748
749
750void get_drive_status(void)
751{
752 uch status[2];
753 type_1_command(c_drive_status, 2, status);
754 cd->dsb = status[0];
755 cd->cc = status[1];
756 cd->media_changed |=
757 !!(cd->dsb & (dsb_possible_media_change |
758 dsb_drive_not_ready | dsb_tray_not_closed));
759}
760
761void get_disc_status(void)
762{
763 if (type_1_command(c_disc_status, 7, cd->disc_status)) {
764 debug(("get_disc_status: error\n"));
765 }
766}
767
768struct block_device_operations cm206_bdops =
769{
770 owner: THIS_MODULE,
771 open: cdrom_open,
772 release: cdrom_release,
773 ioctl: cdrom_ioctl,
774 check_media_change: cdrom_media_changed,
775};
776
777
778
779static int cm206_open(struct cdrom_device_info *cdi, int purpose)
780{
781 if (!cd->openfiles) {
782 cd->background = 0;
783 reset_cm260();
784 cd->adapter_last = -1;
785 cd->sector_last = -1;
786 }
787 ++cd->openfiles;
788 stats(open);
789 return 0;
790}
791
792static void cm206_release(struct cdrom_device_info *cdi)
793{
794 if (cd->openfiles == 1) {
795 if (cd->background) {
796 cd->background = 0;
797 stop_read();
798 }
799 cd->sector_last = -1;
800 FIRST_TRACK = 0;
801 }
802 --cd->openfiles;
803}
804
805
806
807void empty_buffer(int sectors)
808{
809 while (sectors >= 0) {
810 transport_data(r_fifo_output_buffer,
811 cd->sector + cd->fifo_overflowed,
812 RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
813 --sectors;
814 ++cd->adapter_first;
815 cd->fifo_overflowed = 0;
816 stats(sector_transferred);
817 }
818 cd->sector_first = cd->adapter_first - 1;
819 cd->sector_last = cd->adapter_first;
820}
821
822
823
824
825int try_adapter(int sector)
826{
827 if (cd->adapter_first <= sector && sector < cd->adapter_last) {
828
829 empty_buffer(sector - cd->adapter_first);
830 return 0;
831 } else if (cd->background == 1 && cd->adapter_first <= sector
832 && sector < cd->adapter_first + cd->max_sectors) {
833
834 cd->wait_back = 1;
835 while (sector >= cd->adapter_last) {
836 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
837 debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
838 stats(back_read_timeout);
839 cd->wait_back = 0;
840 return -1;
841 }
842 }
843 cd->wait_back = 0;
844 empty_buffer(sector - cd->adapter_first);
845 return 0;
846 } else
847 return -2;
848}
849
850
851
852
853static void do_cm206_request(request_queue_t * q)
854{
855 long int i, cd_sec_no;
856 int quarter, error;
857 uch *source, *dest;
858
859 while (1) {
860 INIT_REQUEST;
861 if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
862 return;
863 if (CURRENT->cmd != READ) {
864 debug(("Non-read command %d on cdrom\n",
865 CURRENT->cmd));
866 end_request(0);
867 continue;
868 }
869 spin_unlock_irq(&io_request_lock);
870 error = 0;
871 for (i = 0; i < CURRENT->nr_sectors; i++) {
872 int e1, e2;
873 cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO;
874 quarter = (CURRENT->sector + i) % BLOCKS_ISO;
875 dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
876
877 if (cd->sector_first <= cd_sec_no
878 && cd_sec_no < cd->sector_last) {
879 source =
880 ((uch *) cd->sector) + 16 +
881 quarter * LINUX_BLOCK_SIZE +
882 (cd_sec_no -
883 cd->sector_first) * RAW_SECTOR_SIZE;
884 memcpy(dest, source, LINUX_BLOCK_SIZE);
885 } else if (!(e1 = try_adapter(cd_sec_no)) ||
886 !(e2 = read_sector(cd_sec_no))) {
887 source =
888 ((uch *) cd->sector) + 16 +
889 quarter * LINUX_BLOCK_SIZE;
890 memcpy(dest, source, LINUX_BLOCK_SIZE);
891 } else {
892 error = 1;
893 debug(("cm206_request: %d %d\n", e1, e2));
894 }
895 }
896 spin_lock_irq(&io_request_lock);
897 end_request(!error);
898 }
899}
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915void seek(int lba)
916{
917 int i;
918 uch seek_command[4] = { c_seek, };
919
920 fsm(lba, &seek_command[1]);
921 for (i = 0; i < 4; i++)
922 type_0_command(seek_command[i], 0);
923 cd->dsb = wait_dsb();
924}
925
926uch bcdbin(unsigned char bcd)
927{
928 return (bcd >> 4) * 10 + (bcd & 0xf);
929}
930
931inline uch normalize_track(uch track)
932{
933 if (track < 1)
934 return 1;
935 if (track > LAST_TRACK)
936 return LAST_TRACK + 1;
937 return track;
938}
939
940
941
942
943
944int get_toc_lba(uch track)
945{
946 int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
947 int i, lba, l, old_lba = 0;
948 uch *q = cd->q;
949 uch ct;
950 int binary = 0;
951 const int skip = 3 * 60 * 75;
952
953 for (i = track; i > 0; i--)
954 if (cd->toc[i].track) {
955 min = fsm2lba(cd->toc[i].fsm);
956 break;
957 }
958 lba = min + skip;
959 do {
960 seek(lba);
961 type_1_command(c_read_current_q, 10, q);
962 ct = normalize_track(q[1]);
963 if (!cd->toc[ct].track) {
964 l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
965 bcdbin(q[4]) - 2 +
966 60 * (q[7] -
967 bcdbin(q
968 [3])));
969 cd->toc[ct].track = q[1];
970 fsm(l, cd->toc[ct].fsm);
971 cd->toc[ct].q0 = q[0];
972 if (ct == track)
973 return l;
974 }
975 old_lba = lba;
976 if (binary) {
977 if (ct < track)
978 min = lba;
979 else
980 max = lba;
981 lba = (min + max) / 2;
982 } else {
983 if (ct < track)
984 lba += skip;
985 else {
986 binary = 1;
987 max = lba;
988 min = lba - skip;
989 lba = (min + max) / 2;
990 }
991 }
992 } while (lba != old_lba);
993 return lba;
994}
995
996void update_toc_entry(uch track)
997{
998 track = normalize_track(track);
999 if (!cd->toc[track].track)
1000 get_toc_lba(track);
1001}
1002
1003
1004int read_toc_header(struct cdrom_tochdr *hp)
1005{
1006 if (!FIRST_TRACK)
1007 get_disc_status();
1008 if (hp) {
1009 int i;
1010 hp->cdth_trk0 = FIRST_TRACK;
1011 hp->cdth_trk1 = LAST_TRACK;
1012
1013 for (i = 0; i < 3; i++)
1014 cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1015 update_toc_entry(LAST_TRACK + 1);
1016 return 0;
1017 }
1018 return -1;
1019}
1020
1021void play_from_to_msf(struct cdrom_msf *msfp)
1022{
1023 uch play_command[] = { c_play,
1024 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1025 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1026 2
1027 };
1028 int i;
1029 for (i = 0; i < 9; i++)
1030 type_0_command(play_command[i], 0);
1031 for (i = 0; i < 3; i++)
1032 PLAY_TO.fsm[i] = play_command[i + 4];
1033 PLAY_TO.track = 0;
1034 cd->dsb = wait_dsb();
1035}
1036
1037void play_from_to_track(int from, int to)
1038{
1039 uch play_command[8] = { c_play, };
1040 int i;
1041
1042 if (from == 0) {
1043 for (i = 0; i < 3; i++) {
1044 play_command[i + 1] = cd->audio_status[i + 2];
1045 play_command[i + 4] = PLAY_TO.fsm[i];
1046 }
1047 } else {
1048 update_toc_entry(from);
1049 update_toc_entry(to + 1);
1050 for (i = 0; i < 3; i++) {
1051 play_command[i + 1] = cd->toc[from].fsm[i];
1052 PLAY_TO.fsm[i] = play_command[i + 4] =
1053 cd->toc[to + 1].fsm[i];
1054 }
1055 PLAY_TO.track = to;
1056 }
1057 for (i = 0; i < 7; i++)
1058 type_0_command(play_command[i], 0);
1059 for (i = 0; i < 2; i++)
1060 type_0_command(0x2, 0);
1061 cd->dsb = wait_dsb();
1062}
1063
1064int get_current_q(struct cdrom_subchnl *qp)
1065{
1066 int i;
1067 uch *q = cd->q;
1068 if (type_1_command(c_read_current_q, 10, q))
1069 return 0;
1070
1071 for (i = 2; i < 6; i++)
1072 q[i] = bcdbin(q[i]);
1073 qp->cdsc_adr = q[0] & 0xf;
1074 qp->cdsc_ctrl = q[0] >> 4;
1075 qp->cdsc_trk = q[1];
1076 qp->cdsc_ind = q[2];
1077 if (qp->cdsc_format == CDROM_MSF) {
1078 qp->cdsc_reladdr.msf.minute = q[3];
1079 qp->cdsc_reladdr.msf.second = q[4];
1080 qp->cdsc_reladdr.msf.frame = q[5];
1081 qp->cdsc_absaddr.msf.minute = q[7];
1082 qp->cdsc_absaddr.msf.second = q[8];
1083 qp->cdsc_absaddr.msf.frame = q[9];
1084 } else {
1085 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1086 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1087 }
1088 get_drive_status();
1089 if (cd->dsb & dsb_play_in_progress)
1090 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1091 else if (PAUSED)
1092 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1093 else
1094 qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1095 return 0;
1096}
1097
1098void invalidate_toc(void)
1099{
1100 memset(cd->toc, 0, sizeof(cd->toc));
1101 memset(cd->disc_status, 0, sizeof(cd->disc_status));
1102}
1103
1104
1105void get_toc_entry(struct cdrom_tocentry *ep)
1106{
1107 uch track = normalize_track(ep->cdte_track);
1108 update_toc_entry(track);
1109 ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1110 ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1111 ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1112 ep->cdte_adr = cd->toc[track].q0 & 0xf;
1113 ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1114 ep->cdte_datamode = 0;
1115}
1116
1117
1118
1119
1120
1121
1122int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1123 void *arg)
1124{
1125 switch (cmd) {
1126 case CDROMREADTOCHDR:
1127 return read_toc_header((struct cdrom_tochdr *) arg);
1128 case CDROMREADTOCENTRY:
1129 get_toc_entry((struct cdrom_tocentry *) arg);
1130 return 0;
1131 case CDROMPLAYMSF:
1132 play_from_to_msf((struct cdrom_msf *) arg);
1133 return 0;
1134 case CDROMPLAYTRKIND:
1135 play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1136 ((struct cdrom_ti *) arg)->cdti_trk1);
1137 return 0;
1138 case CDROMSTOP:
1139 PAUSED = 0;
1140 if (cd->dsb & dsb_play_in_progress)
1141 return type_0_command(c_stop, 1);
1142 else
1143 return 0;
1144 case CDROMPAUSE:
1145 get_drive_status();
1146 if (cd->dsb & dsb_play_in_progress) {
1147 type_0_command(c_stop, 1);
1148 type_1_command(c_audio_status, 5,
1149 cd->audio_status);
1150 PAUSED = 1;
1151 }
1152 return 0;
1153 case CDROMRESUME:
1154 if (PAUSED)
1155 play_from_to_track(0, 0);
1156 PAUSED = 0;
1157 return 0;
1158 case CDROMSTART:
1159 case CDROMVOLCTRL:
1160 return 0;
1161 case CDROMSUBCHNL:
1162 return get_current_q((struct cdrom_subchnl *) arg);
1163 default:
1164 return -EINVAL;
1165 }
1166}
1167
1168
1169
1170
1171
1172static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1173 unsigned long arg)
1174{
1175 switch (cmd) {
1176#ifdef STATISTICS
1177 case CM206CTL_GET_STAT:
1178 if (arg >= NR_STATS)
1179 return -EINVAL;
1180 else
1181 return cd->stats[arg];
1182 case CM206CTL_GET_LAST_STAT:
1183 if (arg >= NR_STATS)
1184 return -EINVAL;
1185 else
1186 return cd->last_stat[arg];
1187#endif
1188 default:
1189 debug(("Unknown ioctl call 0x%x\n", cmd));
1190 return -EINVAL;
1191 }
1192}
1193
1194int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1195{
1196 if (cd != NULL) {
1197 int r;
1198 get_drive_status();
1199 r = cd->media_changed;
1200 cd->media_changed = 0;
1201 return r;
1202 } else
1203 return -EIO;
1204}
1205
1206
1207
1208
1209
1210int cm206_open_files(struct cdrom_device_info *cdi)
1211{
1212 if (cd)
1213 return cd->openfiles;
1214 return -1;
1215}
1216
1217
1218int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1219{
1220 if (position) {
1221 type_0_command(c_open_tray, 1);
1222 invalidate_toc();
1223 } else
1224 type_0_command(c_close_tray, 1);
1225 return 0;
1226}
1227
1228
1229int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1230{
1231 get_drive_status();
1232 if (cd->dsb & dsb_tray_not_closed)
1233 return CDS_TRAY_OPEN;
1234 if (!(cd->dsb & dsb_disc_present))
1235 return CDS_NO_DISC;
1236 if (cd->dsb & dsb_drive_not_ready)
1237 return CDS_DRIVE_NOT_READY;
1238 return CDS_DISC_OK;
1239}
1240
1241
1242int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1243{
1244 uch command = (lock) ? c_lock_tray : c_unlock_tray;
1245 type_0_command(command, 1);
1246
1247 return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1248}
1249
1250
1251
1252
1253int cm206_get_last_session(struct cdrom_device_info *cdi,
1254 struct cdrom_multisession *mssp)
1255{
1256 if (!FIRST_TRACK)
1257 get_disc_status();
1258 if (mssp != NULL) {
1259 if (DISC_STATUS & cds_multi_session) {
1260 mssp->addr.msf.frame = cd->disc_status[3];
1261 mssp->addr.msf.second = cd->disc_status[4];
1262 mssp->addr.msf.minute = cd->disc_status[5];
1263 mssp->addr_format = CDROM_MSF;
1264 mssp->xa_flag = 1;
1265 } else {
1266 mssp->xa_flag = 0;
1267 }
1268 return 1;
1269 }
1270 return 0;
1271}
1272
1273int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1274{
1275 uch upc[10];
1276 char *ret = mcn->medium_catalog_number;
1277 int i;
1278
1279 if (type_1_command(c_read_upc, 10, upc))
1280 return -EIO;
1281 for (i = 0; i < 13; i++) {
1282 int w = i / 2 + 1, r = i % 2;
1283 if (r)
1284 ret[i] = 0x30 | (upc[w] & 0x0f);
1285 else
1286 ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1287 }
1288 ret[13] = '\0';
1289 return 0;
1290}
1291
1292int cm206_reset(struct cdrom_device_info *cdi)
1293{
1294 stop_read();
1295 reset_cm260();
1296 outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1297 mdelay(1);
1298 outw(dc_normal | READ_AHEAD, r_data_control);
1299 cd->sector_last = -1;
1300 cd->adapter_last = -1;
1301 invalidate_toc();
1302 return 0;
1303}
1304
1305int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1306{
1307 int r;
1308 switch (speed) {
1309 case 0:
1310 r = type_0_command(c_auto_mode, 1);
1311 break;
1312 case 1:
1313 r = type_0_command(c_force_1x, 1);
1314 break;
1315 case 2:
1316 r = type_0_command(c_force_2x, 1);
1317 break;
1318 default:
1319 return -1;
1320 }
1321 if (r < 0)
1322 return r;
1323 else
1324 return 1;
1325}
1326
1327static struct cdrom_device_ops cm206_dops = {
1328 open:cm206_open,
1329 release:cm206_release,
1330 drive_status:cm206_drive_status,
1331 media_changed:cm206_media_changed,
1332 tray_move:cm206_tray_move,
1333 lock_door:cm206_lock_door,
1334 select_speed:cm206_select_speed,
1335 get_last_session:cm206_get_last_session,
1336 get_mcn:cm206_get_upc,
1337 reset:cm206_reset,
1338 audio_ioctl:cm206_audio_ioctl,
1339 dev_ioctl:cm206_ioctl,
1340 capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1341 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1342 CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1343 CDC_IOCTLS | CDC_DRIVE_STATUS,
1344 n_minors:1,
1345};
1346
1347
1348static struct cdrom_device_info cm206_info = {
1349 ops:&cm206_dops,
1350 speed:2,
1351 capacity:1,
1352 name:"cm206",
1353};
1354
1355
1356
1357static void cleanup(int level)
1358{
1359 switch (level) {
1360 case 4:
1361 if (unregister_cdrom(&cm206_info)) {
1362 printk("Can't unregister cdrom cm206\n");
1363 return;
1364 }
1365 if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
1366 printk("Can't unregister major cm206\n");
1367 return;
1368 }
1369 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1370 case 3:
1371 free_irq(cm206_irq, NULL);
1372 case 2:
1373 case 1:
1374 kfree(cd);
1375 release_region(cm206_base, 16);
1376 default:;
1377 }
1378}
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390int __init probe_base_port(int base)
1391{
1392 int b = 0x300, e = 0x370;
1393 volatile int fool, i;
1394
1395 if (base)
1396 b = e = base;
1397 for (base = b; base <= e; base += 0x10) {
1398 if (check_region(base, 0x10))
1399 continue;
1400 for (i = 0; i < 3; i++)
1401 fool = inw(base + 2);
1402 if ((inw(base + 6) & 0xffef) != 0x0001 ||
1403 (inw(base) & 0xad00) != 0)
1404 continue;
1405 return (base);
1406 }
1407 return 0;
1408}
1409
1410#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1411
1412int __init probe_irq(int nr)
1413{
1414 int irqs, irq;
1415 outw(dc_normal | READ_AHEAD, r_data_control);
1416 sti();
1417 irqs = probe_irq_on();
1418 reset_cm260();
1419 udelay(100);
1420 irq = probe_irq_off(irqs);
1421 outw(dc_normal | READ_AHEAD, r_data_control);
1422 if (nr && irq != nr && irq > 0)
1423 return 0;
1424 else
1425 return irq;
1426}
1427#endif
1428
1429int __init cm206_init(void)
1430{
1431 uch e = 0;
1432 long int size = sizeof(struct cm206_struct);
1433
1434 printk(KERN_INFO "cm206 cdrom driver " REVISION);
1435 cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1436 if (!cm206_base) {
1437 printk(" can't find adapter!\n");
1438 return -EIO;
1439 }
1440 printk(" adapter at 0x%x", cm206_base);
1441 request_region(cm206_base, 16, "cm206");
1442 cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1443 if (!cd)
1444 return -EIO;
1445
1446
1447
1448#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1449 cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1450 if (cm206_irq <= 0) {
1451 printk("can't find IRQ!\n");
1452 cleanup(1);
1453 return -EIO;
1454 } else
1455 printk(" IRQ %d found\n", cm206_irq);
1456#else
1457 cli();
1458 reset_cm260();
1459
1460
1461
1462 mdelay(1);
1463 outw(dc_normal | READ_AHEAD, r_data_control);
1464 sti();
1465 printk(" using IRQ %d\n", cm206_irq);
1466#endif
1467 if (send_receive_polled(c_drive_configuration) !=
1468 c_drive_configuration) {
1469 printk(KERN_INFO " drive not there\n");
1470 cleanup(1);
1471 return -EIO;
1472 }
1473 e = send_receive_polled(c_gimme);
1474 printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1475 if (e & dcf_transfer_rate)
1476 printk(" double");
1477 else
1478 printk(" single");
1479 printk(" speed drive");
1480 if (e & dcf_motorized_tray)
1481 printk(", motorized tray");
1482 if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1483 printk("\nUnable to reserve IRQ---aborted\n");
1484 cleanup(2);
1485 return -EIO;
1486 }
1487 printk(".\n");
1488 if (devfs_register_blkdev(MAJOR_NR, "cm206", &cm206_bdops) != 0) {
1489 printk(KERN_INFO "Cannot register for major %d!\n",
1490 MAJOR_NR);
1491 cleanup(3);
1492 return -EIO;
1493 }
1494 cm206_info.dev = MKDEV(MAJOR_NR, 0);
1495 if (register_cdrom(&cm206_info) != 0) {
1496 printk(KERN_INFO "Cannot register for cdrom %d!\n",
1497 MAJOR_NR);
1498 cleanup(3);
1499 return -EIO;
1500 }
1501 devfs_plain_cdrom(&cm206_info, &cm206_bdops);
1502 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1503 blksize_size[MAJOR_NR] = cm206_blocksizes;
1504 read_ahead[MAJOR_NR] = 16;
1505 init_bh(CM206_BH, cm206_bh);
1506
1507 memset(cd, 0, sizeof(*cd));
1508 cd->sector_last = -1;
1509 cd->adapter_last = -1;
1510 cd->timer.function = cm206_timeout;
1511 cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1512 printk(KERN_INFO "%d kB adapter memory available, "
1513 " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1514 size);
1515 return 0;
1516}
1517
1518#ifdef MODULE
1519
1520
1521static void __init parse_options(void)
1522{
1523 int i;
1524 for (i = 0; i < 2; i++) {
1525 if (0x300 <= cm206[i] && i <= 0x370
1526 && cm206[i] % 0x10 == 0) {
1527 cm206_base = cm206[i];
1528 auto_probe = 0;
1529 } else if (3 <= cm206[i] && cm206[i] <= 15) {
1530 cm206_irq = cm206[i];
1531 auto_probe = 0;
1532 }
1533 }
1534}
1535
1536int __cm206_init(void)
1537{
1538 parse_options();
1539#if !defined(AUTO_PROBE_MODULE)
1540 auto_probe = 0;
1541#endif
1542 return cm206_init();
1543}
1544
1545void __exit cm206_exit(void)
1546{
1547 cleanup(4);
1548 printk(KERN_INFO "cm206 removed\n");
1549}
1550
1551module_init(__cm206_init);
1552module_exit(cm206_exit);
1553
1554#else
1555
1556
1557
1558
1559static int __init cm206_setup(char *s)
1560{
1561 int i, p[4];
1562
1563 (void) get_options(s, ARRAY_SIZE(p), p);
1564
1565 if (!strcmp(s, "auto"))
1566 auto_probe = 1;
1567 for (i = 1; i <= p[0]; i++) {
1568 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1569 cm206_base = p[i];
1570 auto_probe = 0;
1571 } else if (3 <= p[i] && p[i] <= 15) {
1572 cm206_irq = p[i];
1573 auto_probe = 0;
1574 }
1575 }
1576 return 1;
1577}
1578
1579__setup("cm206=", cm206_setup);
1580
1581#endif
1582
1583
1584
1585
1586
1587
1588
1589