This source file includes following definitions.
- send_command_polled
- receive_echo_polled
- send_receive_polled
- cm206_interrupt
- cm206_timeout
- sleep_or_timeout
- cm206_delay
- send_command
- receive_echo
- send_receive
- wait_dsb
- type_0_command
- type_1_command
- reset_cm260
- fsm
- fsm2lba
- f_s_m2lba
- start_read
- stop_read
- read_background
- read_sector
- cm206_bh
- get_drive_status
- get_disc_status
- cm206_open
- cm206_release
- empty_buffer
- try_adapter
- do_cm206_request
- get_multi_session_info
- seek
- bcdbin
- normalize_track
- get_toc_lba
- update_toc_entry
- read_toc_header
- play_from_to_msf
- play_from_to_track
- get_current_q
- get_toc_entry
- cm206_ioctl
- cleanup
- probe_base_port
- probe_irq
- parse_options
- init_module
- cleanup_module
- cm206_setup
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 #define VERSION "0.34"
83
84 #ifdef MODULE
85 #include <linux/module.h>
86 #include <linux/version.h>
87 #include <linux/malloc.h>
88 #ifndef CONFIG_MODVERSIONS
89 char kernel_version[]=UTS_RELEASE;
90 #endif
91 #else
92 #define MOD_INC_USE_COUNT
93 #define MOD_DEC_USE_COUNT
94 #endif MODULE
95
96 #include <linux/errno.h>
97 #include <linux/delay.h>
98 #include <linux/string.h>
99 #include <linux/sched.h>
100 #include <linux/interrupt.h>
101 #include <linux/timer.h>
102 #include <linux/cdrom.h>
103 #include <linux/ioport.h>
104 #include <linux/mm.h>
105
106 #include <asm/io.h>
107
108 #define MAJOR_NR CM206_CDROM_MAJOR
109 #include "blk.h"
110 #include <linux/cm206.h>
111
112
113
114
115
116 static int auto_probe=1;
117
118 static int cm206_base = CM206_BASE;
119 static int cm206_irq = CM206_IRQ;
120
121 #undef DEBUG
122 #undef DEBUG_SECTORS
123 #define STATISTICS
124 #undef AUTO_PROBE_MODULE
125
126 #define POLLOOP 10000
127 #define READ_AHEAD 1
128 #define BACK_AHEAD 1
129 #define DATA_TIMEOUT 300
130 #define UART_TIMEOUT 5
131 #define DSB_TIMEOUT 700
132
133 #define RAW_SECTOR_SIZE 2352
134 #define ISO_SECTOR_SIZE 2048
135
136 #ifdef STATISTICS
137 #include <linux/stats206.h>
138 #define stats(i) ++cd->stats[st_ ## i]; \
139 cd->last_stat[st_ ## i] = cd->stat_counter++;
140 #else
141 #define stats(i) (void) 0
142 #endif
143
144 #ifdef DEBUG
145 #define debug(a) printk a
146 #else
147 #define debug(a) (void) 0
148 #endif
149
150 typedef unsigned char uch;
151 typedef unsigned short ush;
152
153 struct toc_struct{
154 uch track, fsm[3], q0;
155 };
156
157 struct cm206_struct {
158 ush intr_ds;
159 ush intr_ls;
160 uch intr_ur;
161 uch dsb, cc;
162 uch fool;
163 int command;
164 int openfiles;
165 ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2];
166 int sector_first, sector_last;
167 struct wait_queue * uart;
168 struct wait_queue * data;
169 struct timer_list timer;
170 char timed_out;
171 signed char max_sectors;
172 char wait_back;
173 char background;
174 int adapter_first;
175 int adapter_last;
176 char fifo_overflowed;
177 uch disc_status[7];
178 #ifdef STATISTICS
179 int stats[NR_STATS];
180 int last_stat[NR_STATS];
181 int stat_counter;
182 #endif
183 struct toc_struct toc[101];
184 uch q[10];
185 uch audio_status[5];
186 };
187
188 #define DISC_STATUS cd->disc_status[0]
189 #define FIRST_TRACK cd->disc_status[1]
190 #define LAST_TRACK cd->disc_status[2]
191 #define PAUSED cd->audio_status[0]
192 #define PLAY_TO cd->toc[0]
193
194 static struct cm206_struct * cd;
195
196
197
198
199 void send_command_polled(int command)
200 {
201 int loop=POLLOOP;
202 while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0)
203 --loop;
204 outw(command, r_uart_transmit);
205 }
206
207 uch receive_echo_polled(void)
208 {
209 int loop=POLLOOP;
210 while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) --loop;
211 return ((uch) inw(r_uart_receive));
212 }
213
214 uch send_receive_polled(int command)
215 {
216 send_command_polled(command);
217 return receive_echo_polled();
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233 static void cm206_interrupt(int sig, struct pt_regs * regs)
234 {
235 volatile ush fool;
236 cd->intr_ds = inw(r_data_status);
237
238
239 cd->intr_ls = inw(r_line_status);
240
241 if (cd->intr_ls & ls_receive_buffer_full) {
242 cd->intr_ur = inb(r_uart_receive);
243 cd->intr_ls = inw(r_line_status);
244 if (!cd->background && cd->uart) wake_up_interruptible(&cd->uart);
245 }
246
247 else if (cd->intr_ds & ds_data_ready) {
248 if (cd->background) ++cd->adapter_last;
249 if ((cd->wait_back || !cd->background) && cd->data)
250 wake_up_interruptible(&cd->data);
251 stats(data_ready);
252 }
253
254 else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
255 outw(dc_normal | (inw(r_data_status) & 0x7f), r_data_control);
256 outw(cd->command, r_uart_transmit);
257 cd->command=0;
258 if (!cd->background) wake_up_interruptible(&cd->uart);
259 }
260
261 else if (cd->intr_ds & ds_fifo_overflow) {
262 debug(("Fifo overflow at sectors 0x%x\n", cd->sector_first));
263 fool = inw(r_fifo_output_buffer);
264 cd->fifo_overflowed=1;
265 stats(fifo_overflow);
266 }
267 else if (cd->intr_ds & ds_data_error) {
268 debug(("Data error at sector 0x%x\n", cd->sector_first));
269 stats(data_error);
270 }
271 else if (cd->intr_ds & ds_crc_error) {
272 debug(("CRC error at sector 0x%x\n", cd->sector_first));
273 stats(crc_error);
274 }
275 else if (cd->intr_ds & ds_sync_error) {
276 debug(("Sync at sector 0x%x\n", cd->sector_first));
277 stats(sync_error);
278 }
279 else if (cd->intr_ds & ds_toc_ready) {
280
281 }
282
283 else {
284 outw(dc_normal | READ_AHEAD, r_data_control);
285 stats(lost_intr);
286 }
287 if (cd->background && (cd->adapter_last-cd->adapter_first == cd->max_sectors
288 || cd->fifo_overflowed))
289 mark_bh(CM206_BH);
290 stats(interrupt);
291 }
292
293
294 void cm206_timeout(unsigned long who)
295 {
296 cd->timed_out = 1;
297 wake_up_interruptible((struct wait_queue **) who);
298 }
299
300
301
302 int sleep_or_timeout(struct wait_queue ** wait, int timeout)
303 {
304 cd->timer.data=(unsigned long) wait;
305 cd->timer.expires = timeout;
306 add_timer(&cd->timer);
307 interruptible_sleep_on(wait);
308 del_timer(&cd->timer);
309 if (cd->timed_out) {
310 cd->timed_out = 0;
311 return 1;
312 }
313 else return 0;
314 }
315
316 void cm206_delay(int jiffies)
317 {
318 struct wait_queue * wait = NULL;
319 sleep_or_timeout(&wait, jiffies);
320 }
321
322 void send_command(int command)
323 {
324 if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
325 cd->command = command;
326 cli();
327 outw(dc_mask_sync_error | dc_no_stop_on_error |
328 (inw(r_data_status) & 0x7f), r_data_control);
329
330 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
331 debug(("Time out on write-buffer\n"));
332 stats(write_timeout);
333 outw(command, r_uart_transmit);
334 }
335 }
336 else outw(command, r_uart_transmit);
337 }
338
339 uch receive_echo(void)
340 {
341 if (!(inw(r_line_status) & ls_receive_buffer_full) &&
342 sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
343 debug(("Time out on receive-buffer\n"));
344 stats(receive_timeout);
345 return ((uch) inw(r_uart_receive));
346 }
347 return cd->intr_ur;
348 }
349
350 inline uch send_receive(int command)
351 {
352 send_command(command);
353 return receive_echo();
354 }
355
356 uch wait_dsb(void)
357 {
358 if (!(inw(r_line_status) & ls_receive_buffer_full) &&
359 sleep_or_timeout(&cd->uart, DSB_TIMEOUT)) {
360 debug(("Time out on Drive Status Byte\n"));
361 stats(dsb_timeout);
362 return ((uch) inw(r_uart_receive));
363 }
364 return cd->intr_ur;
365 }
366
367 int type_0_command(int command, int expect_dsb)
368 {
369 int e;
370 if (command != (e=send_receive(command))) {
371 debug(("command 0x%x echoed as 0x%x\n", command, e));
372 stats(echo);
373 return -1;
374 }
375 if (expect_dsb) {
376 cd->dsb = wait_dsb();
377 }
378 return 0;
379 }
380
381 int type_1_command(int command, int bytes, uch * status)
382 {
383 int i;
384 if (type_0_command(command,0)) return -1;
385 for(i=0; i<bytes; i++)
386 status[i] = send_receive(c_gimme);
387 return 0;
388 }
389
390
391
392 void reset_cm260(void)
393 {
394 outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
395 udelay(10);
396 outw(dc_normal | READ_AHEAD, r_data_control);
397 }
398
399
400 void fsm(int lba, uch * fsm)
401 {
402 fsm[0] = lba % 75;
403 lba /= 75; lba += 2;
404 fsm[1] = lba % 60; fsm[2] = lba / 60;
405 }
406
407 inline int fsm2lba(uch * fsm)
408 {
409 return fsm[0] + 75*(fsm[1]-2 + 60*fsm[2]);
410 }
411
412 inline int f_s_m2lba(uch f, uch s, uch m)
413 {
414 return f + 75*(s-2 + 60*m);
415 }
416
417 int start_read(int start)
418 {
419 uch read_sector[4] = {c_read_data, };
420 int i, e;
421
422 fsm(start, &read_sector[1]);
423 for (i=0; i<4; i++)
424 if (read_sector[i] != (e=send_receive(read_sector[i]))) {
425 debug(("read_sector: %x echoes %x\n", read_sector[i], e));
426 stats(echo);
427 return -1;
428 }
429 return 0;
430 }
431
432 int stop_read(void)
433 {
434 type_0_command(c_stop,0);
435 if(receive_echo() != 0xff) {
436 debug(("c_stop didn't send 0xff\n"));
437 stats(stop_0xff);
438 return -1;
439 }
440 return 0;
441 }
442
443
444
445
446
447
448 int read_background(int start, int reading)
449 {
450 if (cd->background) return -1;
451 outw(dc_normal | BACK_AHEAD, r_data_control);
452 if (!reading && start_read(start)) return -2;
453 cd->adapter_first = cd->adapter_last = start;
454 cd->background = 1;
455 return 0;
456 }
457
458 int read_sector(int start)
459 {
460 if (cd->background) {
461 cd->background=0;
462 cd->adapter_last = -1;
463 stop_read();
464 }
465 cd->fifo_overflowed=0;
466 reset_cm260();
467 if (start_read(start)) return -1;
468 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
469 debug(("Read timed out sector 0x%x\n", start));
470 stats(read_timeout);
471 stop_read();
472 return -3;
473 }
474 insw(r_fifo_output_buffer, cd->sector, READ_AHEAD*RAW_SECTOR_SIZE/2);
475 if (read_background(start+READ_AHEAD,1)) stats(read_background);
476 cd->sector_first = start; cd->sector_last = start+READ_AHEAD;
477 stats(read_restarted);
478 return 0;
479 }
480
481
482
483
484
485
486
487
488
489
490
491 void cm206_bh(void * unused)
492 {
493 debug(("bh: %d\n", cd->background));
494 switch (cd->background) {
495 case 1:
496 stats(bh);
497 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
498 cd->command = c_stop;
499 outw(dc_mask_sync_error | dc_no_stop_on_error |
500 (inw(r_data_status) & 0x7f), r_data_control);
501 cd->background=2;
502 break;
503 }
504 else outw(c_stop, r_uart_transmit);
505
506 case 2:
507
508 cd->background=3;
509 break;
510 case 3:
511 if (cd->intr_ur != c_stop) {
512 debug(("cm206_bh: c_stop echoed 0x%x\n", cd->intr_ur));
513 stats(echo);
514 }
515 cd->background++;
516 break;
517 case 4:
518 if (cd->intr_ur != 0xff) {
519 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->intr_ur));
520 stats(stop_0xff);
521 }
522 cd->background=0;
523 }
524 }
525
526 void get_drive_status(void)
527 {
528 uch status[2];
529 type_1_command(c_drive_status, 2, status);
530 cd->dsb=status[0];
531 cd->cc=status[1];
532 }
533
534 void get_disc_status(void)
535 {
536 if (type_1_command(c_disc_status, 7, cd->disc_status)) {
537 debug(("get_disc_status: error\n"));
538 }
539 }
540
541 static int cm206_open(struct inode *ip, struct file *fp)
542 {
543 if (!cd->openfiles) {
544 cd->background=0;
545 reset_cm260();
546 cd->adapter_last = -1;
547 cd->sector_last = -1;
548 get_drive_status();
549 if (cd->dsb & dsb_tray_not_closed) {
550 int i=0;
551 type_0_command(c_close_tray, 1);
552 while (i++<10 && cd->dsb & dsb_drive_not_ready) {
553 cm206_delay(100);
554 get_drive_status();
555 }
556 }
557 if (cd->dsb & (dsb_not_useful)) return -EIO;
558 if (!(cd->dsb & dsb_disc_present)) return -ENODATA;
559 if (cd->dsb & dsb_possible_media_change) {
560 memset(cd->toc, 0, sizeof(cd->toc));
561 memset(cd->audio_status, 0, sizeof(cd->audio_status));
562 }
563 get_disc_status();
564 type_0_command(c_lock_tray,1);
565 if (!(cd->dsb & dsb_tray_locked)) {
566 debug(("Couldn't lock tray\n"));
567 }
568 #if 0
569 if (!(DISC_STATUS & cds_all_audio))
570 read_background(16,0);
571 #endif
572 }
573 ++cd->openfiles; MOD_INC_USE_COUNT;
574 stats(open);
575 return 0;
576 }
577
578 static void cm206_release(struct inode *ip, struct file *fp)
579 {
580 if (cd->openfiles==1) {
581 if (cd->background) {
582 cd->background=0;
583 stop_read();
584 }
585 type_0_command(c_unlock_tray,1);
586 cd->sector_last = -1;
587 FIRST_TRACK = 0;
588 sync_dev(ip -> i_rdev);
589 invalidate_buffers(ip -> i_rdev);
590 }
591 --cd->openfiles; MOD_DEC_USE_COUNT;
592 }
593
594
595
596 void empty_buffer(int sectors)
597 {
598 while (sectors>=0) {
599 insw(r_fifo_output_buffer, cd->sector + cd->fifo_overflowed,
600 RAW_SECTOR_SIZE/2 - cd->fifo_overflowed);
601 --sectors;
602 ++cd->adapter_first;
603 cd->fifo_overflowed=0;
604 stats(sector_transferred);
605 }
606 cd->sector_first=cd->adapter_first-1;
607 cd->sector_last=cd->adapter_first;
608 }
609
610
611
612
613 int try_adapter(int sector)
614 {
615 if (cd->adapter_first <= sector && sector < cd->adapter_last) {
616
617 empty_buffer(sector - cd->adapter_first);
618 return 0;
619 }
620 else if (cd->background==1 && cd->adapter_first <= sector
621 && sector < cd->adapter_first+cd->max_sectors) {
622
623 cd->wait_back=1;
624 while (sector >= cd->adapter_last) {
625 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
626 debug(("Timed out during background wait: %d %d %d %d\n", sector,
627 cd->adapter_last, cd->adapter_first, cd->background));
628 stats(back_read_timeout);
629 cd->wait_back=0;
630 return -1;
631 }
632 }
633 cd->wait_back=0;
634 empty_buffer(sector - cd->adapter_first);
635 return 0;
636 }
637 else return -2;
638 }
639
640
641
642
643 static void do_cm206_request(void)
644 {
645 long int i, cd_sec_no;
646 int quarter, error;
647 uch * source, * dest;
648
649 while(1) {
650 INIT_REQUEST;
651 if (CURRENT == NULL || CURRENT->dev == -1) return;
652 if (CURRENT->cmd != READ) {
653 debug(("Non-read command %d on cdrom\n", CURRENT->cmd));
654 end_request(0);
655 continue;
656 }
657 error=0;
658 for (i=0; i<CURRENT->nr_sectors; i++) {
659 cd_sec_no = (CURRENT->sector+i)/4;
660 quarter = (CURRENT->sector+i) % 4;
661 dest = CURRENT->buffer + i*512;
662
663 if (cd->sector_first <= cd_sec_no && cd_sec_no < cd->sector_last) {
664 source = ((uch *) cd->sector) + 16 +
665 quarter*512 + (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
666 memcpy(dest, source, 512);
667 }
668 else if (!try_adapter(cd_sec_no) || !read_sector(cd_sec_no)) {
669 source = ((uch *) cd->sector)+16+quarter*512;
670 memcpy(dest, source, 512);
671 }
672 else {
673 error=1;
674 }
675 }
676 end_request(!error);
677 }
678 }
679
680 int get_multi_session_info(struct cdrom_multisession * mssp)
681 {
682 if (!FIRST_TRACK) get_disc_status();
683 if (mssp) {
684 if (DISC_STATUS & cds_multi_session) {
685 if (mssp->addr_format == CDROM_LBA)
686 mssp->addr.lba = fsm2lba(&cd->disc_status[3]);
687 else {
688 mssp->addr.msf.frame = cd->disc_status[3];
689 mssp->addr.msf.second = cd->disc_status[4];
690 mssp->addr.msf.minute = cd->disc_status[5];
691 }
692 mssp->xa_flag = 1;
693 } else {
694 mssp->xa_flag = 0;
695 }
696 return 1;
697 }
698 return 0;
699 }
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715 void seek(int lba)
716 {
717 int i;
718 uch seek_command[4]={c_seek, };
719
720 fsm(lba, &seek_command[1]);
721 for (i=0; i<4; i++) type_0_command(seek_command[i], 0);
722 cd->dsb = wait_dsb();
723 }
724
725 uch bcdbin(unsigned char bcd)
726 {
727 return (bcd >> 4)*10 + (bcd & 0xf);
728 }
729
730 inline uch normalize_track(uch track)
731 {
732 if (track<1) return 1;
733 if (track>LAST_TRACK) return LAST_TRACK+1;
734 return track;
735 }
736
737
738
739
740 int get_toc_lba(uch track)
741 {
742 int max=74*60*75-150, min=0;
743 int i, lba, l, old_lba=0;
744 uch * q = cd->q;
745 uch ct;
746 int binary=0;
747 const skip = 3*60*75;
748
749 for (i=track; i>0; i--) if (cd->toc[i].track) {
750 min = fsm2lba(cd->toc[i].fsm);
751 break;
752 }
753 lba = min + skip;
754 do {
755 seek(lba);
756 type_1_command(c_read_current_q, 10, q);
757 ct = normalize_track(q[1]);
758 if (!cd->toc[ct].track) {
759 l = q[9]-bcdbin(q[5]) + 75*(q[8]-bcdbin(q[4])-2 +
760 60*(q[7]-bcdbin(q[3])));
761 cd->toc[ct].track=q[1];
762 fsm(l, cd->toc[ct].fsm);
763 cd->toc[ct].q0 = q[0];
764
765
766
767
768
769 if (ct==track) return l;
770 }
771 old_lba=lba;
772 if (binary) {
773 if (ct < track) min = lba; else max = lba;
774 lba = (min+max)/2;
775 } else {
776 if(ct < track) lba += skip;
777 else {
778 binary=1;
779 max = lba; min = lba - skip;
780 lba = (min+max)/2;
781 }
782 }
783 } while (lba!=old_lba);
784 return lba;
785 }
786
787 void update_toc_entry(uch track)
788 {
789 track = normalize_track(track);
790 if (!cd->toc[track].track) get_toc_lba(track);
791 }
792
793 int read_toc_header(struct cdrom_tochdr * hp)
794 {
795 if (!FIRST_TRACK) get_disc_status();
796 if (hp && DISC_STATUS & cds_all_audio) {
797 int i;
798 hp->cdth_trk0 = FIRST_TRACK;
799 hp->cdth_trk1 = LAST_TRACK;
800 cd->toc[1].track=1;
801 for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
802 update_toc_entry(LAST_TRACK+1);
803 return 1;
804 }
805 return 0;
806 }
807
808 void play_from_to_msf(struct cdrom_msf* msfp)
809 {
810 uch play_command[] = {c_play,
811 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
812 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, 2};
813 int i;
814 for (i=0; i<9; i++) type_0_command(play_command[i], 0);
815 for (i=0; i<3; i++)
816 PLAY_TO.fsm[i] = play_command[i+4];
817 PLAY_TO.track = 0;
818 cd->dsb = wait_dsb();
819 }
820
821 void play_from_to_track(int from, int to)
822 {
823 uch play_command[8] = {c_play, };
824 int i;
825
826 if (from==0) {
827 for (i=0; i<3; i++) {
828 play_command[i+1] = cd->audio_status[i+2];
829 play_command[i+4] = PLAY_TO.fsm[i];
830 }
831 } else {
832 update_toc_entry(from); update_toc_entry(to+1);
833 for (i=0; i<3; i++) {
834 play_command[i+1] = cd->toc[from].fsm[i];
835 PLAY_TO.fsm[i] = play_command[i+4] = cd->toc[to+1].fsm[i];
836 }
837 PLAY_TO.track = to;
838 }
839 for (i=0; i<7; i++) type_0_command(play_command[i],0);
840 for (i=0; i<2; i++) type_0_command(0x2, 0);
841 cd->dsb = wait_dsb();
842 }
843
844 int get_current_q(struct cdrom_subchnl * qp)
845 {
846 int i;
847 uch * q = cd->q;
848 if (type_1_command(c_read_current_q, 10, q)) return 0;
849
850 for (i=2; i<6; i++) q[i]=bcdbin(q[i]);
851 qp->cdsc_adr = q[0] & 0xf; qp->cdsc_ctrl = q[0] >> 4;
852 qp->cdsc_trk = q[1]; qp->cdsc_ind = q[2];
853 if (qp->cdsc_format == CDROM_MSF) {
854 qp->cdsc_reladdr.msf.minute = q[3];
855 qp->cdsc_reladdr.msf.second = q[4];
856 qp->cdsc_reladdr.msf.frame = q[5];
857 qp->cdsc_absaddr.msf.minute = q[7];
858 qp->cdsc_absaddr.msf.second = q[8];
859 qp->cdsc_absaddr.msf.frame = q[9];
860 } else {
861 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
862 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
863 }
864 get_drive_status();
865 if (cd->dsb & dsb_play_in_progress)
866 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY ;
867 else if (PAUSED)
868 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
869 else qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
870 return 1;
871 }
872
873 void get_toc_entry(struct cdrom_tocentry * ep)
874 {
875 uch track = normalize_track(ep->cdte_track);
876 update_toc_entry(track);
877 if (ep->cdte_format == CDROM_MSF) {
878 ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
879 ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
880 ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
881 }
882 else ep->cdte_addr.lba = fsm2lba(cd->toc[track].fsm);
883 ep->cdte_adr = cd->toc[track].q0 & 0xf;
884 ep->cdte_ctrl = cd->toc[track].q0 >> 4;
885 ep->cdte_datamode=0;
886 }
887
888
889
890
891
892
893 static int cm206_ioctl(struct inode * inode, struct file * file,
894 unsigned int cmd, unsigned long arg)
895 {
896 switch (cmd) {
897 #ifdef STATISTICS
898 case CM206CTL_GET_STAT:
899 if (arg >= NR_STATS) return -EINVAL;
900 else return cd->stats[arg];
901 case CM206CTL_GET_LAST_STAT:
902 if (arg >= NR_STATS) return -EINVAL;
903 else return cd->last_stat[arg];
904 #endif
905 case CDROMMULTISESSION: {
906 struct cdrom_multisession ms_info;
907 int st;
908 stats(ioctl_multisession);
909
910 st=verify_area(VERIFY_WRITE, (void *) arg,
911 sizeof(struct cdrom_multisession));
912 if (st) return (st);
913 memcpy_fromfs(&ms_info, (struct cdrom_multisession *) arg,
914 sizeof(struct cdrom_multisession));
915 get_multi_session_info(&ms_info);
916 memcpy_tofs((struct cdrom_multisession *) arg, &ms_info,
917 sizeof(struct cdrom_multisession));
918 return 0;
919 }
920 case CDROMRESET:
921 stop_read();
922 reset_cm260();
923 outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
924 udelay(1000);
925 outw(dc_normal | READ_AHEAD, r_data_control);
926 cd->sector_last = -1;
927 cd->adapter_last = -1;
928 return 0;
929 }
930
931 get_drive_status();
932 if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) )
933 return -EAGAIN;
934
935 switch (cmd) {
936 case CDROMREADTOCHDR: {
937 struct cdrom_tochdr header;
938 int st;
939
940 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(header));
941 if (st) return (st);
942 if (read_toc_header(&header)) {
943 memcpy_tofs((struct cdrom_tochdr *) arg, &header, sizeof(header));
944 return 0;
945 }
946 else return -ENODATA;
947 }
948 case CDROMREADTOCENTRY: {
949 struct cdrom_tocentry entry;
950 int st;
951
952 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(entry));
953 if (st) return (st);
954 memcpy_fromfs(&entry, (struct cdrom_tocentry *) arg, sizeof entry);
955 get_toc_entry(&entry);
956 memcpy_tofs((struct cdrom_tocentry *) arg, &entry, sizeof entry);
957 return 0;
958 }
959 case CDROMPLAYMSF: {
960 struct cdrom_msf msf;
961 int st;
962
963 st=verify_area(VERIFY_READ, (void *) arg, sizeof(msf));
964 if (st) return (st);
965 memcpy_fromfs(&msf, (struct cdrom_mdf *) arg, sizeof msf);
966 play_from_to_msf(&msf);
967 return 0;
968 }
969 case CDROMPLAYTRKIND: {
970 struct cdrom_ti track_index;
971 int st;
972
973 st=verify_area(VERIFY_READ, (void *) arg, sizeof(track_index));
974 if (st) return (st);
975 memcpy_fromfs(&track_index, (struct cdrom_ti *) arg, sizeof(track_index));
976 play_from_to_track(track_index.cdti_trk0, track_index.cdti_trk1);
977 return 0;
978 }
979 case CDROMSTOP:
980 PAUSED=0;
981 if (cd->dsb & dsb_play_in_progress) return type_0_command(c_stop, 1);
982 return 0;
983 case CDROMPAUSE:
984 if (cd->dsb & dsb_play_in_progress) {
985 type_0_command(c_stop, 1);
986 type_1_command(c_audio_status, 5, cd->audio_status);
987 PAUSED=1;
988 }
989 return 0;
990 case CDROMRESUME:
991 if (PAUSED) play_from_to_track(0,0);
992 PAUSED=0;
993 return 0;
994 case CDROMEJECT:
995 PAUSED=0;
996 if (cd->openfiles == 1) {
997 type_0_command(c_open_tray,1);
998 memset(cd->toc, 0, sizeof(cd->toc));
999 memset(cd->disc_status, 0, sizeof(cd->disc_status));
1000 return 0;
1001 }
1002 else return -EBUSY;
1003 case CDROMSTART:
1004 case CDROMVOLCTRL:
1005 return 0;
1006 case CDROMSUBCHNL: {
1007 struct cdrom_subchnl q;
1008 int st;
1009
1010 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(q));
1011 if (st) return (st);
1012 memcpy_fromfs(&q, (struct cdrom_subchnl *) arg, sizeof q);
1013 if (get_current_q(&q)) {
1014 memcpy_tofs((struct cdrom_subchnl *) arg, &q, sizeof q);
1015 return 0;
1016 }
1017 else return -cmd;
1018 }
1019 case CDROM_GET_UPC: {
1020 uch upc[10];
1021 int st;
1022
1023 st=verify_area(VERIFY_WRITE, (void *) arg, 8);
1024 if (st) return (st);
1025 if (type_1_command(c_read_upc, 10, upc)) return -EIO;
1026 memcpy_tofs((uch *) arg, &upc[1], 8);
1027 return 0;
1028 }
1029 default:
1030 debug(("Unknown ioctl call 0x%x\n", cmd));
1031 return -EINVAL;
1032 }
1033 }
1034
1035
1036 static struct file_operations cm206_fops = {
1037 NULL,
1038 block_read,
1039 block_write,
1040 NULL,
1041 NULL,
1042 cm206_ioctl,
1043 NULL,
1044 cm206_open,
1045 cm206_release,
1046 NULL,
1047 NULL,
1048 NULL,
1049 NULL
1050 };
1051
1052
1053
1054 void cleanup(int level)
1055 {
1056 switch (level) {
1057 case 4:
1058 if (unregister_blkdev(MAJOR_NR, "cm206")) {
1059 printk("Can't unregister cm206\n");
1060 return;
1061 }
1062 case 3:
1063 free_irq(cm206_irq);
1064 case 2:
1065 case 1:
1066 #ifdef MODULE
1067 kfree(cd);
1068 #endif
1069 release_region(cm206_base, 16);
1070 default:
1071 }
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 int probe_base_port(int base)
1085 {
1086 int b=0x300, e=0x370;
1087 volatile int fool;
1088 #if 0
1089 const pattern1=0x65, pattern2=0x1a;
1090 #endif
1091
1092 if (base) b=e=base;
1093 for (base=b; base<=e; base += 0x10) {
1094 if (check_region(base, 0x10)) continue;
1095 fool = inw(base+2);
1096 if((inw(base+6) & 0xffef) != 0x0001 ||
1097 (inw(base) & 0xad00) != 0)
1098 continue;
1099 #if 0
1100 outw(dc_normal | pattern1, base+8);
1101 if ((inw(base) & 0x7f) != pattern1) continue;
1102 outw(dc_normal | pattern2, base+8);
1103 if ((inw(base) & 0x7f) != pattern2) continue;
1104 outw(dc_normal | READ_AHEAD, base+8);
1105 #endif
1106 return(base);
1107 }
1108 return 0;
1109 }
1110
1111 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1112
1113 int probe_irq(int nr) {
1114 int irqs, irq;
1115 outw(dc_normal | READ_AHEAD, r_data_control);
1116 sti();
1117 irqs = probe_irq_on();
1118 reset_cm260();
1119 udelay(10);
1120 irq = probe_irq_off(irqs);
1121 outw(dc_normal | READ_AHEAD, r_data_control);
1122 if (nr && irq!=nr && irq>0) return 0;
1123 else return irq;
1124 }
1125 #endif
1126
1127 #ifdef MODULE
1128 #define OK 0
1129 #define ERROR -EIO
1130
1131 static int cm206[2] = {0,0};
1132 void parse_options()
1133 {
1134 int i;
1135 for (i=0; i<2; i++) {
1136 if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
1137 cm206_base = cm206[i];
1138 auto_probe=0;
1139 }
1140 else if (3 <= cm206[i] && cm206[i] <= 15) {
1141 cm206_irq = cm206[i];
1142 auto_probe=0;
1143 }
1144 }
1145 }
1146
1147 #else MODULE
1148
1149 #define OK mem_start+size
1150 #define ERROR mem_start
1151
1152 #endif MODULE
1153
1154 #ifdef MODULE
1155 int init_module(void)
1156 #else
1157 unsigned long cm206_init(unsigned long mem_start, unsigned long mem_end)
1158 #endif
1159 {
1160 uch e=0;
1161 long int size=sizeof(struct cm206_struct);
1162
1163 printk("cm206: v" VERSION);
1164 #if defined(MODULE)
1165 parse_options();
1166 #if !defined(AUTO_PROBE_MODULE)
1167 auto_probe=0;
1168 #endif
1169 #endif
1170 cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1171 if (!cm206_base) {
1172 printk(" can't find adapter!\n");
1173 return ERROR;
1174 }
1175 printk(" adapter at 0x%x", cm206_base);
1176 request_region(cm206_base, 16, "cm206");
1177 #ifdef MODULE
1178 cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1179 if (!cd) return ERROR;
1180 #else
1181 cd = (struct cm206_struct *) mem_start;
1182 #endif
1183
1184
1185
1186 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1187 cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1188 if (cm206_irq<=0) {
1189 printk("can't find IRQ!\n");
1190 cleanup(1);
1191 return ERROR;
1192 }
1193 else printk(" IRQ %d found\n", cm206_irq);
1194 #else
1195 reset_cm260();
1196 printk(" using IRQ %d\n", cm206_irq);
1197 #endif
1198 if (send_receive_polled(c_drive_configuration) != c_drive_configuration)
1199 {
1200 printk(" drive not there\n");
1201 cleanup(1);
1202 return ERROR;
1203 }
1204 e = send_receive_polled(c_gimme);
1205 printk("Firmware revision %d", e & dcf_revision_code);
1206 if (e & dcf_transfer_rate) printk(" double");
1207 else printk(" single");
1208 printk(" speed drive");
1209 if (e & dcf_motorized_tray) printk(", motorized tray");
1210 if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206")) {
1211 printk("\nUnable to reserve IRQ---aborted\n");
1212 cleanup(2);
1213 return ERROR;
1214 }
1215 printk(".\n");
1216 if (register_blkdev(MAJOR_NR, "cm206", &cm206_fops) != 0) {
1217 printk("Cannot register for major %d!\n", MAJOR_NR);
1218 cleanup(3);
1219 return ERROR;
1220 }
1221 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1222 read_ahead[MAJOR_NR] = 16;
1223 bh_base[CM206_BH].routine = cm206_bh;
1224 enable_bh(CM206_BH);
1225
1226 memset(cd, 0, sizeof(*cd));
1227 cd->sector_last = -1;
1228 cd->adapter_last = -1;
1229 cd->timer.function = cm206_timeout;
1230 cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1231 printk("%d kB adapter memory available, "
1232 " %ld bytes kernel memory used.\n", cd->max_sectors*2, size);
1233 return OK;
1234 }
1235 #undef OK
1236 #undef ERROR
1237
1238 #ifdef MODULE
1239 void cleanup_module(void)
1240 {
1241 cleanup(4);
1242 printk("cm206 removed\n");
1243 }
1244
1245 #else MODULE
1246
1247
1248
1249 void cm206_setup(char *s, int *p)
1250 {
1251 int i;
1252 if (!strcmp(s, "auto")) auto_probe=1;
1253 for(i=1; i<=p[0]; i++) {
1254 if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
1255 cm206_base = p[i];
1256 auto_probe = 0;
1257 }
1258 else if (3 <= p[i] && p[i] <= 15) {
1259 cm206_irq = p[i];
1260 auto_probe = 0;
1261 }
1262 }
1263 }
1264 #endif MODULE