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