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
- cm206_init
- 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 #ifndef CONFIG_MODVERSIONS
88 char kernel_version[]=UTS_RELEASE;
89 #endif
90 #else
91 #define MOD_INC_USE_COUNT
92 #define MOD_DEC_USE_COUNT
93 #endif MODULE
94
95 #include <linux/errno.h>
96 #include <linux/delay.h>
97 #include <linux/string.h>
98 #include <linux/sched.h>
99 #include <linux/interrupt.h>
100 #include <linux/timer.h>
101 #include <linux/cdrom.h>
102 #include <linux/ioport.h>
103 #include <linux/mm.h>
104 #include <linux/malloc.h>
105
106 #include <asm/io.h>
107
108 #define MAJOR_NR CM206_CDROM_MAJOR
109 #include <linux/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 (3*HZ)
130 #define UART_TIMEOUT (5*HZ/100)
131 #define DSB_TIMEOUT (7*HZ)
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 = jiffies + 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->rq_status == RQ_INACTIVE)
652 return;
653 if (CURRENT->cmd != READ) {
654 debug(("Non-read command %d on cdrom\n", CURRENT->cmd));
655 end_request(0);
656 continue;
657 }
658 error=0;
659 for (i=0; i<CURRENT->nr_sectors; i++) {
660 cd_sec_no = (CURRENT->sector+i)/4;
661 quarter = (CURRENT->sector+i) % 4;
662 dest = CURRENT->buffer + i*512;
663
664 if (cd->sector_first <= cd_sec_no && cd_sec_no < cd->sector_last) {
665 source = ((uch *) cd->sector) + 16 +
666 quarter*512 + (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
667 memcpy(dest, source, 512);
668 }
669 else if (!try_adapter(cd_sec_no) || !read_sector(cd_sec_no)) {
670 source = ((uch *) cd->sector)+16+quarter*512;
671 memcpy(dest, source, 512);
672 }
673 else {
674 error=1;
675 }
676 }
677 end_request(!error);
678 }
679 }
680
681 int get_multi_session_info(struct cdrom_multisession * mssp)
682 {
683 if (!FIRST_TRACK) get_disc_status();
684 if (mssp) {
685 if (DISC_STATUS & cds_multi_session) {
686 if (mssp->addr_format == CDROM_LBA)
687 mssp->addr.lba = fsm2lba(&cd->disc_status[3]);
688 else {
689 mssp->addr.msf.frame = cd->disc_status[3];
690 mssp->addr.msf.second = cd->disc_status[4];
691 mssp->addr.msf.minute = cd->disc_status[5];
692 }
693 mssp->xa_flag = 1;
694 } else {
695 mssp->xa_flag = 0;
696 }
697 return 1;
698 }
699 return 0;
700 }
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716 void seek(int lba)
717 {
718 int i;
719 uch seek_command[4]={c_seek, };
720
721 fsm(lba, &seek_command[1]);
722 for (i=0; i<4; i++) type_0_command(seek_command[i], 0);
723 cd->dsb = wait_dsb();
724 }
725
726 uch bcdbin(unsigned char bcd)
727 {
728 return (bcd >> 4)*10 + (bcd & 0xf);
729 }
730
731 inline uch normalize_track(uch track)
732 {
733 if (track<1) return 1;
734 if (track>LAST_TRACK) return LAST_TRACK+1;
735 return track;
736 }
737
738
739
740
741 int get_toc_lba(uch track)
742 {
743 int max=74*60*75-150, min=0;
744 int i, lba, l, old_lba=0;
745 uch * q = cd->q;
746 uch ct;
747 int binary=0;
748 const skip = 3*60*75;
749
750 for (i=track; i>0; i--) if (cd->toc[i].track) {
751 min = fsm2lba(cd->toc[i].fsm);
752 break;
753 }
754 lba = min + skip;
755 do {
756 seek(lba);
757 type_1_command(c_read_current_q, 10, q);
758 ct = normalize_track(q[1]);
759 if (!cd->toc[ct].track) {
760 l = q[9]-bcdbin(q[5]) + 75*(q[8]-bcdbin(q[4])-2 +
761 60*(q[7]-bcdbin(q[3])));
762 cd->toc[ct].track=q[1];
763 fsm(l, cd->toc[ct].fsm);
764 cd->toc[ct].q0 = q[0];
765
766
767
768
769
770 if (ct==track) return l;
771 }
772 old_lba=lba;
773 if (binary) {
774 if (ct < track) min = lba; else max = lba;
775 lba = (min+max)/2;
776 } else {
777 if(ct < track) lba += skip;
778 else {
779 binary=1;
780 max = lba; min = lba - skip;
781 lba = (min+max)/2;
782 }
783 }
784 } while (lba!=old_lba);
785 return lba;
786 }
787
788 void update_toc_entry(uch track)
789 {
790 track = normalize_track(track);
791 if (!cd->toc[track].track) get_toc_lba(track);
792 }
793
794 int read_toc_header(struct cdrom_tochdr * hp)
795 {
796 if (!FIRST_TRACK) get_disc_status();
797 if (hp && DISC_STATUS & cds_all_audio) {
798 int i;
799 hp->cdth_trk0 = FIRST_TRACK;
800 hp->cdth_trk1 = LAST_TRACK;
801 cd->toc[1].track=1;
802 for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
803 update_toc_entry(LAST_TRACK+1);
804 return 1;
805 }
806 return 0;
807 }
808
809 void play_from_to_msf(struct cdrom_msf* msfp)
810 {
811 uch play_command[] = {c_play,
812 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
813 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, 2};
814 int i;
815 for (i=0; i<9; i++) type_0_command(play_command[i], 0);
816 for (i=0; i<3; i++)
817 PLAY_TO.fsm[i] = play_command[i+4];
818 PLAY_TO.track = 0;
819 cd->dsb = wait_dsb();
820 }
821
822 void play_from_to_track(int from, int to)
823 {
824 uch play_command[8] = {c_play, };
825 int i;
826
827 if (from==0) {
828 for (i=0; i<3; i++) {
829 play_command[i+1] = cd->audio_status[i+2];
830 play_command[i+4] = PLAY_TO.fsm[i];
831 }
832 } else {
833 update_toc_entry(from); update_toc_entry(to+1);
834 for (i=0; i<3; i++) {
835 play_command[i+1] = cd->toc[from].fsm[i];
836 PLAY_TO.fsm[i] = play_command[i+4] = cd->toc[to+1].fsm[i];
837 }
838 PLAY_TO.track = to;
839 }
840 for (i=0; i<7; i++) type_0_command(play_command[i],0);
841 for (i=0; i<2; i++) type_0_command(0x2, 0);
842 cd->dsb = wait_dsb();
843 }
844
845 int get_current_q(struct cdrom_subchnl * qp)
846 {
847 int i;
848 uch * q = cd->q;
849 if (type_1_command(c_read_current_q, 10, q)) return 0;
850
851 for (i=2; i<6; i++) q[i]=bcdbin(q[i]);
852 qp->cdsc_adr = q[0] & 0xf; qp->cdsc_ctrl = q[0] >> 4;
853 qp->cdsc_trk = q[1]; qp->cdsc_ind = q[2];
854 if (qp->cdsc_format == CDROM_MSF) {
855 qp->cdsc_reladdr.msf.minute = q[3];
856 qp->cdsc_reladdr.msf.second = q[4];
857 qp->cdsc_reladdr.msf.frame = q[5];
858 qp->cdsc_absaddr.msf.minute = q[7];
859 qp->cdsc_absaddr.msf.second = q[8];
860 qp->cdsc_absaddr.msf.frame = q[9];
861 } else {
862 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
863 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
864 }
865 get_drive_status();
866 if (cd->dsb & dsb_play_in_progress)
867 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY ;
868 else if (PAUSED)
869 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
870 else qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
871 return 1;
872 }
873
874 void get_toc_entry(struct cdrom_tocentry * ep)
875 {
876 uch track = normalize_track(ep->cdte_track);
877 update_toc_entry(track);
878 if (ep->cdte_format == CDROM_MSF) {
879 ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
880 ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
881 ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
882 }
883 else ep->cdte_addr.lba = fsm2lba(cd->toc[track].fsm);
884 ep->cdte_adr = cd->toc[track].q0 & 0xf;
885 ep->cdte_ctrl = cd->toc[track].q0 >> 4;
886 ep->cdte_datamode=0;
887 }
888
889
890
891
892
893
894 static int cm206_ioctl(struct inode * inode, struct file * file,
895 unsigned int cmd, unsigned long arg)
896 {
897 switch (cmd) {
898 #ifdef STATISTICS
899 case CM206CTL_GET_STAT:
900 if (arg >= NR_STATS) return -EINVAL;
901 else return cd->stats[arg];
902 case CM206CTL_GET_LAST_STAT:
903 if (arg >= NR_STATS) return -EINVAL;
904 else return cd->last_stat[arg];
905 #endif
906 case CDROMMULTISESSION: {
907 struct cdrom_multisession ms_info;
908 int st;
909 stats(ioctl_multisession);
910
911 st=verify_area(VERIFY_WRITE, (void *) arg,
912 sizeof(struct cdrom_multisession));
913 if (st) return (st);
914 memcpy_fromfs(&ms_info, (struct cdrom_multisession *) arg,
915 sizeof(struct cdrom_multisession));
916 get_multi_session_info(&ms_info);
917 memcpy_tofs((struct cdrom_multisession *) arg, &ms_info,
918 sizeof(struct cdrom_multisession));
919 return 0;
920 }
921 case CDROMRESET:
922 stop_read();
923 reset_cm260();
924 outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
925 udelay(1000);
926 outw(dc_normal | READ_AHEAD, r_data_control);
927 cd->sector_last = -1;
928 cd->adapter_last = -1;
929 return 0;
930 }
931
932 get_drive_status();
933 if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) )
934 return -EAGAIN;
935
936 switch (cmd) {
937 case CDROMREADTOCHDR: {
938 struct cdrom_tochdr header;
939 int st;
940
941 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(header));
942 if (st) return (st);
943 if (read_toc_header(&header)) {
944 memcpy_tofs((struct cdrom_tochdr *) arg, &header, sizeof(header));
945 return 0;
946 }
947 else return -ENODATA;
948 }
949 case CDROMREADTOCENTRY: {
950 struct cdrom_tocentry entry;
951 int st;
952
953 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(entry));
954 if (st) return (st);
955 memcpy_fromfs(&entry, (struct cdrom_tocentry *) arg, sizeof entry);
956 get_toc_entry(&entry);
957 memcpy_tofs((struct cdrom_tocentry *) arg, &entry, sizeof entry);
958 return 0;
959 }
960 case CDROMPLAYMSF: {
961 struct cdrom_msf msf;
962 int st;
963
964 st=verify_area(VERIFY_READ, (void *) arg, sizeof(msf));
965 if (st) return (st);
966 memcpy_fromfs(&msf, (struct cdrom_mdf *) arg, sizeof msf);
967 play_from_to_msf(&msf);
968 return 0;
969 }
970 case CDROMPLAYTRKIND: {
971 struct cdrom_ti track_index;
972 int st;
973
974 st=verify_area(VERIFY_READ, (void *) arg, sizeof(track_index));
975 if (st) return (st);
976 memcpy_fromfs(&track_index, (struct cdrom_ti *) arg, sizeof(track_index));
977 play_from_to_track(track_index.cdti_trk0, track_index.cdti_trk1);
978 return 0;
979 }
980 case CDROMSTOP:
981 PAUSED=0;
982 if (cd->dsb & dsb_play_in_progress) return type_0_command(c_stop, 1);
983 return 0;
984 case CDROMPAUSE:
985 if (cd->dsb & dsb_play_in_progress) {
986 type_0_command(c_stop, 1);
987 type_1_command(c_audio_status, 5, cd->audio_status);
988 PAUSED=1;
989 }
990 return 0;
991 case CDROMRESUME:
992 if (PAUSED) play_from_to_track(0,0);
993 PAUSED=0;
994 return 0;
995 case CDROMEJECT:
996 PAUSED=0;
997 if (cd->openfiles == 1) {
998 type_0_command(c_open_tray,1);
999 memset(cd->toc, 0, sizeof(cd->toc));
1000 memset(cd->disc_status, 0, sizeof(cd->disc_status));
1001 return 0;
1002 }
1003 else return -EBUSY;
1004 case CDROMSTART:
1005 case CDROMVOLCTRL:
1006 return 0;
1007 case CDROMSUBCHNL: {
1008 struct cdrom_subchnl q;
1009 int st;
1010
1011 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(q));
1012 if (st) return (st);
1013 memcpy_fromfs(&q, (struct cdrom_subchnl *) arg, sizeof q);
1014 if (get_current_q(&q)) {
1015 memcpy_tofs((struct cdrom_subchnl *) arg, &q, sizeof q);
1016 return 0;
1017 }
1018 else return -cmd;
1019 }
1020 case CDROM_GET_UPC: {
1021 uch upc[10];
1022 int st;
1023
1024 st=verify_area(VERIFY_WRITE, (void *) arg, 8);
1025 if (st) return (st);
1026 if (type_1_command(c_read_upc, 10, upc)) return -EIO;
1027 memcpy_tofs((uch *) arg, &upc[1], 8);
1028 return 0;
1029 }
1030 default:
1031 debug(("Unknown ioctl call 0x%x\n", cmd));
1032 return -EINVAL;
1033 }
1034 }
1035
1036
1037 static struct file_operations cm206_fops = {
1038 NULL,
1039 block_read,
1040 block_write,
1041 NULL,
1042 NULL,
1043 cm206_ioctl,
1044 NULL,
1045 cm206_open,
1046 cm206_release,
1047 NULL,
1048 NULL,
1049 NULL,
1050 NULL
1051 };
1052
1053
1054
1055 void cleanup(int level)
1056 {
1057 switch (level) {
1058 case 4:
1059 if (unregister_blkdev(MAJOR_NR, "cm206")) {
1060 printk("Can't unregister cm206\n");
1061 return;
1062 }
1063 case 3:
1064 free_irq(cm206_irq);
1065 case 2:
1066 case 1:
1067 kfree(cd);
1068 release_region(cm206_base, 16);
1069 default:
1070 }
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083 int probe_base_port(int base)
1084 {
1085 int b=0x300, e=0x370;
1086 volatile int fool;
1087 #if 0
1088 const pattern1=0x65, pattern2=0x1a;
1089 #endif
1090
1091 if (base) b=e=base;
1092 for (base=b; base<=e; base += 0x10) {
1093 if (check_region(base, 0x10)) continue;
1094 fool = inw(base+2);
1095 if((inw(base+6) & 0xffef) != 0x0001 ||
1096 (inw(base) & 0xad00) != 0)
1097 continue;
1098 #if 0
1099 outw(dc_normal | pattern1, base+8);
1100 if ((inw(base) & 0x7f) != pattern1) continue;
1101 outw(dc_normal | pattern2, base+8);
1102 if ((inw(base) & 0x7f) != pattern2) continue;
1103 outw(dc_normal | READ_AHEAD, base+8);
1104 #endif
1105 return(base);
1106 }
1107 return 0;
1108 }
1109
1110 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1111
1112 int probe_irq(int nr) {
1113 int irqs, irq;
1114 outw(dc_normal | READ_AHEAD, r_data_control);
1115 sti();
1116 irqs = probe_irq_on();
1117 reset_cm260();
1118 udelay(10);
1119 irq = probe_irq_off(irqs);
1120 outw(dc_normal | READ_AHEAD, r_data_control);
1121 if (nr && irq!=nr && irq>0) return 0;
1122 else return irq;
1123 }
1124 #endif
1125
1126 #ifdef MODULE
1127
1128 static int cm206[2] = {0,0};
1129 void parse_options(void)
1130 {
1131 int i;
1132 for (i=0; i<2; i++) {
1133 if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
1134 cm206_base = cm206[i];
1135 auto_probe=0;
1136 }
1137 else if (3 <= cm206[i] && cm206[i] <= 15) {
1138 cm206_irq = cm206[i];
1139 auto_probe=0;
1140 }
1141 }
1142 }
1143
1144 #define cm206_init init_module
1145
1146 #endif MODULE
1147
1148
1149 int cm206_init(void)
1150 {
1151 uch e=0;
1152 long int size=sizeof(struct cm206_struct);
1153
1154 printk("cm206: v" VERSION);
1155 #if defined(MODULE)
1156 parse_options();
1157 #if !defined(AUTO_PROBE_MODULE)
1158 auto_probe=0;
1159 #endif
1160 #endif
1161 cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1162 if (!cm206_base) {
1163 printk(" can't find adapter!\n");
1164 return -EIO;
1165 }
1166 printk(" adapter at 0x%x", cm206_base);
1167 request_region(cm206_base, 16, "cm206");
1168 cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1169 if (!cd) return -EIO;
1170
1171
1172
1173 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1174 cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1175 if (cm206_irq<=0) {
1176 printk("can't find IRQ!\n");
1177 cleanup(1);
1178 return -EIO;
1179 }
1180 else printk(" IRQ %d found\n", cm206_irq);
1181 #else
1182 reset_cm260();
1183 printk(" using IRQ %d\n", cm206_irq);
1184 #endif
1185 if (send_receive_polled(c_drive_configuration) != c_drive_configuration)
1186 {
1187 printk(" drive not there\n");
1188 cleanup(1);
1189 return -EIO;
1190 }
1191 e = send_receive_polled(c_gimme);
1192 printk("Firmware revision %d", e & dcf_revision_code);
1193 if (e & dcf_transfer_rate) printk(" double");
1194 else printk(" single");
1195 printk(" speed drive");
1196 if (e & dcf_motorized_tray) printk(", motorized tray");
1197 if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206")) {
1198 printk("\nUnable to reserve IRQ---aborted\n");
1199 cleanup(2);
1200 return -EIO;
1201 }
1202 printk(".\n");
1203 if (register_blkdev(MAJOR_NR, "cm206", &cm206_fops) != 0) {
1204 printk("Cannot register for major %d!\n", MAJOR_NR);
1205 cleanup(3);
1206 return -EIO;
1207 }
1208 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1209 read_ahead[MAJOR_NR] = 16;
1210 bh_base[CM206_BH].routine = cm206_bh;
1211 enable_bh(CM206_BH);
1212
1213 memset(cd, 0, sizeof(*cd));
1214 cd->sector_last = -1;
1215 cd->adapter_last = -1;
1216 cd->timer.function = cm206_timeout;
1217 cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1218 printk("%d kB adapter memory available, "
1219 " %ld bytes kernel memory used.\n", cd->max_sectors*2, size);
1220 return 0;
1221 }
1222
1223 #ifdef MODULE
1224 void cleanup_module(void)
1225 {
1226 cleanup(4);
1227 printk("cm206 removed\n");
1228 }
1229
1230 #else MODULE
1231
1232
1233
1234 void cm206_setup(char *s, int *p)
1235 {
1236 int i;
1237 if (!strcmp(s, "auto")) auto_probe=1;
1238 for(i=1; i<=p[0]; i++) {
1239 if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
1240 cm206_base = p[i];
1241 auto_probe = 0;
1242 }
1243 else if (3 <= p[i] && p[i] <= 15) {
1244 cm206_irq = p[i];
1245 auto_probe = 0;
1246 }
1247 }
1248 }
1249 #endif MODULE