This source file includes following definitions.
- check_cdu31a_media_change
- sony_sleep
- is_attention
- is_busy
- is_data_ready
- is_data_requested
- is_result_ready
- is_param_write_rdy
- reset_drive
- clear_attention
- clear_result_ready
- clear_data_ready
- clear_param_reg
- read_status_register
- read_result_register
- read_data_register
- write_param
- write_cmd
- write_params
- get_result
- get_data
- do_sony_cd_cmd
- handle_sony_cd_attention
- int_to_bcd
- bcd_to_int
- log_to_msf
- msf_to_log
- size_to_buf
- do_cdu31a_request
- sony_get_toc
- find_track
- read_subcode
- sony_get_subchnl_info
- scd_ioctl
- scd_open
- scd_release
- get_drive_configuration
- cdu31a_init
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 #include <linux/config.h>
63 #ifdef CONFIG_CDU31A
64
65 #include <linux/errno.h>
66 #include <linux/signal.h>
67 #include <linux/sched.h>
68 #include <linux/timer.h>
69 #include <linux/fs.h>
70 #include <linux/kernel.h>
71 #include <linux/hdreg.h>
72 #include <linux/genhd.h>
73
74 #include <asm/system.h>
75 #include <asm/io.h>
76 #include <asm/segment.h>
77
78 #include <linux/cdrom.h>
79 #include <linux/cdu31a.h>
80
81 #define MAJOR_NR 15
82 #include "blk.h"
83
84
85 static unsigned short cdu31a_addresses[] =
86 {
87 0x340,
88 0x1f88,
89 0x360,
90 0x320,
91 0x330,
92 0
93 };
94
95
96 static int handle_sony_cd_attention(void);
97 static int read_subcode(void);
98 static void sony_get_toc(void);
99 static int scd_open(struct inode *inode, struct file *filp);
100
101
102
103
104 static unsigned short sony_cd_base_io = 0;
105
106
107
108
109
110 static volatile unsigned short sony_cd_cmd_reg;
111 static volatile unsigned short sony_cd_param_reg;
112 static volatile unsigned short sony_cd_write_reg;
113 static volatile unsigned short sony_cd_control_reg;
114 static volatile unsigned short sony_cd_status_reg;
115 static volatile unsigned short sony_cd_result_reg;
116 static volatile unsigned short sony_cd_read_reg;
117 static volatile unsigned short sony_cd_fifost_reg;
118
119
120 static int initialized = 0;
121 static int sony_disc_changed = 1;
122
123 static int sony_toc_read = 0;
124
125 static int sony_spun_up = 0;
126 static unsigned int sony_buffer_size;
127
128 static unsigned int sony_buffer_sectors;
129
130 static unsigned int sony_usage = 0;
131
132
133 static volatile int sony_first_block = -1;
134
135 static volatile int sony_last_block = -1;
136
137
138 static struct s_sony_toc *sony_toc;
139
140 static struct s_sony_subcode * volatile last_sony_subcode;
141
142 static unsigned char * volatile sony_buffer;
143
144
145 static volatile int sony_inuse = 0;
146
147
148 static struct wait_queue * sony_wait = NULL;
149
150 static struct task_struct *has_cd_task = NULL;
151
152
153
154
155
156
157 static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
158
159
160
161
162
163
164
165
166 unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
167 unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
168
169
170
171
172
173 int
174 check_cdu31a_media_change(int full_dev, int flag)
175 {
176 int retval, target;
177
178
179 target = MINOR(full_dev);
180
181 if (target > 0) {
182 printk("Sony CD-ROM request error: invalid device.\n");
183 return 0;
184 }
185
186 retval = sony_disc_changed;
187 if (!flag)
188 {
189 sony_disc_changed = 0;
190 }
191
192 return retval;
193 }
194
195
196
197
198
199
200 static inline void
201 sony_sleep(void)
202 {
203 current->state = TASK_INTERRUPTIBLE;
204 current->timeout = jiffies;
205 schedule();
206 }
207
208
209
210
211
212
213 static inline int
214 is_attention(void)
215 {
216 return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
217 }
218
219 static inline int
220 is_busy(void)
221 {
222 return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
223 }
224
225 static inline int
226 is_data_ready(void)
227 {
228 return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
229 }
230
231 static inline int
232 is_data_requested(void)
233 {
234 return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
235 }
236
237 static inline int
238 is_result_ready(void)
239 {
240 return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
241 }
242
243 static inline int
244 is_param_write_rdy(void)
245 {
246 return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
247 }
248
249 static inline void
250 reset_drive(void)
251 {
252 outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
253 }
254
255 static inline void
256 clear_attention(void)
257 {
258 outb(SONY_ATTN_CLR_BIT, sony_cd_control_reg);
259 }
260
261 static inline void
262 clear_result_ready(void)
263 {
264 outb(SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
265 }
266
267 static inline void
268 clear_data_ready(void)
269 {
270 outb(SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
271 }
272
273 static inline void
274 clear_param_reg(void)
275 {
276 outb(SONY_PARAM_CLR_BIT, sony_cd_control_reg);
277 }
278
279 static inline unsigned char
280 read_status_register(void)
281 {
282 return(inb(sony_cd_status_reg));
283 }
284
285 static inline unsigned char
286 read_result_register(void)
287 {
288 return(inb(sony_cd_result_reg));
289 }
290
291 static inline unsigned char
292 read_data_register(void)
293 {
294 return(inb(sony_cd_read_reg));
295 }
296
297 static inline void
298 write_param(unsigned char param)
299 {
300 outb(param, sony_cd_param_reg);
301 }
302
303 static inline void
304 write_cmd(unsigned char cmd)
305 {
306 outb(cmd, sony_cd_cmd_reg);
307 outb(SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
308 }
309
310
311
312
313
314
315 static int
316 write_params(unsigned char *params,
317 int num_params)
318 {
319 unsigned int retry_count;
320
321
322 retry_count = SONY_READY_RETRIES;
323 while ((retry_count > 0) && (!is_param_write_rdy()))
324 {
325 retry_count--;
326 }
327 if (!is_param_write_rdy())
328 {
329 return -EIO;
330 }
331
332 while (num_params > 0)
333 {
334 write_param(*params);
335 params++;
336 num_params--;
337 }
338
339 return 0;
340 }
341
342
343
344
345
346
347
348
349 static void
350 get_result(unsigned char *result_buffer,
351 unsigned int *result_size)
352 {
353 unsigned char a, b;
354 int i;
355 unsigned int retry_count;
356
357
358 while (handle_sony_cd_attention())
359 ;
360
361 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
362 while ((retry_count > jiffies) && (is_busy() || (!(is_result_ready()))))
363 {
364 sony_sleep();
365
366 while (handle_sony_cd_attention())
367 ;
368 }
369 if (is_busy() || (!(is_result_ready())))
370 {
371 result_buffer[0] = 0x20;
372 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
373 *result_size = 2;
374 return;
375 }
376
377
378
379
380
381 clear_result_ready();
382 a = read_result_register();
383 *result_buffer = a;
384 result_buffer++;
385 b = read_result_register();
386 *result_buffer = b;
387 result_buffer++;
388 *result_size = 2;
389
390
391
392
393
394
395
396
397
398 if ((a & 0xf0) != 0x20)
399 {
400 if (b > 8)
401 {
402 for (i=0; i<8; i++)
403 {
404 *result_buffer = read_result_register();
405 result_buffer++;
406 (*result_size)++;
407 }
408 b = b - 8;
409
410 while (b > 10)
411 {
412 retry_count = SONY_READY_RETRIES;
413 while ((retry_count > 0) && (!is_result_ready()))
414 {
415 retry_count--;
416 }
417 if (!is_result_ready())
418 {
419 result_buffer[0] = 0x20;
420 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
421 *result_size = 2;
422 return;
423 }
424
425 clear_result_ready();
426
427 for (i=0; i<10; i++)
428 {
429 *result_buffer = read_result_register();
430 result_buffer++;
431 (*result_size)++;
432 }
433 b = b - 10;
434 }
435
436 if (b > 0)
437 {
438 retry_count = SONY_READY_RETRIES;
439 while ((retry_count > 0) && (!is_result_ready()))
440 {
441 retry_count--;
442 }
443 if (!is_result_ready())
444 {
445 result_buffer[0] = 0x20;
446 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
447 *result_size = 2;
448 return;
449 }
450 }
451 }
452
453 while (b > 0)
454 {
455 *result_buffer = read_result_register();
456 result_buffer++;
457 (*result_size)++;
458 b--;
459 }
460 }
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474 static void
475 get_data(unsigned char *data,
476 unsigned char *params,
477
478 unsigned int data_size,
479 unsigned char *result_buffer,
480 unsigned int *result_size)
481 {
482 int i;
483 unsigned int cur_offset;
484 unsigned int retry_count;
485 int result_read;
486 int num_retries;
487
488
489 cli();
490 if (current != has_cd_task)
491 {
492 while (sony_inuse)
493 {
494 interruptible_sleep_on(&sony_wait);
495 if (current->signal & ~current->blocked)
496 {
497 result_buffer[0] = 0x20;
498 result_buffer[1] = SONY_SIGNAL_OP_ERR;
499 *result_size = 2;
500 return;
501 }
502 }
503 }
504 sony_inuse = 1;
505 has_cd_task = current;
506 sti();
507
508 num_retries = 0;
509 retry_data_operation:
510
511
512
513
514
515 while (handle_sony_cd_attention())
516 ;
517
518 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
519 while ((retry_count > jiffies) && (is_busy()))
520 {
521 sony_sleep();
522
523 while (handle_sony_cd_attention())
524 ;
525 }
526 if (is_busy())
527 {
528 result_buffer[0] = 0x20;
529 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
530 *result_size = 2;
531 goto get_data_end;
532 }
533
534
535 clear_result_ready();
536 clear_param_reg();
537
538 write_params(params, 6);
539 write_cmd(SONY_READ_CMD);
540
541
542
543
544
545
546 cur_offset = 0;
547 result_read = 0;
548 while (data_size > 0)
549 {
550
551 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
552 while ((retry_count > jiffies) && (!(is_result_ready() || is_data_ready())))
553 {
554 while (handle_sony_cd_attention())
555 ;
556
557 sony_sleep();
558 }
559 if (!(is_result_ready() || is_data_ready()))
560 {
561 result_buffer[0] = 0x20;
562 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
563 *result_size = 2;
564 goto get_data_end;
565 }
566
567
568 if (is_result_ready())
569 {
570 result_read = 1;
571 get_result(result_buffer, result_size);
572 if ((*result_size < 2) || (result_buffer[0] != 0))
573 {
574 goto get_data_end;
575 }
576 }
577 else
578 {
579
580
581
582
583 clear_data_ready();
584 for (i=0; i<2048; i++)
585 {
586 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
587 while ((retry_count > jiffies) && (!is_data_requested()))
588 {
589 while (handle_sony_cd_attention())
590 ;
591
592 sony_sleep();
593 }
594 if (!is_data_requested())
595 {
596 result_buffer[0] = 0x20;
597 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
598 *result_size = 2;
599 goto get_data_end;
600 }
601
602 *data = read_data_register();
603 data++;
604 data_size--;
605 }
606 cur_offset = cur_offset + 2048;
607 }
608 }
609
610
611 if (!result_read)
612 {
613 get_result(result_buffer, result_size);
614 }
615
616 get_data_end:
617 if ( ((result_buffer[0] & 0x20) == 0x20)
618 && (num_retries < MAX_CDU31A_RETRIES))
619 {
620 num_retries++;
621 goto retry_data_operation;
622 }
623
624 has_cd_task = NULL;
625 sony_inuse = 0;
626 wake_up_interruptible(&sony_wait);
627 }
628
629
630
631
632
633 static void
634 do_sony_cd_cmd(unsigned char cmd,
635 unsigned char *params,
636 unsigned int num_params,
637 unsigned char *result_buffer,
638 unsigned int *result_size)
639 {
640 unsigned int retry_count;
641 int num_retries;
642
643
644 cli();
645 if (current != has_cd_task)
646 {
647 while (sony_inuse)
648 {
649 interruptible_sleep_on(&sony_wait);
650 if (current->signal & ~current->blocked)
651 {
652 result_buffer[0] = 0x20;
653 result_buffer[1] = SONY_SIGNAL_OP_ERR;
654 *result_size = 2;
655 return;
656 }
657 }
658 }
659 sony_inuse = 1;
660 has_cd_task = current;
661 sti();
662
663 num_retries = 0;
664 retry_cd_operation:
665
666 while (handle_sony_cd_attention())
667 ;
668
669 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
670 while ((retry_count > jiffies) && (is_busy()))
671 {
672 sony_sleep();
673
674 while (handle_sony_cd_attention())
675 ;
676 }
677 if (is_busy())
678 {
679 result_buffer[0] = 0x20;
680 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
681 *result_size = 2;
682 goto do_cmd_end;
683 }
684
685 clear_result_ready();
686 clear_param_reg();
687
688 write_params(params, num_params);
689 write_cmd(cmd);
690
691 get_result(result_buffer, result_size);
692
693 do_cmd_end:
694 if ( ((result_buffer[0] & 0x20) == 0x20)
695 && (num_retries < MAX_CDU31A_RETRIES))
696 {
697 num_retries++;
698 goto retry_cd_operation;
699 }
700
701 has_cd_task = NULL;
702 sony_inuse = 0;
703 wake_up_interruptible(&sony_wait);
704 }
705
706
707
708
709
710
711 static int
712 handle_sony_cd_attention(void)
713 {
714 unsigned char atten_code;
715 unsigned char res_reg[2];
716 unsigned int res_size;
717
718
719 if (is_attention())
720 {
721 clear_attention();
722 atten_code = read_result_register();
723
724 switch (atten_code)
725 {
726
727 case SONY_MECH_LOADED_ATTN:
728 sony_disc_changed = 1;
729 sony_toc_read = 0;
730 sony_audio_status = CDROM_AUDIO_NO_STATUS;
731 sony_first_block = -1;
732 sony_last_block = -1;
733 if (initialized)
734 {
735 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
736 sony_get_toc();
737 }
738 break;
739
740 case SONY_AUDIO_PLAY_DONE_ATTN:
741 sony_audio_status = CDROM_AUDIO_COMPLETED;
742 read_subcode();
743 break;
744
745 case SONY_EJECT_PUSHED_ATTN:
746 sony_audio_status = CDROM_AUDIO_INVALID;
747 break;
748
749 case SONY_LEAD_IN_ERR_ATTN:
750 case SONY_LEAD_OUT_ERR_ATTN:
751 case SONY_DATA_TRACK_ERR_ATTN:
752 case SONY_AUDIO_PLAYBACK_ERR_ATTN:
753 sony_audio_status = CDROM_AUDIO_ERROR;
754 break;
755 }
756 return(1);
757 }
758
759 return(0);
760 }
761
762
763
764 static inline unsigned int
765 int_to_bcd(unsigned int val)
766 {
767 int retval;
768
769
770 retval = (val / 10) << 4;
771 retval = retval | val % 10;
772 return(retval);
773 }
774
775
776
777 static unsigned int
778 bcd_to_int(unsigned int bcd)
779 {
780 return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
781 }
782
783
784
785
786
787
788 static void
789 log_to_msf(unsigned int log, unsigned char *msf)
790 {
791 log = log + LOG_START_OFFSET;
792 msf[0] = int_to_bcd(log / 4500);
793 log = log % 4500;
794 msf[1] = int_to_bcd(log / 75);
795 msf[2] = int_to_bcd(log % 75);
796 }
797
798
799
800
801
802 static unsigned int
803 msf_to_log(unsigned char *msf)
804 {
805 unsigned int log;
806
807
808 log = bcd_to_int(msf[2]);
809 log += bcd_to_int(msf[1]) * 75;
810 log += bcd_to_int(msf[0]) * 4500;
811 log = log - LOG_START_OFFSET;
812
813 return log;
814 }
815
816
817
818
819
820
821 static void
822 size_to_buf(unsigned int size,
823 unsigned char *buf)
824 {
825 buf[0] = size / 65536;
826 size = size % 65536;
827 buf[1] = size / 256;
828 buf[2] = size % 256;
829 }
830
831
832
833
834
835
836
837
838
839 static void
840 do_cdu31a_request(void)
841 {
842 int block;
843 unsigned int dev;
844 int nsect;
845 unsigned char params[10];
846 unsigned char res_reg[2];
847 unsigned int res_size;
848 int copyoff;
849 int spin_up_retry;
850 unsigned int read_size;
851
852
853 if (!sony_spun_up)
854 {
855 scd_open (NULL,NULL);
856 }
857
858 while (1)
859 {
860
861
862
863
864 if (!(CURRENT) || CURRENT->dev < 0)
865 {
866 return;
867 }
868
869 INIT_REQUEST;
870 dev = MINOR(CURRENT->dev);
871 block = CURRENT->sector;
872 nsect = CURRENT->nr_sectors;
873 if (dev != 0)
874 {
875 end_request(0);
876 continue;
877 }
878
879 switch(CURRENT->cmd)
880 {
881 case READ:
882
883
884
885
886 if ((block / 4) >= sony_toc->lead_out_start_lba)
887 {
888 end_request(0);
889 return;
890 }
891 if (((block + nsect) / 4) >= sony_toc->lead_out_start_lba)
892 {
893 end_request(0);
894 return;
895 }
896
897 while (nsect > 0)
898 {
899
900
901
902
903 if ((block < sony_first_block) || (block > sony_last_block))
904 {
905 sony_first_block = (block / 4) * 4;
906 log_to_msf(block/4, params);
907
908
909
910
911
912 if (((block / 4) + sony_buffer_sectors) >= sony_toc->lead_out_start_lba)
913 {
914 sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
915 read_size = sony_toc->lead_out_start_lba - (block / 4);
916 }
917 else
918 {
919 sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
920 read_size = sony_buffer_sectors;
921 }
922 size_to_buf(read_size, ¶ms[3]);
923
924
925
926
927
928 spin_up_retry = 0;
929 try_read_again:
930 get_data(sony_buffer, params, (read_size * 2048), res_reg, &res_size);
931 if ((res_size < 2) || (res_reg[0] != 0))
932 {
933 if ((res_reg[1] == SONY_NOT_SPIN_ERR) && (!spin_up_retry))
934 {
935 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
936 spin_up_retry = 1;
937 goto try_read_again;
938 }
939
940 printk("Sony CDROM Read error: 0x%2.2x\n", res_reg[1]);
941 sony_first_block = -1;
942 sony_last_block = -1;
943 end_request(0);
944 return;
945 }
946 }
947
948
949
950
951
952 copyoff = (block - sony_first_block) * 512;
953 memcpy(CURRENT->buffer, sony_buffer+copyoff, 512);
954
955 block += 1;
956 nsect -= 1;
957 CURRENT->buffer += 512;
958 }
959
960 end_request(1);
961 break;
962
963 case WRITE:
964 end_request(0);
965 break;
966
967 default:
968 panic("Unkown SONY CD cmd");
969 }
970 }
971 }
972
973
974
975
976
977
978 static void
979 sony_get_toc(void)
980 {
981 unsigned int res_size;
982
983
984 if (!sony_toc_read)
985 {
986 do_sony_cd_cmd(SONY_REQ_TOC_DATA_CMD,
987 NULL,
988 0,
989 (unsigned char *) sony_toc,
990 &res_size);
991 if ((res_size < 2) || ((sony_toc->exec_status[0] & 0x20) == 0x20))
992 {
993 return;
994 }
995 sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
996 sony_toc_read = 1;
997 }
998 }
999
1000
1001
1002
1003
1004 static int
1005 find_track(int track)
1006 {
1007 int i;
1008 int num_tracks;
1009
1010
1011 num_tracks = sony_toc->last_track_num + sony_toc->first_track_num + 1;
1012 for (i = 0; i < num_tracks; i++)
1013 {
1014 if (sony_toc->tracks[i].track == track)
1015 {
1016 return i;
1017 }
1018 }
1019
1020 return -1;
1021 }
1022
1023
1024
1025
1026
1027 static int
1028 read_subcode(void)
1029 {
1030 unsigned int res_size;
1031
1032
1033 do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
1034 NULL,
1035 0,
1036 (unsigned char *) last_sony_subcode,
1037 &res_size);
1038 if ((res_size < 2) || ((last_sony_subcode->exec_status[0] & 0x20) == 0x20))
1039 {
1040 printk("Sony CDROM error 0x%2.2x (read_subcode)\n",
1041 last_sony_subcode->exec_status[1]);
1042 return -EIO;
1043 }
1044
1045 return 0;
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 static int
1057 sony_get_subchnl_info(long arg)
1058 {
1059 struct cdrom_subchnl schi;
1060
1061
1062
1063 while (handle_sony_cd_attention())
1064 ;
1065
1066 sony_get_toc();
1067 if (!sony_toc_read)
1068 {
1069 return -EIO;
1070 }
1071
1072 verify_area(VERIFY_READ, (char *) arg, sizeof(schi));
1073 verify_area(VERIFY_WRITE, (char *) arg, sizeof(schi));
1074
1075 memcpy_fromfs(&schi, (char *) arg, sizeof(schi));
1076
1077 switch (sony_audio_status)
1078 {
1079 case CDROM_AUDIO_PLAY:
1080 if (read_subcode() < 0)
1081 {
1082 return -EIO;
1083 }
1084 break;
1085
1086 case CDROM_AUDIO_PAUSED:
1087 case CDROM_AUDIO_COMPLETED:
1088 break;
1089
1090 case CDROM_AUDIO_NO_STATUS:
1091 schi.cdsc_audiostatus = sony_audio_status;
1092 memcpy_tofs((char *) arg, &schi, sizeof(schi));
1093 return 0;
1094 break;
1095
1096 case CDROM_AUDIO_INVALID:
1097 case CDROM_AUDIO_ERROR:
1098 default:
1099 return -EIO;
1100 }
1101
1102 schi.cdsc_audiostatus = sony_audio_status;
1103 schi.cdsc_adr = last_sony_subcode->address;
1104 schi.cdsc_ctrl = last_sony_subcode->control;
1105 schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
1106 schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
1107 if (schi.cdsc_format == CDROM_MSF)
1108 {
1109 schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
1110 schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
1111 schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
1112
1113 schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
1114 schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
1115 schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
1116 }
1117 else if (schi.cdsc_format == CDROM_LBA)
1118 {
1119 schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
1120 schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
1121 }
1122
1123 memcpy_tofs((char *) arg, &schi, sizeof(schi));
1124 return 0;
1125 }
1126
1127
1128
1129
1130
1131 static int
1132 scd_ioctl(struct inode *inode,
1133 struct file *file,
1134 unsigned int cmd,
1135 unsigned int arg)
1136 {
1137 unsigned int dev;
1138 unsigned char res_reg[2];
1139 unsigned int res_size;
1140 unsigned char params[7];
1141 int i;
1142
1143
1144 if (!inode)
1145 {
1146 return -EINVAL;
1147 }
1148 dev = MINOR(inode->i_rdev) >> 6;
1149 if (dev != 0)
1150 {
1151 return -EINVAL;
1152 }
1153
1154 switch (cmd)
1155 {
1156 case CDROMSTART:
1157 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1158 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1159 {
1160 printk("Sony CDROM error 0x%2.2x (CDROMSTART)\n", res_reg[1]);
1161 return -EIO;
1162 }
1163 return 0;
1164 break;
1165
1166 case CDROMSTOP:
1167 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1168
1169
1170
1171
1172
1173 sony_audio_status = CDROM_AUDIO_NO_STATUS;
1174 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1175 if ( ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1176 && (res_reg[1] != SONY_NOT_SPIN_ERR))
1177 {
1178 printk("Sony CDROM error 0x%2.2x (CDROMSTOP)\n", res_reg[1]);
1179 return -EIO;
1180 }
1181
1182 return 0;
1183 break;
1184
1185 case CDROMPAUSE:
1186 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1187 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1188 {
1189 printk("Sony CDROM error 0x%2.2x (CDROMPAUSE)\n", res_reg[1]);
1190 return -EIO;
1191 }
1192
1193
1194 if (read_subcode() < 0)
1195 {
1196 return -EIO;
1197 }
1198 cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1199 cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1200 cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1201 sony_audio_status = CDROM_AUDIO_PAUSED;
1202 return 0;
1203 break;
1204
1205 case CDROMRESUME:
1206 if (sony_audio_status != CDROM_AUDIO_PAUSED)
1207 {
1208 return -EINVAL;
1209 }
1210
1211 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1212
1213
1214 params[1] = cur_pos_msf[0];
1215 params[2] = cur_pos_msf[1];
1216 params[3] = cur_pos_msf[2];
1217 params[4] = final_pos_msf[0];
1218 params[5] = final_pos_msf[1];
1219 params[6] = final_pos_msf[2];
1220 params[0] = 0x03;
1221 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1222 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1223 {
1224 printk("Sony CDROM error 0x%2.2x (CDROMRESUME)\n", res_reg[1]);
1225 return -EIO;
1226 }
1227 sony_audio_status = CDROM_AUDIO_PLAY;
1228 return 0;
1229 break;
1230
1231 case CDROMPLAYMSF:
1232 verify_area(VERIFY_READ, (char *) arg, 6);
1233 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1234 memcpy_fromfs(&(params[1]), (void *) arg, 6);
1235
1236
1237 for (i=1; i<7; i++)
1238 {
1239 params[i] = int_to_bcd(params[i]);
1240 }
1241 params[0] = 0x03;
1242 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1243 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1244 {
1245 printk("Sony CDROM error 0x%2.2x (CDROMPLAYMSF)\n", res_reg[1]);
1246 return -EIO;
1247 }
1248
1249
1250 final_pos_msf[0] = params[4];
1251 final_pos_msf[1] = params[5];
1252 final_pos_msf[2] = params[6];
1253 sony_audio_status = CDROM_AUDIO_PLAY;
1254 return 0;
1255 break;
1256
1257 case CDROMREADTOCHDR:
1258 {
1259 struct cdrom_tochdr *hdr;
1260 struct cdrom_tochdr loc_hdr;
1261
1262 sony_get_toc();
1263 if (!sony_toc_read)
1264 {
1265 return -EIO;
1266 }
1267
1268 hdr = (struct cdrom_tochdr *) arg;
1269 verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
1270 loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1271 loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1272 memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
1273 }
1274 return 0;
1275 break;
1276
1277 case CDROMREADTOCENTRY:
1278 {
1279 struct cdrom_tocentry *entry;
1280 struct cdrom_tocentry loc_entry;
1281 int track_idx;
1282 unsigned char *msf_val = NULL;
1283
1284 sony_get_toc();
1285 if (!sony_toc_read)
1286 {
1287 return -EIO;
1288 }
1289
1290 entry = (struct cdrom_tocentry *) arg;
1291 verify_area(VERIFY_READ, entry, sizeof(*entry));
1292 verify_area(VERIFY_WRITE, entry, sizeof(*entry));
1293
1294 memcpy_fromfs(&loc_entry, entry, sizeof(loc_entry));
1295
1296
1297 if (loc_entry.cdte_track == CDROM_LEADOUT)
1298 {
1299 loc_entry.cdte_adr = sony_toc->address2;
1300 loc_entry.cdte_ctrl = sony_toc->control2;
1301 msf_val = sony_toc->lead_out_start_msf;
1302 }
1303 else
1304 {
1305 track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1306 if (track_idx < 0)
1307 {
1308 return -EINVAL;
1309 }
1310
1311 loc_entry.cdte_adr = sony_toc->tracks[track_idx].address;
1312 loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1313 msf_val = sony_toc->tracks[track_idx].track_start_msf;
1314 }
1315
1316
1317 if (loc_entry.cdte_format == CDROM_LBA)
1318 {
1319 loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1320 }
1321 else if (loc_entry.cdte_format == CDROM_MSF)
1322 {
1323 loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1324 loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val+1));
1325 loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val+2));
1326 }
1327 memcpy_tofs(entry, &loc_entry, sizeof(*entry));
1328 }
1329 return 0;
1330 break;
1331
1332 case CDROMPLAYTRKIND:
1333 {
1334 struct cdrom_ti ti;
1335 int track_idx;
1336
1337 sony_get_toc();
1338 if (!sony_toc_read)
1339 {
1340 return -EIO;
1341 }
1342
1343 verify_area(VERIFY_READ, (char *) arg, sizeof(ti));
1344
1345 memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
1346 if ( (ti.cdti_trk0 < sony_toc->first_track_num)
1347 || (ti.cdti_trk0 > sony_toc->last_track_num)
1348 || (ti.cdti_trk1 < ti.cdti_trk0))
1349 {
1350 return -EINVAL;
1351 }
1352
1353 track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1354 if (track_idx < 0)
1355 {
1356 return -EINVAL;
1357 }
1358 params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1359 params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1360 params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1361
1362
1363
1364
1365
1366 if (ti.cdti_trk1 >= bcd_to_int(sony_toc->last_track_num))
1367 {
1368 log_to_msf(msf_to_log(sony_toc->lead_out_start_msf)-1,
1369 &(params[4]));
1370 }
1371 else
1372 {
1373 track_idx = find_track(int_to_bcd(ti.cdti_trk1+1));
1374 if (track_idx < 0)
1375 {
1376 return -EINVAL;
1377 }
1378 log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf)-1,
1379 &(params[4]));
1380 }
1381 params[0] = 0x03;
1382
1383 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1384
1385 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1386 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1387 {
1388 printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
1389 params[2], params[3], params[4], params[5], params[6]);
1390 printk("Sony CDROM error 0x%2.2x (CDROMPLAYTRKIND\n", res_reg[1]);
1391 return -EIO;
1392 }
1393
1394
1395 final_pos_msf[0] = params[4];
1396 final_pos_msf[1] = params[5];
1397 final_pos_msf[2] = params[6];
1398 sony_audio_status = CDROM_AUDIO_PLAY;
1399 return 0;
1400 }
1401
1402 case CDROMSUBCHNL:
1403 return sony_get_subchnl_info(arg);
1404
1405 case CDROMVOLCTRL:
1406 {
1407 struct cdrom_volctrl volctrl;
1408
1409 verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
1410
1411 memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
1412 params[0] = SONY_SD_AUDIO_VOLUME;
1413 params[1] = volctrl.channel0;
1414 params[2] = volctrl.channel1;
1415 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
1416 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1417 {
1418 printk("Sony CDROM error 0x%2.2x (CDROMVOLCTRL)\n", res_reg[1]);
1419 return -EIO;
1420 }
1421 }
1422 return 0;
1423
1424 case CDROMEJECT:
1425 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1426 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1427
1428 sony_audio_status = CDROM_AUDIO_INVALID;
1429 do_sony_cd_cmd(SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
1430 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1431 {
1432 printk("Sony CDROM error 0x%2.2x (CDROMEJECT)\n", res_reg[1]);
1433 return -EIO;
1434 }
1435 return 0;
1436 break;
1437
1438 default:
1439 return -EINVAL;
1440 }
1441 }
1442
1443
1444
1445
1446
1447
1448 static int
1449 scd_open(struct inode *inode,
1450 struct file *filp)
1451 {
1452 unsigned char res_reg[2];
1453 unsigned int res_size;
1454
1455
1456 if (!sony_spun_up)
1457 {
1458 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1459
1460
1461
1462 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1463 {
1464 printk("Sony CDROM error 0x%2.2x (scd_open, spin up)\n", res_reg[1]);
1465 return -EIO;
1466 }
1467
1468 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
1469
1470
1471
1472 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1473 {
1474
1475 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
1476 {
1477 goto drive_spinning;
1478 }
1479
1480 printk("Sony CDROM error 0x%2.2x (scd_open, read toc)\n", res_reg[1]);
1481 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1482
1483 return -EIO;
1484 }
1485
1486 sony_get_toc();
1487 if (!sony_toc_read)
1488 {
1489 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1490 return -EIO;
1491 }
1492
1493 sony_spun_up = 1;
1494 }
1495
1496 drive_spinning:
1497
1498 if (inode)
1499 {
1500 check_disk_change(inode->i_rdev);
1501 }
1502
1503 sony_usage++;
1504
1505 return 0;
1506 }
1507
1508
1509
1510
1511
1512
1513 static void
1514 scd_release(struct inode *inode,
1515 struct file *filp)
1516 {
1517 unsigned char res_reg[2];
1518 unsigned int res_size;
1519
1520
1521 if (sony_usage > 0)
1522 {
1523 sony_usage--;
1524 }
1525 if (sony_usage == 0)
1526 {
1527 sync_dev(inode->i_rdev);
1528 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1529
1530 sony_spun_up = 0;
1531 }
1532 }
1533
1534
1535 static struct file_operations scd_fops = {
1536 NULL,
1537 block_read,
1538 block_write,
1539 NULL,
1540 NULL,
1541 scd_ioctl,
1542 NULL,
1543 scd_open,
1544 scd_release
1545 };
1546
1547
1548
1549 static char *load_mech[] = { "caddy", "tray", "pop-up", "unknown" };
1550
1551
1552
1553 static unsigned int mem_size[] = { 4096, 8192, 16384, 2048 };
1554
1555 void
1556 get_drive_configuration(unsigned short base_io,
1557 unsigned char res_reg[],
1558 unsigned int *res_size)
1559 {
1560 int retry_count;
1561
1562
1563
1564 sony_cd_base_io = base_io;
1565
1566
1567 sony_cd_cmd_reg = sony_cd_base_io + SONY_CMD_REG_OFFSET;
1568 sony_cd_param_reg = sony_cd_base_io + SONY_PARAM_REG_OFFSET;
1569 sony_cd_write_reg = sony_cd_base_io + SONY_WRITE_REG_OFFSET;
1570 sony_cd_control_reg = sony_cd_base_io + SONY_CONTROL_REG_OFFSET;
1571 sony_cd_status_reg = sony_cd_base_io + SONY_STATUS_REG_OFFSET;
1572 sony_cd_result_reg = sony_cd_base_io + SONY_RESULT_REG_OFFSET;
1573 sony_cd_read_reg = sony_cd_base_io + SONY_READ_REG_OFFSET;
1574 sony_cd_fifost_reg = sony_cd_base_io + SONY_FIFOST_REG_OFFSET;
1575
1576
1577
1578
1579
1580
1581 if (read_status_register() != 0xff)
1582 {
1583
1584
1585
1586
1587 reset_drive();
1588 retry_count = jiffies + SONY_RESET_TIMEOUT;
1589 while ((retry_count > jiffies) && (!is_attention()))
1590 {
1591 sony_sleep();
1592 }
1593
1594
1595 if (!is_attention())
1596 {
1597 res_reg[0] = 0x20;
1598 return;
1599 }
1600
1601
1602
1603
1604 do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
1605 NULL,
1606 0,
1607 (unsigned char *) res_reg,
1608 res_size);
1609 return;
1610 }
1611
1612
1613 res_reg[0] = 0x20;
1614 }
1615
1616
1617
1618
1619
1620 unsigned long
1621 cdu31a_init(unsigned long mem_start, unsigned long mem_end)
1622 {
1623 struct s_sony_drive_config drive_config;
1624 unsigned char params[3];
1625 unsigned char res_reg[2];
1626 unsigned int res_size;
1627 int i;
1628 int drive_found;
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638 outb(0xbc, 0x9a01);
1639 outb(0xe2, 0x9a01);
1640
1641 i = 0;
1642 drive_found = 0;
1643 while ( (cdu31a_addresses[i] != 0)
1644 && (!drive_found))
1645 {
1646 get_drive_configuration(cdu31a_addresses[i],
1647 drive_config.exec_status,
1648 &res_size);
1649 if ((res_size > 2) && ((drive_config.exec_status[0] & 0x20) == 0x00))
1650 {
1651 drive_found = 1;
1652
1653 if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
1654 {
1655 printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
1656 return mem_start;
1657 }
1658
1659 sony_buffer_size = mem_size[SONY_HWC_GET_BUF_MEM_SIZE(drive_config)];
1660 sony_buffer_sectors = sony_buffer_size / 2048;
1661
1662 printk("Sony I/F CDROM : %8.8s %16.16s %8.8s with %s load mechanism\n",
1663 drive_config.vendor_id,
1664 drive_config.product_id,
1665 drive_config.product_rev_level,
1666 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
1667 printk(" using %d byte buffer", sony_buffer_size);
1668 if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
1669 {
1670 printk(", capable of audio playback");
1671 }
1672 printk("\n");
1673
1674 params[0] = SONY_SD_MECH_CONTROL;
1675 params[1] = 0x03;
1676 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
1677 params,
1678 2,
1679 res_reg,
1680 &res_size);
1681 if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1682 {
1683 printk(" Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
1684 }
1685
1686 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1687 read_ahead[MAJOR_NR] = 8;
1688
1689 sony_toc = (struct s_sony_toc *) mem_start;
1690 mem_start += sizeof(*sony_toc);
1691 last_sony_subcode = (struct s_sony_subcode *) mem_start;
1692 mem_start += sizeof(*last_sony_subcode);
1693 sony_buffer = (unsigned char *) mem_start;
1694 mem_start += sony_buffer_size;
1695
1696 initialized = 1;
1697 }
1698
1699 i++;
1700 }
1701
1702 return mem_start;
1703 }
1704
1705 #endif