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