This source file includes following definitions.
- cdu535_check_media_change
- sony_sleep
- select_unit
- read_result_reg
- read_exec_status
- check_drive_status
- do_sony_cmd
- set_drive_mode
- seek_and_read_N_blocks
- request_toc_data
- spin_up_drive
- int_to_bcd
- bcd_to_int
- log_to_msf
- msf_to_log
- size_to_buf
- do_cdu535_request
- sony_get_toc
- find_track
- read_subcode
- sony_get_subchnl_info
- cdu_ioctl
- cdu_open
- cdu_release
- sony535_init
- sonycd535_setup
- cleanup_module
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
83
84
85
86
87
88
89
90
91
92
93
94
95 #include <linux/config.h>
96 #if defined(CONFIG_CDU535) || defined(MODULE)
97
98 #ifdef MODULE
99 # include <linux/module.h>
100 # include <linux/malloc.h>
101 # include <linux/version.h>
102 #endif
103
104 #include <linux/errno.h>
105 #include <linux/signal.h>
106 #include <linux/sched.h>
107 #include <linux/timer.h>
108 #include <linux/fs.h>
109 #include <linux/kernel.h>
110 #include <linux/ioport.h>
111 #include <linux/hdreg.h>
112 #include <linux/genhd.h>
113 #include <linux/mm.h>
114
115 #define REALLY_SLOW_IO
116 #include <asm/system.h>
117 #include <asm/io.h>
118 #include <asm/segment.h>
119
120 #include <linux/cdrom.h>
121 #include <linux/sonycd535.h>
122
123 #define MAJOR_NR CDU535_CDROM_MAJOR
124
125 #ifdef MODULE
126 # include "/usr/src/linux/drivers/block/blk.h"
127 #else
128 # include "blk.h"
129 # define MOD_INC_USE_COUNT
130 # define MOD_DEC_USE_COUNT
131 #endif
132
133
134
135
136
137
138
139 #ifndef CDU535_ADDRESS
140 # define CDU535_ADDRESS (0x340)
141 #endif
142
143 #ifndef CDU535_HANDLE
144 # define CDU535_HANDLE "cdu535"
145 #endif
146 #ifndef CDU535_MESSAGE_NAME
147 # define CDU535_MESSAGE_NAME "Sony CDU-535"
148 #endif
149
150 #ifndef DEBUG
151 # define DEBUG 1
152 #endif
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 #define SONY535_BUFFER_SIZE (64*1024)
169
170
171
172
173
174 #define LOCK_DOORS
175
176 static int read_subcode(void);
177 static void sony_get_toc(void);
178 static int cdu_open(struct inode *inode, struct file *filp);
179 static inline unsigned int int_to_bcd(unsigned int val);
180 static unsigned int bcd_to_int(unsigned int bcd);
181 static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
182 Byte * response, int nResponse, int ignoreStatusBit7);
183
184
185
186 static unsigned short sony_cd_base_io = CDU535_ADDRESS;
187
188
189
190
191
192 static unsigned short select_unit_reg;
193 static unsigned short result_reg;
194 static unsigned short command_reg;
195 static unsigned short read_status_reg;
196 static unsigned short data_reg;
197
198 static int initialized = 0;
199 static int sony_disc_changed = 1;
200
201 static int sony_toc_read = 0;
202
203 static unsigned int sony_buffer_size;
204
205 static unsigned int sony_buffer_sectors;
206
207 static unsigned int sony_usage = 0;
208
209
210 static int sony_first_block = -1;
211
212 static int sony_last_block = -1;
213
214
215 static struct s535_sony_toc *sony_toc;
216
217 static struct s535_sony_subcode *last_sony_subcode;
218
219 #ifndef MODULE
220 static unsigned char *sony_buffer;
221 #else
222 static unsigned char **sony_buffer;
223
224 #endif
225 static int sony_inuse = 0;
226
227
228
229
230
231
232 static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
233
234
235
236
237
238
239
240
241
242
243 static unsigned char cur_pos_msf[3] = {0, 0, 0};
244 static unsigned char final_pos_msf[3] = {0, 0, 0};
245
246
247
248
249
250
251 static int
252 cdu535_check_media_change(dev_t full_dev)
253 {
254 int retval;
255
256 if (MINOR(full_dev) != 0) {
257 printk("Sony CD-ROM request error: invalid device.\n");
258 return 0;
259 }
260
261
262 retval = initialized ? sony_disc_changed : 0;
263 sony_disc_changed = 0;
264 return retval;
265 }
266
267
268
269
270
271
272
273 static inline void
274 sony_sleep(void)
275 {
276 current->state = TASK_INTERRUPTIBLE;
277 current->timeout = jiffies;
278 schedule();
279 }
280
281
282
283
284
285
286
287
288 static void
289 select_unit(int unit_no)
290 {
291 unsigned int select_mask = ~(1 << unit_no);
292 outb(select_mask, select_unit_reg);
293 }
294
295
296
297
298
299
300
301
302 static int
303 read_result_reg(unsigned char *data_ptr)
304 {
305 int retry_count;
306 int read_status;
307
308 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
309 while (jiffies < retry_count) {
310 if (((read_status = inb(read_status_reg)) & SONY535_RESULT_NOT_READY_BIT) == 0) {
311 #if DEBUG > 1
312 printk("read_result_reg(): readStatReg = 0x%x\n", read_status);
313 #endif
314 *data_ptr = inb(result_reg);
315 return 0;
316 } else {
317 sony_sleep();
318 }
319 }
320 printk(" Sony CDROM read_result_reg: TIME OUT!\n");
321 return TIME_OUT;
322 }
323
324
325
326
327
328
329
330
331 static int
332 read_exec_status(Byte status[2])
333 {
334 status[1] = 0;
335 if (read_result_reg(&(status[0])) != 0)
336 return TIME_OUT;
337 if ((status[0] & 0x80) != 0) {
338 if (read_result_reg(&(status[1])) != 0)
339 return TIME_OUT;
340 }
341 #if DEBUG > 1
342 printk("read_exec_status: read 0x%x\n", status[0]);
343 if (status[0] & 0x80)
344 printk(" and 0x%x\n", status[1]);
345 printk("\n");
346 #endif
347 return 0;
348 }
349
350
351
352
353
354
355
356
357 static int
358 check_drive_status(void)
359 {
360 Byte status, e_status[2];
361 int CDD, ATN;
362 unsigned char cmd;
363
364 select_unit(0);
365 if (sony_audio_status == CDROM_AUDIO_PLAY) {
366 outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
367 if (read_result_reg(&status) == 0) {
368 switch (status) {
369 case 0x0:
370 break;
371 case 0x1:
372 break;
373 case 0x3:
374 case 0x5:
375 sony_audio_status = CDROM_AUDIO_COMPLETED;
376 read_subcode();
377 break;
378 case 0x4:
379 sony_audio_status = CDROM_AUDIO_ERROR;
380 break;
381 }
382 }
383 }
384
385 outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
386 if (read_result_reg(&status) != 0)
387 return TIME_OUT;
388
389 #if DEBUG > 1
390 printk("--check_drive_status() got 0x%x\n", status);
391 #endif
392
393 if (status == 0)
394 return 0;
395
396 ATN = status & 0xf;
397 CDD = (status >> 4) & 0xf;
398
399 switch (ATN) {
400 case 0x0:
401 break;
402 case SONY535_ATN_BUSY:
403 if (initialized)
404 printk("Sony CDROM error, drive busy\n");
405 return CD_BUSY;
406 case SONY535_ATN_EJECT_IN_PROGRESS:
407 printk("Sony CDROM error, eject in progress\n");
408 sony_audio_status = CDROM_AUDIO_INVALID;
409 return CD_BUSY;
410 case SONY535_ATN_RESET_OCCURRED:
411 case SONY535_ATN_DISC_CHANGED:
412 case SONY535_ATN_RESET_AND_DISC_CHANGED:
413 #if DEBUG > 0
414 printk("Sony CDROM, reset occurred or disc changed\n");
415 #endif
416 sony_disc_changed = 1;
417 sony_toc_read = 0;
418 sony_audio_status = CDROM_AUDIO_NO_STATUS;
419 sony_first_block = -1;
420 sony_last_block = -1;
421 if (initialized) {
422 cmd = SONY535_SPIN_UP;
423 do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
424 sony_get_toc();
425 }
426 return 0;
427 default:
428 printk("Sony CDROM error, drive busy (ATN=0x%x)\n", ATN);
429 return CD_BUSY;
430 }
431 switch (CDD) {
432 case 0x0:
433 case 0x2:
434 case 0xa:
435 break;
436 case 0xc:
437 printk("check_drive_status(): CDD = 0xc! Not properly handled!\n");
438 return CD_BUSY;
439 default:
440 return CD_BUSY;
441 }
442 return 0;
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 static int
462 do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
463 Byte * response, int n_response, int ignore_status_bit7)
464 {
465 int i;
466
467
468 for (i = 0; i < n_cmd; i++)
469 outb(cmd[i], command_reg);
470
471
472 if (read_result_reg(status) != 0)
473 return TIME_OUT;
474 if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
475
476 if (read_result_reg(status + 1) != 0)
477 return TIME_OUT;
478 } else {
479 status[1] = 0;
480 }
481 #if DEBUG > 2
482 printk("do_sony_cmd %x: %x %x\n", *cmd, status[0], status[1]);
483 #endif
484
485
486 if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
487 return 0;
488
489
490 for (i = 0; 0 < n_response; n_response--, i++)
491 if (read_result_reg(response + i) != 0)
492 return TIME_OUT;
493 return 0;
494 }
495
496
497
498
499
500
501
502 static int
503 set_drive_mode(int mode, Byte status[2])
504 {
505 Byte cmd_buff[2], ret_buff[1];
506
507 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
508 cmd_buff[1] = mode;
509 return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
510 }
511
512
513
514
515
516
517
518
519
520
521
522
523
524 static int
525 #ifndef MODULE
526 seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
527 Byte * data_buff, int buf_size)
528 #else
529 seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
530 unsigned char **buff, int buf_size)
531 #endif
532 {
533 int i;
534 const int block_size = 2048;
535 Byte cmd_buff[7];
536 int read_status;
537 int retry_count;
538 #ifdef MODULE
539 Byte *data_buff;
540 int sector_count = 0;
541 #else
542 Byte *start_pos = data_buff;
543 #endif
544
545 if (buf_size < ((long)block_size) * n_blocks)
546 return NO_ROOM;
547
548 set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
549
550
551 cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
552 for (i = 0; i < 6; i++)
553 cmd_buff[i + 1] = params[i];
554 for (i = 0; i < 7; i++)
555 outb(cmd_buff[i], command_reg);
556
557
558 while (0 < n_blocks--) {
559
560 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
561 while (jiffies < retry_count) {
562 read_status = inb(read_status_reg);
563 if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
564 read_exec_status(status);
565 return BAD_STATUS;
566 }
567 if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
568
569 #ifdef MODULE
570 data_buff = buff[sector_count++];
571 #endif
572 for (i = 0; i < block_size; i++)
573 *data_buff++ = inb(data_reg);
574 break;
575 }
576 sony_sleep();
577 }
578 if (retry_count <= jiffies)
579 return TIME_OUT;
580 }
581
582
583 if ((i = read_exec_status(status)) != 0)
584 return i;
585 #ifndef MODULE
586 return data_buff - start_pos;
587 #else
588 return block_size * sector_count;
589 #endif
590 }
591
592
593
594
595
596
597
598 static int
599 request_toc_data(Byte status[2], struct s535_sony_toc *toc)
600 {
601 int to_status;
602 int i, j, n_tracks, track_no;
603 Byte cmd_no = 0xb2;
604 Byte track_address_buffer[5];
605 int first_track_num, last_track_num;
606
607
608 if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
609 return to_status;
610
611
612 first_track_num = bcd_to_int(toc->first_track_num);
613 last_track_num = bcd_to_int(toc->last_track_num);
614 n_tracks = last_track_num - first_track_num + 1;
615
616
617 for (i = 0; i < n_tracks; i++) {
618
619 for (j = 0; j < 5; j++) {
620 if (read_result_reg(track_address_buffer + j) != 0)
621 return TIME_OUT;
622 if (j == 1)
623 track_no = bcd_to_int(track_address_buffer[j]);
624 }
625
626 memcpy(toc->tracks + i, track_address_buffer, 5);
627 }
628 return 0;
629 }
630
631
632
633
634
635
636 static int
637 spin_up_drive(Byte status[2])
638 {
639 Byte cmd_buff[1];
640
641
642 cmd_buff[0] = SONY535_REQUEST_DRIVE_STATUS_1;
643 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0)
644 return TIME_OUT;
645 if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
646 return 0;
647
648
649 cmd_buff[0] = SONY535_SPIN_UP;
650 return do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
651 }
652
653
654
655
656 static inline unsigned int
657 int_to_bcd(unsigned int val)
658 {
659 int retval;
660
661
662 retval = (val / 10) << 4;
663 retval = retval | val % 10;
664 return retval;
665 }
666
667
668
669 static unsigned int
670 bcd_to_int(unsigned int bcd)
671 {
672 return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
673 }
674
675
676
677
678
679
680 static void
681 log_to_msf(unsigned int log, unsigned char *msf)
682 {
683 log = log + LOG_START_OFFSET;
684 msf[0] = int_to_bcd(log / 4500);
685 log = log % 4500;
686 msf[1] = int_to_bcd(log / 75);
687 msf[2] = int_to_bcd(log % 75);
688 }
689
690
691
692
693
694 static unsigned int
695 msf_to_log(unsigned char *msf)
696 {
697 unsigned int log;
698
699
700 log = bcd_to_int(msf[2]);
701 log += bcd_to_int(msf[1]) * 75;
702 log += bcd_to_int(msf[0]) * 4500;
703 log = log - LOG_START_OFFSET;
704
705 return log;
706 }
707
708
709
710
711
712
713 static void
714 size_to_buf(unsigned int size,
715 unsigned char *buf)
716 {
717 buf[0] = size / 65536;
718 size = size % 65536;
719 buf[1] = size / 256;
720 buf[2] = size % 256;
721 }
722
723
724
725
726
727
728
729
730
731 static void
732 do_cdu535_request(void)
733 {
734 int block;
735 unsigned int dev;
736 int nsect;
737 unsigned char params[10];
738 int copyoff;
739 int spin_up_retry;
740 unsigned int read_size;
741 unsigned char status[2], cmd[2];
742
743
744 if (!sony_inuse) {
745 cdu_open(NULL, NULL);
746 }
747 while (1) {
748
749
750
751
752 if (!(CURRENT) || CURRENT->dev < 0) {
753 return;
754 }
755 INIT_REQUEST;
756 dev = MINOR(CURRENT->dev);
757 block = CURRENT->sector;
758 nsect = CURRENT->nr_sectors;
759 if (dev != 0) {
760 end_request(0);
761 continue;
762 }
763 switch (CURRENT->cmd) {
764 case READ:
765
766
767
768
769
770 if (sony_toc->lead_out_start_lba <= (block / 4)) {
771 end_request(0);
772 return;
773 }
774 if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
775 end_request(0);
776 return;
777 }
778 while (0 < nsect) {
779
780
781
782
783 if ((block < sony_first_block) || (sony_last_block < block)) {
784 sony_first_block = (block / 4) * 4;
785 log_to_msf(block / 4, params);
786
787
788
789
790
791 if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
792 sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
793 read_size = sony_toc->lead_out_start_lba - (block / 4);
794 } else {
795 sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
796 read_size = sony_buffer_sectors;
797 }
798 size_to_buf(read_size, ¶ms[3]);
799
800
801
802
803
804 spin_up_retry = 0;
805 try_read_again:
806 #if DEBUG > 1
807 if (check_drive_status() != 0) {
808 sony_first_block = -1;
809 sony_last_block = -1;
810 end_request(0);
811 return;
812 }
813 #endif
814 if (seek_and_read_N_blocks(params, read_size, status, sony_buffer,
815 (read_size * 2048)) < 0) {
816 if ((status[0] & SONY535_STATUS1_NOT_SPINNING) && (!spin_up_retry)) {
817 printk(" Sony535 Debug -- calling spin up when reading data!\n");
818 cmd[0] = SONY535_SPIN_UP;
819 do_sony_cmd(cmd, 1, status, NULL, 0, 0);
820 spin_up_retry = 1;
821 goto try_read_again;
822 }
823 printk("Sony CDROM Read error: 0x%.2x\n", status[0]);
824 sony_first_block = -1;
825 sony_last_block = -1;
826 end_request(0);
827 return;
828 }
829 }
830
831
832
833
834 #ifndef MODULE
835 copyoff = (block - sony_first_block) * 512;
836 memcpy(CURRENT->buffer, sony_buffer + copyoff, 512);
837 #else
838 copyoff = block - sony_first_block;
839 memcpy(CURRENT->buffer,
840 sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
841 #endif
842
843 block += 1;
844 nsect -= 1;
845 CURRENT->buffer += 512;
846 }
847
848 end_request(1);
849 break;
850
851 case WRITE:
852 end_request(0);
853 break;
854
855 default:
856 panic("Unknown SONY CD cmd");
857 }
858 }
859 }
860
861
862
863
864
865
866 static void
867 sony_get_toc(void)
868 {
869 unsigned char status[2];
870 if (!sony_toc_read) {
871
872 if (request_toc_data(status, sony_toc) < 0)
873 return;
874 sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
875 sony_toc_read = 1;
876 }
877 }
878
879
880
881
882
883
884 static int
885 find_track(int track)
886 {
887 int i;
888 int num_tracks;
889
890
891 num_tracks = bcd_to_int(sony_toc->last_track_num) -
892 bcd_to_int(sony_toc->first_track_num) + 1;
893 for (i = 0; i < num_tracks; i++) {
894 if (sony_toc->tracks[i].track == track) {
895 return i;
896 }
897 }
898
899 return -1;
900 }
901
902
903
904
905 static int
906 read_subcode(void)
907 {
908 Byte cmd = SONY535_REQUEST_SUB_Q_DATA, status[2];
909 int dsc_status;
910
911 if (check_drive_status() != 0)
912 return -EIO;
913
914 if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
915 sizeof (struct s535_sony_subcode), 1)) != 0) {
916 printk("Sony CDROM error 0x%.2x, %d (read_subcode)\n", status[0],
917 dsc_status);
918 return -EIO;
919 }
920 return 0;
921 }
922
923
924
925
926
927
928
929
930
931 static int
932 sony_get_subchnl_info(long arg)
933 {
934 struct cdrom_subchnl schi;
935
936
937
938 if (check_drive_status() != 0)
939 return -EIO;
940
941 sony_get_toc();
942 if (!sony_toc_read) {
943 return -EIO;
944 }
945 verify_area(VERIFY_WRITE , (char *)arg, sizeof (schi));
946
947 memcpy_fromfs(&schi, (char *)arg, sizeof (schi));
948
949 switch (sony_audio_status) {
950 case CDROM_AUDIO_PLAY:
951 if (read_subcode() < 0) {
952 return -EIO;
953 }
954 break;
955
956 case CDROM_AUDIO_PAUSED:
957 case CDROM_AUDIO_COMPLETED:
958 break;
959
960 case CDROM_AUDIO_NO_STATUS:
961 schi.cdsc_audiostatus = sony_audio_status;
962 memcpy_tofs((char *)arg, &schi, sizeof (schi));
963 return 0;
964 break;
965
966 case CDROM_AUDIO_INVALID:
967 case CDROM_AUDIO_ERROR:
968 default:
969 return -EIO;
970 }
971
972 schi.cdsc_audiostatus = sony_audio_status;
973 schi.cdsc_adr = last_sony_subcode->address;
974 schi.cdsc_ctrl = last_sony_subcode->control;
975 schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
976 schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
977 if (schi.cdsc_format == CDROM_MSF) {
978 schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
979 schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
980 schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
981
982 schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
983 schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
984 schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
985 } else if (schi.cdsc_format == CDROM_LBA) {
986 schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
987 schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
988 }
989 memcpy_tofs((char *)arg, &schi, sizeof (schi));
990 return 0;
991 }
992
993
994
995
996
997 static int
998 cdu_ioctl(struct inode *inode,
999 struct file *file,
1000 unsigned int cmd,
1001 unsigned long arg)
1002 {
1003 unsigned int dev;
1004 unsigned char status[2];
1005 unsigned char cmd_buff[10], params[10];
1006 int i, dsc_status;
1007
1008
1009 if (!inode) {
1010 return -EINVAL;
1011 }
1012 dev = MINOR(inode->i_rdev) >> 6;
1013 if (dev != 0) {
1014 return -EINVAL;
1015 }
1016 if (check_drive_status() != 0)
1017 return -EIO;
1018
1019 switch (cmd) {
1020 case CDROMSTART:
1021 if (spin_up_drive(status) < 0) {
1022 printk("Sony CDROM error 0x%.2x (CDROMSTART)\n", status[0]);
1023 return -EIO;
1024 }
1025 return 0;
1026 break;
1027
1028 case CDROMSTOP:
1029 cmd_buff[0] = SONY535_HOLD;
1030 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1031
1032
1033
1034
1035
1036 sony_audio_status = CDROM_AUDIO_NO_STATUS;
1037 cmd_buff[0] = SONY535_SPIN_DOWN;
1038 dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1039 if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
1040 ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
1041 printk("Sony CDROM error 0x%.2x (CDROMSTOP)\n", status[0]);
1042 return -EIO;
1043 }
1044 return 0;
1045 break;
1046
1047 case CDROMPAUSE:
1048 cmd_buff[0] = SONY535_HOLD;
1049 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1050 printk("Sony CDROM error 0x%.2x (CDROMPAUSE)\n", status[0]);
1051 return -EIO;
1052 }
1053
1054 if (read_subcode() < 0) {
1055 return -EIO;
1056 }
1057 cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1058 cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1059 cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1060 sony_audio_status = CDROM_AUDIO_PAUSED;
1061 return 0;
1062 break;
1063
1064 case CDROMRESUME:
1065 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1066
1067 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
1068 return -EINVAL;
1069 }
1070 spin_up_drive(status);
1071
1072
1073 cmd_buff[0] = SONY535_PLAY_AUDIO;
1074 cmd_buff[1] = 0;
1075 cmd_buff[2] = cur_pos_msf[0];
1076 cmd_buff[3] = cur_pos_msf[1];
1077 cmd_buff[4] = cur_pos_msf[2];
1078 cmd_buff[5] = SONY535_PLAY_AUDIO;
1079 cmd_buff[6] = 2;
1080 cmd_buff[7] = final_pos_msf[0];
1081 cmd_buff[8] = final_pos_msf[1];
1082 cmd_buff[9] = final_pos_msf[2];
1083 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1084 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1085 printk("Sony CDROM error 0x%.2x (CDROMRESUME)\n", status[0]);
1086 return -EIO;
1087 }
1088 sony_audio_status = CDROM_AUDIO_PLAY;
1089 return 0;
1090 break;
1091
1092 case CDROMPLAYMSF:
1093 verify_area(VERIFY_READ, (char *)arg, 6);
1094 spin_up_drive(status);
1095 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1096 memcpy_fromfs(params, (void *)arg, 6);
1097
1098
1099 for (i = 0; i < 3; i++) {
1100 cmd_buff[2 + i] = int_to_bcd(params[i]);
1101 cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
1102 }
1103 cmd_buff[0] = SONY535_PLAY_AUDIO;
1104 cmd_buff[1] = 0;
1105
1106 cmd_buff[5] = SONY535_PLAY_AUDIO;
1107 cmd_buff[6] = 2;
1108
1109 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1110 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1111 printk("Sony CDROM error 0x%.2x (CDROMPLAYMSF)\n", status[0]);
1112 return -EIO;
1113 }
1114
1115 final_pos_msf[0] = cmd_buff[7];
1116 final_pos_msf[1] = cmd_buff[8];
1117 final_pos_msf[2] = cmd_buff[9];
1118 sony_audio_status = CDROM_AUDIO_PLAY;
1119 return 0;
1120 break;
1121
1122 case CDROMREADTOCHDR:
1123 {
1124 struct cdrom_tochdr *hdr;
1125 struct cdrom_tochdr loc_hdr;
1126
1127 sony_get_toc();
1128 if (!sony_toc_read)
1129 return -EIO;
1130 hdr = (struct cdrom_tochdr *)arg;
1131 verify_area(VERIFY_WRITE, hdr, sizeof (*hdr));
1132 loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1133 loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1134 memcpy_tofs(hdr, &loc_hdr, sizeof (*hdr));
1135 }
1136 return 0;
1137 break;
1138
1139 case CDROMREADTOCENTRY:
1140 {
1141 struct cdrom_tocentry *entry;
1142 struct cdrom_tocentry loc_entry;
1143 int track_idx;
1144 unsigned char *msf_val = NULL;
1145
1146 sony_get_toc();
1147 if (!sony_toc_read) {
1148 return -EIO;
1149 }
1150 entry = (struct cdrom_tocentry *)arg;
1151 verify_area(VERIFY_WRITE , entry, sizeof (*entry));
1152
1153 memcpy_fromfs(&loc_entry, entry, sizeof (loc_entry));
1154
1155
1156 if (loc_entry.cdte_track == CDROM_LEADOUT) {
1157 loc_entry.cdte_adr = 0 ;
1158 loc_entry.cdte_ctrl = sony_toc->control2;
1159 msf_val = sony_toc->lead_out_start_msf;
1160 } else {
1161 track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1162 if (track_idx < 0)
1163 return -EINVAL;
1164 loc_entry.cdte_adr = 0 ;
1165 loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1166 msf_val = sony_toc->tracks[track_idx].track_start_msf;
1167 }
1168
1169
1170 if (loc_entry.cdte_format == CDROM_LBA) {
1171 loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1172 } else if (loc_entry.cdte_format == CDROM_MSF) {
1173 loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1174 loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
1175 loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
1176 }
1177 memcpy_tofs(entry, &loc_entry, sizeof (*entry));
1178 }
1179 return 0;
1180 break;
1181
1182 case CDROMPLAYTRKIND:
1183 {
1184 struct cdrom_ti ti;
1185 int track_idx;
1186
1187 sony_get_toc();
1188 if (!sony_toc_read)
1189 return -EIO;
1190 verify_area(VERIFY_READ, (char *)arg, sizeof (ti));
1191
1192 memcpy_fromfs(&ti, (char *)arg, sizeof (ti));
1193 if ((ti.cdti_trk0 < sony_toc->first_track_num)
1194 || (sony_toc->last_track_num < ti.cdti_trk0)
1195 || (ti.cdti_trk1 < ti.cdti_trk0)) {
1196 return -EINVAL;
1197 }
1198 track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1199 if (track_idx < 0)
1200 return -EINVAL;
1201 params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1202 params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1203 params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1204
1205
1206
1207
1208 if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
1209 log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
1210 &(params[4]));
1211 } else {
1212 track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
1213 if (track_idx < 0)
1214 return -EINVAL;
1215 log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
1216 &(params[4]));
1217 }
1218 params[0] = 0x03;
1219
1220 spin_up_drive(status);
1221
1222 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1223
1224
1225 cmd_buff[0] = SONY535_PLAY_AUDIO;
1226 cmd_buff[1] = 0;
1227 cmd_buff[2] = params[1];
1228 cmd_buff[3] = params[2];
1229 cmd_buff[4] = params[3];
1230 cmd_buff[5] = SONY535_PLAY_AUDIO;
1231 cmd_buff[6] = 2;
1232 cmd_buff[7] = params[4];
1233 cmd_buff[8] = params[5];
1234 cmd_buff[9] = params[6];
1235 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1236 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1237 printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
1238 params[2], params[3], params[4], params[5], params[6]);
1239 printk("Sony CDROM error 0x%.2x (CDROMPLAYTRKIND)\n", status[0]);
1240 return -EIO;
1241 }
1242
1243 final_pos_msf[0] = params[4];
1244 final_pos_msf[1] = params[5];
1245 final_pos_msf[2] = params[6];
1246 sony_audio_status = CDROM_AUDIO_PLAY;
1247 return 0;
1248 }
1249
1250 case CDROMSUBCHNL:
1251 return sony_get_subchnl_info(arg);
1252
1253 case CDROMVOLCTRL:
1254 {
1255 struct cdrom_volctrl volctrl;
1256
1257 verify_area(VERIFY_READ, (char *)arg, sizeof (volctrl));
1258
1259 memcpy_fromfs(&volctrl, (char *)arg, sizeof (volctrl));
1260 cmd_buff[0] = SONY535_SET_VOLUME;
1261 cmd_buff[1] = volctrl.channel0;
1262 cmd_buff[2] = volctrl.channel1;
1263 if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
1264 printk("Sony CDROM error 0x%.2x (CDROMVOLCTRL)\n", status[0]);
1265 return -EIO;
1266 }
1267 }
1268 return 0;
1269
1270 case CDROMEJECT:
1271 cmd_buff[0] = SONY535_STOP;
1272 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1273 cmd_buff[0] = SONY535_SPIN_DOWN;
1274 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1275
1276 sony_audio_status = CDROM_AUDIO_INVALID;
1277 cmd_buff[0] = SONY535_EJECT_CADDY;
1278 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1279 printk("Sony CDROM error 0x%.2x (CDROMEJECT)\n", status[0]);
1280 return -EIO;
1281 }
1282 return 0;
1283 break;
1284
1285 default:
1286 return -EINVAL;
1287 }
1288 }
1289
1290
1291
1292
1293
1294
1295 static int
1296 cdu_open(struct inode *inode,
1297 struct file *filp)
1298 {
1299 unsigned char status[2], cmd_buff[2];
1300
1301
1302 if (sony_inuse)
1303 return -EBUSY;
1304 if (check_drive_status() != 0)
1305 return -EIO;
1306 sony_inuse = 1;
1307 MOD_INC_USE_COUNT;
1308
1309 if (spin_up_drive(status) != 0) {
1310 printk("Sony CDROM error 0x%.2x (cdu_open, spin up)\n", status[0]);
1311 sony_inuse = 0;
1312 MOD_DEC_USE_COUNT;
1313 return -EIO;
1314 }
1315 sony_get_toc();
1316 if (!sony_toc_read) {
1317 cmd_buff[0] = SONY535_SPIN_DOWN;
1318 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1319 sony_inuse = 0;
1320 MOD_DEC_USE_COUNT;
1321 return -EIO;
1322 }
1323 if (inode) {
1324 check_disk_change(inode->i_rdev);
1325 }
1326 sony_usage++;
1327
1328 #ifdef LOCK_DOORS
1329
1330 cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
1331 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1332 #endif
1333
1334 return 0;
1335 }
1336
1337
1338
1339
1340
1341
1342 static void
1343 cdu_release(struct inode *inode,
1344 struct file *filp)
1345 {
1346 unsigned char status[2], cmd_no;
1347
1348 sony_inuse = 0;
1349 MOD_DEC_USE_COUNT;
1350
1351 if (0 < sony_usage) {
1352 sony_usage--;
1353 }
1354 if (sony_usage == 0) {
1355 sync_dev(inode->i_rdev);
1356 check_drive_status();
1357
1358 if (sony_audio_status != CDROM_AUDIO_PLAY) {
1359 cmd_no = SONY535_SPIN_DOWN;
1360 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1361 }
1362 #ifdef LOCK_DOORS
1363
1364 cmd_no = SONY535_ENABLE_EJECT_BUTTON;
1365 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1366 #endif
1367 }
1368 }
1369
1370
1371 static struct file_operations cdu_fops =
1372 {
1373 NULL,
1374 block_read,
1375 block_write,
1376 NULL,
1377 NULL,
1378 cdu_ioctl,
1379 NULL,
1380 cdu_open,
1381 cdu_release,
1382 NULL,
1383 NULL,
1384 cdu535_check_media_change,
1385 NULL
1386 };
1387
1388
1389
1390
1391 #ifndef MODULE
1392 unsigned long
1393 sony535_init(unsigned long mem_start, unsigned long mem_end)
1394 #else
1395 int
1396 init_module(void)
1397 #endif
1398 {
1399 struct s535_sony_drive_config drive_config;
1400 unsigned char cmd_buff[3], ret_buff[2];
1401 unsigned char status[2];
1402 int retry_count;
1403 #ifdef MODULE
1404 int i;
1405 #endif
1406
1407
1408 result_reg = sony_cd_base_io;
1409 command_reg = sony_cd_base_io;
1410 data_reg = sony_cd_base_io + 1;
1411 read_status_reg = sony_cd_base_io + 2;
1412 select_unit_reg = sony_cd_base_io + 3;
1413
1414 printk("sonycd535: probing base address %03X\n", sony_cd_base_io);
1415 if (check_region(sony_cd_base_io,4)) {
1416 printk("sonycd535: my base address is not free!\n");
1417 #ifndef MODULE
1418 return mem_start;
1419 #else
1420 return -EIO;
1421 #endif
1422 }
1423
1424 inb(select_unit_reg);
1425 retry_count = jiffies + 2 * HZ;
1426 while (jiffies < retry_count)
1427 sony_sleep();
1428 inb(result_reg);
1429
1430 outb(0, read_status_reg);
1431 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1432 while (jiffies < retry_count) {
1433 select_unit(0);
1434 if (inb(result_reg) != 0xff)
1435 break;
1436 sony_sleep();
1437 }
1438
1439 if ((jiffies < retry_count) && (check_drive_status() != TIME_OUT)) {
1440
1441 cmd_buff[0] = SONY535_INQUIRY;
1442 if (do_sony_cmd(cmd_buff, 1, status, (Byte *) & drive_config, 28, 1) == 0) {
1443
1444 #if DEBUG > 0
1445
1446 if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
1447 printk("Inquiry command returned status = 0x%x\n", status[0]);
1448 #endif
1449 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
1450 cmd_buff[1] = 0x0;
1451 if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) == 0) {
1452
1453 sony_buffer_size = SONY535_BUFFER_SIZE;
1454 sony_buffer_sectors = sony_buffer_size / 2048;
1455
1456 printk("Sony I/F CDROM : %8.8s %16.16s %4.4s",
1457 drive_config.vendor_id,
1458 drive_config.product_id,
1459 drive_config.product_rev_level);
1460 printk(" using %d byte buffer\n", sony_buffer_size);
1461
1462 if (register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) {
1463 printk("Unable to get major %d for %s\n",
1464 MAJOR_NR, CDU535_MESSAGE_NAME);
1465 #ifndef MODULE
1466 return mem_start;
1467 #else
1468 return -EIO;
1469 #endif
1470 }
1471 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1472 read_ahead[MAJOR_NR] = 8;
1473
1474 #ifndef MODULE
1475 sony_toc = (struct s535_sony_toc *)mem_start;
1476 mem_start += sizeof (*sony_toc);
1477 last_sony_subcode = (struct s535_sony_subcode *)mem_start;
1478 mem_start += sizeof (*last_sony_subcode);
1479 sony_buffer = (unsigned char *)mem_start;
1480 mem_start += sony_buffer_size;
1481
1482 #else
1483 sony_toc = (struct s535_sony_toc *)
1484 kmalloc(sizeof (*sony_toc), GFP_KERNEL);
1485 last_sony_subcode = (struct s535_sony_subcode *)
1486 kmalloc(sizeof (*last_sony_subcode), GFP_KERNEL);
1487 sony_buffer = (unsigned char **)
1488 kmalloc(4 * sony_buffer_sectors, GFP_KERNEL);
1489 for (i = 0; i < sony_buffer_sectors; i++)
1490 sony_buffer[i] = (unsigned char *)kmalloc(2048, GFP_KERNEL);
1491 #endif
1492 initialized = 1;
1493 }
1494 }
1495 }
1496
1497 if (!initialized) {
1498 printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
1499 #ifdef MODULE
1500 return -EIO;
1501 #endif
1502 } else {
1503 request_region(sony_cd_base_io, 4, CDU535_HANDLE);
1504 }
1505 #ifndef MODULE
1506 return mem_start;
1507 #else
1508 return 0;
1509 #endif
1510 }
1511
1512 #ifndef MODULE
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 void
1523 sonycd535_setup(char *strings, int *ints)
1524 {
1525 if (ints[0] > 0)
1526 sony_cd_base_io = ints[1];
1527 #if 0
1528 if (ints[0] > 1)
1529 irq_used = ints[2];
1530 #endif
1531 if ((strings != NULL) && (*strings != '\0'))
1532 printk("%s: Warning: Unknown interface type: %s\n",
1533 strings, CDU535_MESSAGE_NAME);
1534 }
1535
1536 #else
1537
1538 void
1539 cleanup_module(void)
1540 {
1541 int i;
1542 if (MOD_IN_USE) {
1543 printk("Sony 535 module in use, cannot remove\n");
1544 return;
1545 }
1546 release_region(sony_cd_base_io, 4);
1547 kfree_s(sony_toc, sizeof (*sony_toc));
1548 kfree_s(last_sony_subcode, sizeof (*last_sony_subcode));
1549 for (i = 0; i < sony_buffer_sectors; i++)
1550 kfree_s(sony_buffer[i], 2048);
1551 kfree_s(sony_buffer, 4 * sony_buffer_sectors);
1552 if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
1553 printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
1554 else
1555 printk(CDU535_HANDLE " module released\n");
1556 }
1557 #endif
1558
1559 #endif