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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152#include <linux/major.h>
153
154#include <linux/module.h>
155
156#include <linux/errno.h>
157#include <linux/signal.h>
158#include <linux/sched.h>
159#include <linux/timer.h>
160#include <linux/fs.h>
161#include <linux/kernel.h>
162#include <linux/hdreg.h>
163#include <linux/genhd.h>
164#include <linux/ioport.h>
165#include <linux/devfs_fs_kernel.h>
166#include <linux/string.h>
167#include <linux/slab.h>
168#include <linux/init.h>
169#include <linux/interrupt.h>
170
171#include <asm/system.h>
172#include <asm/io.h>
173#include <asm/uaccess.h>
174#include <asm/dma.h>
175
176#include <linux/cdrom.h>
177#include "cdu31a.h"
178
179#define MAJOR_NR CDU31A_CDROM_MAJOR
180#include <linux/blkdev.h>
181
182#define CDU31A_READAHEAD 4
183#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
184
185#define DEBUG 0
186
187
188#undef SONY_POLL_EACH_BYTE
189
190
191
192
193
194
195static struct {
196 unsigned short base;
197 short int_num;
198
199} cdu31a_addresses[] __initdata = {
200 {0}
201};
202
203static int handle_sony_cd_attention(void);
204static int read_subcode(void);
205static void sony_get_toc(void);
206static int scd_spinup(void);
207
208static int scd_open(struct cdrom_device_info *, int);
209static void do_sony_cd_cmd(unsigned char cmd,
210 unsigned char *params,
211 unsigned int num_params,
212 unsigned char *result_buffer,
213 unsigned int *result_size);
214static void size_to_buf(unsigned int size, unsigned char *buf);
215
216
217static unsigned int sony_next_block;
218static unsigned int sony_blocks_left = 0;
219
220
221
222
223
224static unsigned int cdu31a_port = 0;
225MODULE_PARM(cdu31a_port, "i");
226
227
228
229
230
231static volatile unsigned short sony_cd_cmd_reg;
232static volatile unsigned short sony_cd_param_reg;
233static volatile unsigned short sony_cd_write_reg;
234static volatile unsigned short sony_cd_control_reg;
235static volatile unsigned short sony_cd_status_reg;
236static volatile unsigned short sony_cd_result_reg;
237static volatile unsigned short sony_cd_read_reg;
238static volatile unsigned short sony_cd_fifost_reg;
239
240static struct request_queue *cdu31a_queue;
241static spinlock_t cdu31a_lock = SPIN_LOCK_UNLOCKED;
242
243static int sony_spun_up = 0;
244
245static int sony_speed = 0;
246
247static int sony_xa_mode = 0;
248
249
250static int sony_raw_data_mode = 1;
251
252
253static unsigned int sony_usage = 0;
254
255
256static int sony_pas_init = 0;
257
258
259static struct s_sony_session_toc single_toc;
260
261
262
263static struct s_all_sessions_toc sony_toc;
264
265
266static int sony_toc_read = 0;
267
268
269static struct s_sony_subcode last_sony_subcode;
270
271
272static volatile int sony_inuse = 0;
273
274
275static DECLARE_WAIT_QUEUE_HEAD(sony_wait);
276
277static struct task_struct *has_cd_task = NULL;
278
279
280
281static int is_double_speed = 0;
282static int is_a_cdu31a = 1;
283
284static int is_auto_eject = 1;
285
286
287
288
289
290static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
291
292
293
294
295
296
297
298
299static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
300static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
301
302
303static int cdu31a_irq = 0;
304MODULE_PARM(cdu31a_irq, "i");
305
306
307
308DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
309
310static int curr_control_reg = 0;
311
312
313
314
315static char disk_changed;
316
317
318
319
320static char readahead_buffer[CD_FRAMESIZE_RAW];
321static int readahead_dataleft = 0;
322static int readahead_bad = 0;
323
324
325
326
327static struct timer_list cdu31a_abort_timer;
328
329
330
331
332static int abort_read_started = 0;
333
334
335
336
337
338static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
339{
340 int retval;
341
342 retval = disk_changed;
343 disk_changed = 0;
344
345 return retval;
346}
347
348
349
350
351
352static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
353{
354 if (CDSL_CURRENT != slot_nr) {
355
356 return -EINVAL;
357 }
358 if (scd_spinup() == 0) {
359 sony_spun_up = 1;
360 }
361 return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
362}
363
364static inline void enable_interrupts(void)
365{
366 curr_control_reg |= (SONY_ATTN_INT_EN_BIT
367 | SONY_RES_RDY_INT_EN_BIT
368 | SONY_DATA_RDY_INT_EN_BIT);
369 outb(curr_control_reg, sony_cd_control_reg);
370}
371
372static inline void disable_interrupts(void)
373{
374 curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
375 | SONY_RES_RDY_INT_EN_BIT
376 | SONY_DATA_RDY_INT_EN_BIT);
377 outb(curr_control_reg, sony_cd_control_reg);
378}
379
380
381
382
383
384static inline void sony_sleep(void)
385{
386 unsigned long flags;
387
388 if (cdu31a_irq <= 0) {
389 yield();
390 } else {
391
392 save_flags(flags);
393 cli();
394 enable_interrupts();
395 interruptible_sleep_on(&cdu31a_irq_wait);
396 restore_flags(flags);
397 }
398}
399
400
401
402
403
404
405static inline int is_attention(void)
406{
407 return ((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
408}
409
410static inline int is_busy(void)
411{
412 return ((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
413}
414
415static inline int is_data_ready(void)
416{
417 return ((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
418}
419
420static inline int is_data_requested(void)
421{
422 return ((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
423}
424
425static inline int is_result_ready(void)
426{
427 return ((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
428}
429
430static inline int is_param_write_rdy(void)
431{
432 return ((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
433}
434
435static inline int is_result_reg_not_empty(void)
436{
437 return ((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
438}
439
440static inline void reset_drive(void)
441{
442 curr_control_reg = 0;
443 readahead_dataleft = 0;
444 sony_toc_read = 0;
445 outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
446}
447
448
449
450
451
452static int scd_reset(struct cdrom_device_info *cdi)
453{
454 unsigned long retry_count;
455
456 reset_drive();
457
458 retry_count = jiffies + SONY_RESET_TIMEOUT;
459 while (time_before(jiffies, retry_count) && (!is_attention())) {
460 sony_sleep();
461 }
462
463 return 0;
464}
465
466static inline void clear_attention(void)
467{
468 outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
469}
470
471static inline void clear_result_ready(void)
472{
473 outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
474}
475
476static inline void clear_data_ready(void)
477{
478 outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
479 sony_cd_control_reg);
480}
481
482static inline void clear_param_reg(void)
483{
484 outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
485}
486
487static inline unsigned char read_status_register(void)
488{
489 return (inb(sony_cd_status_reg));
490}
491
492static inline unsigned char read_result_register(void)
493{
494 return (inb(sony_cd_result_reg));
495}
496
497static inline unsigned char read_data_register(void)
498{
499 return (inb(sony_cd_read_reg));
500}
501
502static inline void write_param(unsigned char param)
503{
504 outb(param, sony_cd_param_reg);
505}
506
507static inline void write_cmd(unsigned char cmd)
508{
509 outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
510 sony_cd_control_reg);
511 outb(cmd, sony_cd_cmd_reg);
512}
513
514static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
515{
516 unsigned char val;
517
518 if (abort_read_started) {
519
520
521
522
523 while (is_result_reg_not_empty()) {
524 val = read_result_register();
525 }
526 clear_data_ready();
527 clear_result_ready();
528
529
530 while (is_data_requested()) {
531 val = read_data_register();
532 }
533 abort_read_started = 0;
534
535
536 if (waitqueue_active(&cdu31a_irq_wait)) {
537 disable_interrupts();
538 wake_up(&cdu31a_irq_wait);
539 }
540 } else if (waitqueue_active(&cdu31a_irq_wait)) {
541 disable_interrupts();
542 wake_up(&cdu31a_irq_wait);
543 } else {
544 disable_interrupts();
545 printk
546 ("CDU31A: Got an interrupt but nothing was waiting\n");
547 }
548 return IRQ_HANDLED;
549}
550
551
552
553
554static unsigned char *translate_error(unsigned char err_code)
555{
556 static unsigned char errbuf[80];
557
558 switch (err_code) {
559 case 0x10:
560 return "illegal command ";
561 case 0x11:
562 return "illegal parameter ";
563
564 case 0x20:
565 return "not loaded ";
566 case 0x21:
567 return "no disc ";
568 case 0x22:
569 return "not spinning ";
570 case 0x23:
571 return "spinning ";
572 case 0x25:
573 return "spindle servo ";
574 case 0x26:
575 return "focus servo ";
576 case 0x29:
577 return "eject mechanism ";
578 case 0x2a:
579 return "audio playing ";
580 case 0x2c:
581 return "emergency eject ";
582
583 case 0x30:
584 return "focus ";
585 case 0x31:
586 return "frame sync ";
587 case 0x32:
588 return "subcode address ";
589 case 0x33:
590 return "block sync ";
591 case 0x34:
592 return "header address ";
593
594 case 0x40:
595 return "illegal track read ";
596 case 0x41:
597 return "mode 0 read ";
598 case 0x42:
599 return "illegal mode read ";
600 case 0x43:
601 return "illegal block size read ";
602 case 0x44:
603 return "mode read ";
604 case 0x45:
605 return "form read ";
606 case 0x46:
607 return "leadout read ";
608 case 0x47:
609 return "buffer overrun ";
610
611 case 0x53:
612 return "unrecoverable CIRC ";
613 case 0x57:
614 return "unrecoverable LECC ";
615
616 case 0x60:
617 return "no TOC ";
618 case 0x61:
619 return "invalid subcode data ";
620 case 0x63:
621 return "focus on TOC read ";
622 case 0x64:
623 return "frame sync on TOC read ";
624 case 0x65:
625 return "TOC data ";
626
627 case 0x70:
628 return "hardware failure ";
629 case 0x91:
630 return "leadin ";
631 case 0x92:
632 return "leadout ";
633 case 0x93:
634 return "data track ";
635 }
636 sprintf(errbuf, "unknown 0x%02x ", err_code);
637 return errbuf;
638}
639
640
641
642
643
644static void set_drive_params(int want_doublespeed)
645{
646 unsigned char res_reg[12];
647 unsigned int res_size;
648 unsigned char params[3];
649
650
651 params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
652 params[1] = 0x00;
653 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
654 params, 2, res_reg, &res_size);
655 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
656 printk(" Unable to set spin-down time: 0x%2.2x\n",
657 res_reg[1]);
658 }
659
660 params[0] = SONY_SD_MECH_CONTROL;
661 params[1] = SONY_AUTO_SPIN_UP_BIT;
662
663 if (is_auto_eject)
664 params[1] |= SONY_AUTO_EJECT_BIT;
665
666 if (is_double_speed && want_doublespeed) {
667 params[1] |= SONY_DOUBLE_SPEED_BIT;
668
669 }
670 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
671 params, 2, res_reg, &res_size);
672 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
673 printk(" Unable to set mechanical parameters: 0x%2.2x\n",
674 res_reg[1]);
675 }
676}
677
678
679
680
681
682static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
683{
684 if (speed == 0)
685 sony_speed = 1;
686 else
687 sony_speed = speed - 1;
688
689 set_drive_params(sony_speed);
690 return 0;
691}
692
693
694
695
696
697static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
698{
699 if (lock == 0 && sony_usage == 1) {
700
701 is_auto_eject = 1;
702 } else {
703 is_auto_eject = 0;
704 }
705 set_drive_params(sony_speed);
706 return 0;
707}
708
709
710
711
712static void restart_on_error(void)
713{
714 unsigned char res_reg[12];
715 unsigned int res_size;
716 unsigned long retry_count;
717
718
719 printk("cdu31a: Resetting drive on error\n");
720 reset_drive();
721 retry_count = jiffies + SONY_RESET_TIMEOUT;
722 while (time_before(jiffies, retry_count) && (!is_attention())) {
723 sony_sleep();
724 }
725 set_drive_params(sony_speed);
726 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
727 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
728 printk("cdu31a: Unable to spin up drive: 0x%2.2x\n",
729 res_reg[1]);
730 }
731
732 current->state = TASK_INTERRUPTIBLE;
733 schedule_timeout(2 * HZ);
734
735 sony_get_toc();
736}
737
738
739
740
741
742static int write_params(unsigned char *params, int num_params)
743{
744 unsigned int retry_count;
745
746
747 retry_count = SONY_READY_RETRIES;
748 while ((retry_count > 0) && (!is_param_write_rdy())) {
749 retry_count--;
750 }
751 if (!is_param_write_rdy()) {
752 return -EIO;
753 }
754
755 while (num_params > 0) {
756 write_param(*params);
757 params++;
758 num_params--;
759 }
760
761 return 0;
762}
763
764
765
766
767
768
769
770
771static void
772get_result(unsigned char *result_buffer, unsigned int *result_size)
773{
774 unsigned char a, b;
775 int i;
776 unsigned long retry_count;
777
778
779 while (handle_sony_cd_attention());
780
781 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
782 while (time_before(jiffies, retry_count)
783 && (is_busy() || (!(is_result_ready())))) {
784 sony_sleep();
785
786 while (handle_sony_cd_attention());
787 }
788 if (is_busy() || (!(is_result_ready()))) {
789#if DEBUG
790 printk("CDU31A timeout out %d\n", __LINE__);
791#endif
792 result_buffer[0] = 0x20;
793 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
794 *result_size = 2;
795 return;
796 }
797
798
799
800
801
802 clear_result_ready();
803 a = read_result_register();
804 *result_buffer = a;
805 result_buffer++;
806
807
808 if ((a & 0xf0) == 0x50) {
809 *result_size = 1;
810 return;
811 }
812
813 b = read_result_register();
814 *result_buffer = b;
815 result_buffer++;
816 *result_size = 2;
817
818
819
820
821
822
823
824
825
826 if ((a & 0xf0) != 0x20) {
827 if (b > 8) {
828 for (i = 0; i < 8; i++) {
829 *result_buffer = read_result_register();
830 result_buffer++;
831 (*result_size)++;
832 }
833 b = b - 8;
834
835 while (b > 10) {
836 retry_count = SONY_READY_RETRIES;
837 while ((retry_count > 0)
838 && (!is_result_ready())) {
839 retry_count--;
840 }
841 if (!is_result_ready()) {
842#if DEBUG
843 printk("CDU31A timeout out %d\n",
844 __LINE__);
845#endif
846 result_buffer[0] = 0x20;
847 result_buffer[1] =
848 SONY_TIMEOUT_OP_ERR;
849 *result_size = 2;
850 return;
851 }
852
853 clear_result_ready();
854
855 for (i = 0; i < 10; i++) {
856 *result_buffer =
857 read_result_register();
858 result_buffer++;
859 (*result_size)++;
860 }
861 b = b - 10;
862 }
863
864 if (b > 0) {
865 retry_count = SONY_READY_RETRIES;
866 while ((retry_count > 0)
867 && (!is_result_ready())) {
868 retry_count--;
869 }
870 if (!is_result_ready()) {
871#if DEBUG
872 printk("CDU31A timeout out %d\n",
873 __LINE__);
874#endif
875 result_buffer[0] = 0x20;
876 result_buffer[1] =
877 SONY_TIMEOUT_OP_ERR;
878 *result_size = 2;
879 return;
880 }
881 }
882 }
883
884 while (b > 0) {
885 *result_buffer = read_result_register();
886 result_buffer++;
887 (*result_size)++;
888 b--;
889 }
890 }
891}
892
893
894
895
896
897
898static void
899do_sony_cd_cmd(unsigned char cmd,
900 unsigned char *params,
901 unsigned int num_params,
902 unsigned char *result_buffer, unsigned int *result_size)
903{
904 unsigned long retry_count;
905 int num_retries;
906 int recursive_call;
907 unsigned long flags;
908
909
910 save_flags(flags);
911 cli();
912 if (current != has_cd_task) {
913 while (sony_inuse) {
914 interruptible_sleep_on(&sony_wait);
915 if (signal_pending(current)) {
916 result_buffer[0] = 0x20;
917 result_buffer[1] = SONY_SIGNAL_OP_ERR;
918 *result_size = 2;
919 restore_flags(flags);
920 return;
921 }
922 }
923 sony_inuse = 1;
924 has_cd_task = current;
925 recursive_call = 0;
926 } else {
927 recursive_call = 1;
928 }
929
930 num_retries = 0;
931retry_cd_operation:
932
933 while (handle_sony_cd_attention());
934
935 sti();
936
937 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
938 while (time_before(jiffies, retry_count) && (is_busy())) {
939 sony_sleep();
940
941 while (handle_sony_cd_attention());
942 }
943 if (is_busy()) {
944#if DEBUG
945 printk("CDU31A timeout out %d\n", __LINE__);
946#endif
947 result_buffer[0] = 0x20;
948 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
949 *result_size = 2;
950 } else {
951 clear_result_ready();
952 clear_param_reg();
953
954 write_params(params, num_params);
955 write_cmd(cmd);
956
957 get_result(result_buffer, result_size);
958 }
959
960 if (((result_buffer[0] & 0xf0) == 0x20)
961 && (num_retries < MAX_CDU31A_RETRIES)) {
962 num_retries++;
963 current->state = TASK_INTERRUPTIBLE;
964 schedule_timeout(HZ / 10);
965 goto retry_cd_operation;
966 }
967
968 if (!recursive_call) {
969 has_cd_task = NULL;
970 sony_inuse = 0;
971 wake_up_interruptible(&sony_wait);
972 }
973
974 restore_flags(flags);
975}
976
977
978
979
980
981
982
983
984
985
986
987static int handle_sony_cd_attention(void)
988{
989 unsigned char atten_code;
990 static int num_consecutive_attentions = 0;
991 volatile int val;
992
993
994#if 0*DEBUG
995 printk("Entering handle_sony_cd_attention\n");
996#endif
997 if (is_attention()) {
998 if (num_consecutive_attentions >
999 CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
1000 printk
1001 ("cdu31a: Too many consecutive attentions: %d\n",
1002 num_consecutive_attentions);
1003 num_consecutive_attentions = 0;
1004#if DEBUG
1005 printk("Leaving handle_sony_cd_attention at %d\n",
1006 __LINE__);
1007#endif
1008 return (0);
1009 }
1010
1011 clear_attention();
1012 atten_code = read_result_register();
1013
1014 switch (atten_code) {
1015
1016 case SONY_MECH_LOADED_ATTN:
1017 disk_changed = 1;
1018 sony_toc_read = 0;
1019 sony_audio_status = CDROM_AUDIO_NO_STATUS;
1020 sony_blocks_left = 0;
1021 break;
1022
1023 case SONY_SPIN_DOWN_COMPLETE_ATTN:
1024
1025 sony_spun_up = 0;
1026 break;
1027
1028 case SONY_AUDIO_PLAY_DONE_ATTN:
1029 sony_audio_status = CDROM_AUDIO_COMPLETED;
1030 read_subcode();
1031 break;
1032
1033 case SONY_EJECT_PUSHED_ATTN:
1034 if (is_auto_eject) {
1035 sony_audio_status = CDROM_AUDIO_INVALID;
1036 }
1037 break;
1038
1039 case SONY_LEAD_IN_ERR_ATTN:
1040 case SONY_LEAD_OUT_ERR_ATTN:
1041 case SONY_DATA_TRACK_ERR_ATTN:
1042 case SONY_AUDIO_PLAYBACK_ERR_ATTN:
1043 sony_audio_status = CDROM_AUDIO_ERROR;
1044 break;
1045 }
1046
1047 num_consecutive_attentions++;
1048#if DEBUG
1049 printk("Leaving handle_sony_cd_attention at %d\n",
1050 __LINE__);
1051#endif
1052 return (1);
1053 } else if (abort_read_started) {
1054 while (is_result_reg_not_empty()) {
1055 val = read_result_register();
1056 }
1057 clear_data_ready();
1058 clear_result_ready();
1059
1060 while (is_data_requested()) {
1061 val = read_data_register();
1062 }
1063 abort_read_started = 0;
1064#if DEBUG
1065 printk("Leaving handle_sony_cd_attention at %d\n",
1066 __LINE__);
1067#endif
1068 return (1);
1069 }
1070
1071 num_consecutive_attentions = 0;
1072#if 0*DEBUG
1073 printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
1074#endif
1075 return (0);
1076}
1077
1078
1079
1080static inline unsigned int int_to_bcd(unsigned int val)
1081{
1082 int retval;
1083
1084
1085 retval = (val / 10) << 4;
1086 retval = retval | val % 10;
1087 return (retval);
1088}
1089
1090
1091
1092static unsigned int bcd_to_int(unsigned int bcd)
1093{
1094 return ((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
1095}
1096
1097
1098
1099
1100
1101
1102static void log_to_msf(unsigned int log, unsigned char *msf)
1103{
1104 log = log + LOG_START_OFFSET;
1105 msf[0] = int_to_bcd(log / 4500);
1106 log = log % 4500;
1107 msf[1] = int_to_bcd(log / 75);
1108 msf[2] = int_to_bcd(log % 75);
1109}
1110
1111
1112
1113
1114
1115static unsigned int msf_to_log(unsigned char *msf)
1116{
1117 unsigned int log;
1118
1119
1120 log = msf[2];
1121 log += msf[1] * 75;
1122 log += msf[0] * 4500;
1123 log = log - LOG_START_OFFSET;
1124
1125 return log;
1126}
1127
1128
1129
1130
1131
1132
1133static void size_to_buf(unsigned int size, unsigned char *buf)
1134{
1135 buf[0] = size / 65536;
1136 size = size % 65536;
1137 buf[1] = size / 256;
1138 buf[2] = size % 256;
1139}
1140
1141
1142
1143
1144
1145
1146
1147static int
1148start_request(unsigned int sector, unsigned int nsect, int read_nsect_only)
1149{
1150 unsigned char params[6];
1151 unsigned int read_size;
1152 unsigned long retry_count;
1153
1154
1155#if DEBUG
1156 printk("Entering start_request\n");
1157#endif
1158 log_to_msf(sector, params);
1159
1160 if (read_nsect_only) {
1161 read_size = nsect;
1162 }
1163
1164
1165
1166
1167 else if ((sector + nsect) >= sony_toc.lead_out_start_lba) {
1168 read_size = sony_toc.lead_out_start_lba - sector;
1169 }
1170
1171 else {
1172 read_size = CDU31A_READAHEAD / 4;
1173 }
1174 size_to_buf(read_size, ¶ms[3]);
1175
1176
1177
1178
1179
1180 while (handle_sony_cd_attention());
1181
1182 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1183 while (time_before(jiffies, retry_count) && (is_busy())) {
1184 sony_sleep();
1185
1186 while (handle_sony_cd_attention());
1187 }
1188
1189 if (is_busy()) {
1190 printk("CDU31A: Timeout while waiting to issue command\n");
1191#if DEBUG
1192 printk("Leaving start_request at %d\n", __LINE__);
1193#endif
1194 return (1);
1195 } else {
1196
1197 clear_result_ready();
1198 clear_param_reg();
1199
1200 write_params(params, 6);
1201 write_cmd(SONY_READ_BLKERR_STAT_CMD);
1202
1203 sony_blocks_left = read_size * 4;
1204 sony_next_block = sector * 4;
1205 readahead_dataleft = 0;
1206 readahead_bad = 0;
1207#if DEBUG
1208 printk("Leaving start_request at %d\n", __LINE__);
1209#endif
1210 return (0);
1211 }
1212#if DEBUG
1213 printk("Leaving start_request at %d\n", __LINE__);
1214#endif
1215}
1216
1217
1218
1219static void abort_read(void)
1220{
1221 unsigned char result_reg[2];
1222 int result_size;
1223 volatile int val;
1224
1225
1226 do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
1227 if ((result_reg[0] & 0xf0) == 0x20) {
1228 printk("CDU31A: Error aborting read, %s error\n",
1229 translate_error(result_reg[1]));
1230 }
1231
1232 while (is_result_reg_not_empty()) {
1233 val = read_result_register();
1234 }
1235 clear_data_ready();
1236 clear_result_ready();
1237
1238 while (is_data_requested()) {
1239 val = read_data_register();
1240 }
1241
1242 sony_blocks_left = 0;
1243 readahead_dataleft = 0;
1244 readahead_bad = 0;
1245}
1246
1247
1248
1249static void handle_abort_timeout(unsigned long data)
1250{
1251 unsigned long flags;
1252
1253#if DEBUG
1254 printk("Entering handle_abort_timeout\n");
1255#endif
1256 save_flags(flags);
1257 cli();
1258
1259 if (!sony_inuse) {
1260
1261
1262
1263
1264 clear_result_ready();
1265 clear_param_reg();
1266 write_cmd(SONY_ABORT_CMD);
1267
1268 sony_blocks_left = 0;
1269 readahead_dataleft = 0;
1270 readahead_bad = 0;
1271 abort_read_started = 1;
1272 }
1273 restore_flags(flags);
1274#if DEBUG
1275 printk("Leaving handle_abort_timeout\n");
1276#endif
1277}
1278
1279
1280static void
1281input_data(char *buffer,
1282 unsigned int bytesleft,
1283 unsigned int nblocks, unsigned int offset, unsigned int skip)
1284{
1285 int i;
1286 volatile unsigned char val;
1287
1288
1289#if DEBUG
1290 printk("Entering input_data\n");
1291#endif
1292
1293
1294 if (sony_xa_mode) {
1295 for (i = 0; i < CD_XA_HEAD; i++) {
1296 val = read_data_register();
1297 }
1298 }
1299
1300 clear_data_ready();
1301
1302 if (bytesleft == 2048) {
1303 insb(sony_cd_read_reg, buffer, 2048);
1304 readahead_dataleft = 0;
1305 } else {
1306
1307
1308 if (skip != 0) {
1309 insb(sony_cd_read_reg, readahead_buffer, skip);
1310 }
1311
1312
1313 insb(sony_cd_read_reg, &buffer[offset], bytesleft);
1314
1315
1316
1317 readahead_dataleft = (2048 - skip) - bytesleft;
1318 insb(sony_cd_read_reg,
1319 readahead_buffer + bytesleft, readahead_dataleft);
1320 }
1321 sony_blocks_left -= nblocks;
1322 sony_next_block += nblocks;
1323
1324
1325
1326 if (sony_xa_mode) {
1327 for (i = 0; i < CD_XA_TAIL; i++) {
1328 val = read_data_register();
1329 }
1330 }
1331#if DEBUG
1332 printk("Leaving input_data at %d\n", __LINE__);
1333#endif
1334}
1335
1336
1337static void
1338read_data_block(char *buffer,
1339 unsigned int block,
1340 unsigned int nblocks,
1341 unsigned char res_reg[], int *res_size)
1342{
1343 unsigned long retry_count;
1344 unsigned int bytesleft;
1345 unsigned int offset;
1346 unsigned int skip;
1347
1348
1349#if DEBUG
1350 printk("Entering read_data_block\n");
1351#endif
1352
1353 res_reg[0] = 0;
1354 res_reg[1] = 0;
1355 *res_size = 0;
1356 bytesleft = nblocks * 512;
1357 offset = 0;
1358
1359
1360
1361 if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) {
1362 sony_next_block += block % 4;
1363 sony_blocks_left -= block % 4;
1364 skip = (block % 4) * 512;
1365 } else {
1366 skip = 0;
1367 }
1368
1369
1370
1371 if (readahead_dataleft != 0) {
1372 if (bytesleft > readahead_dataleft) {
1373
1374
1375 memcpy(buffer,
1376 readahead_buffer + (2048 -
1377 readahead_dataleft),
1378 readahead_dataleft);
1379 bytesleft -= readahead_dataleft;
1380 offset += readahead_dataleft;
1381 readahead_dataleft = 0;
1382 } else {
1383
1384
1385 memcpy(buffer,
1386 readahead_buffer + (2048 -
1387 readahead_dataleft),
1388 bytesleft);
1389 readahead_dataleft -= bytesleft;
1390 bytesleft = 0;
1391 sony_blocks_left -= nblocks;
1392 sony_next_block += nblocks;
1393
1394
1395
1396 if (readahead_bad) {
1397 res_reg[0] = 0x20;
1398 res_reg[1] = SONY_BAD_DATA_ERR;
1399 *res_size = 2;
1400 }
1401
1402 if (readahead_dataleft == 0) {
1403 readahead_bad = 0;
1404 }
1405
1406
1407 if (sony_blocks_left == 0) {
1408 get_result(res_reg, res_size);
1409 }
1410#if DEBUG
1411 printk("Leaving read_data_block at %d\n",
1412 __LINE__);
1413#endif
1414 return;
1415 }
1416 }
1417
1418
1419 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1420 while (time_before(jiffies, retry_count) && !(is_data_ready())) {
1421 while (handle_sony_cd_attention());
1422
1423 sony_sleep();
1424 }
1425 if (!(is_data_ready())) {
1426 if (is_result_ready()) {
1427 get_result(res_reg, res_size);
1428 if ((res_reg[0] & 0xf0) != 0x20) {
1429 printk
1430 ("CDU31A: Got result that should have been error: %d\n",
1431 res_reg[0]);
1432 res_reg[0] = 0x20;
1433 res_reg[1] = SONY_BAD_DATA_ERR;
1434 *res_size = 2;
1435 }
1436 abort_read();
1437 } else {
1438#if DEBUG
1439 printk("CDU31A timeout out %d\n", __LINE__);
1440#endif
1441 res_reg[0] = 0x20;
1442 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1443 *res_size = 2;
1444 abort_read();
1445 }
1446 } else {
1447 input_data(buffer, bytesleft, nblocks, offset, skip);
1448
1449
1450 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1451 while (time_before(jiffies, retry_count)
1452 && !(is_result_ready())) {
1453 while (handle_sony_cd_attention());
1454
1455 sony_sleep();
1456 }
1457
1458 if (!is_result_ready()) {
1459#if DEBUG
1460 printk("CDU31A timeout out %d\n", __LINE__);
1461#endif
1462 res_reg[0] = 0x20;
1463 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1464 *res_size = 2;
1465 abort_read();
1466 } else {
1467 get_result(res_reg, res_size);
1468
1469
1470 if ((res_reg[0] & 0xf0) == 0x50) {
1471
1472 if ((res_reg[0] ==
1473 SONY_NO_CIRC_ERR_BLK_STAT)
1474 || (res_reg[0] ==
1475 SONY_NO_LECC_ERR_BLK_STAT)
1476 || (res_reg[0] ==
1477 SONY_RECOV_LECC_ERR_BLK_STAT)) {
1478
1479
1480
1481 if (readahead_bad) {
1482 readahead_bad = 0;
1483 res_reg[0] = 0x20;
1484 res_reg[1] =
1485 SONY_BAD_DATA_ERR;
1486 *res_size = 2;
1487 }
1488 } else {
1489 printk
1490 ("CDU31A: Data block error: 0x%x\n",
1491 res_reg[0]);
1492 res_reg[0] = 0x20;
1493 res_reg[1] = SONY_BAD_DATA_ERR;
1494 *res_size = 2;
1495
1496
1497
1498 if (bytesleft != 2048) {
1499 readahead_bad = 1;
1500 }
1501 }
1502
1503
1504 if (sony_blocks_left == 0) {
1505 get_result(res_reg, res_size);
1506 }
1507 } else if ((res_reg[0] & 0xf0) != 0x20) {
1508
1509
1510 printk
1511 ("CDU31A: Invalid block status: 0x%x\n",
1512 res_reg[0]);
1513 restart_on_error();
1514 res_reg[0] = 0x20;
1515 res_reg[1] = SONY_BAD_DATA_ERR;
1516 *res_size = 2;
1517 }
1518 }
1519 }
1520#if DEBUG
1521 printk("Leaving read_data_block at %d\n", __LINE__);
1522#endif
1523}
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533static void do_cdu31a_request(request_queue_t * q)
1534{
1535 struct request *req;
1536 int block;
1537 int nblock;
1538 unsigned char res_reg[12];
1539 unsigned int res_size;
1540 int num_retries;
1541 unsigned long flags;
1542
1543
1544#if DEBUG
1545 printk("Entering do_cdu31a_request\n");
1546#endif
1547
1548
1549
1550
1551
1552 save_flags(flags);
1553 cli();
1554 while (sony_inuse) {
1555 interruptible_sleep_on(&sony_wait);
1556 if (signal_pending(current)) {
1557 restore_flags(flags);
1558#if DEBUG
1559 printk("Leaving do_cdu31a_request at %d\n",
1560 __LINE__);
1561#endif
1562 return;
1563 }
1564 }
1565 sony_inuse = 1;
1566 has_cd_task = current;
1567
1568
1569 while (handle_sony_cd_attention());
1570
1571
1572 sony_get_toc();
1573
1574
1575
1576
1577 spin_unlock_irq(q->queue_lock);
1578
1579
1580 del_timer(&cdu31a_abort_timer);
1581
1582 while (1) {
1583
1584
1585
1586
1587 req = elv_next_request(q);
1588 if (!req)
1589 goto end_do_cdu31a_request;
1590
1591 if (!sony_spun_up)
1592 scd_spinup();
1593
1594 block = req->sector;
1595 nblock = req->nr_sectors;
1596
1597 if (!sony_toc_read) {
1598 printk("CDU31A: TOC not read\n");
1599 end_request(req, 0);
1600 continue;
1601 }
1602
1603
1604 if (!(req->flags & REQ_CMD))
1605 continue;
1606 if (rq_data_dir(req) == WRITE) {
1607 end_request(req, 0);
1608 continue;
1609 }
1610 if (rq_data_dir(req) != READ)
1611 panic("CDU31A: Unknown cmd");
1612
1613
1614
1615
1616 if ((block / 4) >= sony_toc.lead_out_start_lba) {
1617 printk("CDU31A: Request past end of media\n");
1618 end_request(req, 0);
1619 continue;
1620 }
1621 if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
1622 printk("CDU31A: Request past end of media\n");
1623 end_request(req, 0);
1624 continue;
1625 }
1626
1627 num_retries = 0;
1628
1629 try_read_again:
1630 while (handle_sony_cd_attention());
1631
1632 if (!sony_toc_read) {
1633 printk("CDU31A: TOC not read\n");
1634 end_request(req, 0);
1635 continue;
1636 }
1637
1638
1639
1640 if (sony_blocks_left == 0) {
1641 if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) {
1642 end_request(req, 0);
1643 continue;
1644 }
1645 }
1646
1647
1648
1649 else if (block != sony_next_block) {
1650#if DEBUG
1651 printk("CDU31A Warning: Read for block %d, expected %d\n",
1652 block, sony_next_block);
1653#endif
1654 abort_read();
1655 if (!sony_toc_read) {
1656 printk("CDU31A: TOC not read\n");
1657 end_request(req, 0);
1658 continue;
1659 }
1660 if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) {
1661 printk("CDU31a: start request failed\n");
1662 end_request(req, 0);
1663 continue;
1664 }
1665 }
1666
1667 read_data_block(req->buffer, block, nblock, res_reg, &res_size);
1668
1669 if (res_reg[0] != 0x20) {
1670 end_request(req, 1);
1671 continue;
1672 }
1673
1674 if (num_retries > MAX_CDU31A_RETRIES) {
1675 end_request(req, 0);
1676 continue;
1677 }
1678
1679 num_retries++;
1680 if (res_reg[1] == SONY_NOT_SPIN_ERR) {
1681 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1682 &res_size);
1683 } else {
1684 printk("CDU31A: %s error for block %d, nblock %d\n",
1685 translate_error(res_reg[1]), block, nblock);
1686 }
1687 goto try_read_again;
1688 }
1689 end_do_cdu31a_request:
1690 spin_lock_irq(q->queue_lock);
1691#if 0
1692
1693 abort_read();
1694#else
1695
1696
1697 cdu31a_abort_timer.expires = jiffies + 2 * HZ;
1698 add_timer(&cdu31a_abort_timer);
1699#endif
1700
1701 has_cd_task = NULL;
1702 sony_inuse = 0;
1703 wake_up_interruptible(&sony_wait);
1704 restore_flags(flags);
1705#if DEBUG
1706 printk("Leaving do_cdu31a_request at %d\n", __LINE__);
1707#endif
1708}
1709
1710
1711
1712
1713
1714
1715static void sony_get_toc(void)
1716{
1717 unsigned char res_reg[2];
1718 unsigned int res_size;
1719 unsigned char parms[1];
1720 int session;
1721 int num_spin_ups;
1722 int totaltracks = 0;
1723 int mint = 99;
1724 int maxt = 0;
1725
1726#if DEBUG
1727 printk("Entering sony_get_toc\n");
1728#endif
1729
1730 num_spin_ups = 0;
1731 if (!sony_toc_read) {
1732 respinup_on_gettoc:
1733
1734 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1735 &res_size);
1736
1737 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
1738 &res_size);
1739
1740
1741
1742 if ((res_size < 2)
1743 || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
1744
1745 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
1746 || (res_reg[1] == 0)) {
1747 goto gettoc_drive_spinning;
1748 }
1749
1750
1751
1752 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
1753 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
1754 num_spin_ups++;
1755 goto respinup_on_gettoc;
1756 }
1757
1758 printk("cdu31a: Error reading TOC: %x %s\n",
1759 res_reg[0], translate_error(res_reg[1]));
1760 return;
1761 }
1762
1763 gettoc_drive_spinning:
1764
1765
1766
1767
1768
1769
1770#if DEBUG
1771 memset(&sony_toc, 0x0e, sizeof(sony_toc));
1772 memset(&single_toc, 0x0f, sizeof(single_toc));
1773#endif
1774 session = 1;
1775 while (1) {
1776
1777
1778
1779#if 1
1780 printk("cdu31a: Trying session %d\n", session);
1781#endif
1782 parms[0] = session;
1783 do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
1784 parms, 1, res_reg, &res_size);
1785
1786#if DEBUG
1787 printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
1788#endif
1789
1790 if ((res_size < 2)
1791 || ((res_reg[0] & 0xf0) == 0x20)) {
1792
1793 if (session == 1)
1794 printk
1795 ("Yikes! Couldn't read any sessions!");
1796 break;
1797 }
1798#if DEBUG
1799 printk("Reading session %d\n", session);
1800#endif
1801
1802 parms[0] = session;
1803 do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
1804 parms,
1805 1,
1806 (unsigned char *) &single_toc,
1807 &res_size);
1808 if ((res_size < 2)
1809 || ((single_toc.exec_status[0] & 0xf0) ==
1810 0x20)) {
1811 printk
1812 ("cdu31a: Error reading session %d: %x %s\n",
1813 session, single_toc.exec_status[0],
1814 translate_error(single_toc.
1815 exec_status[1]));
1816
1817
1818 return;
1819 }
1820#if DEBUG
1821 printk
1822 ("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
1823 single_toc.address0, single_toc.control0,
1824 single_toc.point0,
1825 bcd_to_int(single_toc.first_track_num),
1826 single_toc.disk_type, single_toc.dummy0);
1827 printk
1828 ("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
1829 single_toc.address1, single_toc.control1,
1830 single_toc.point1,
1831 bcd_to_int(single_toc.last_track_num),
1832 single_toc.dummy1, single_toc.dummy2);
1833 printk
1834 ("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
1835 single_toc.address2, single_toc.control2,
1836 single_toc.point2,
1837 bcd_to_int(single_toc.lead_out_start_msf[0]),
1838 bcd_to_int(single_toc.lead_out_start_msf[1]),
1839 bcd_to_int(single_toc.lead_out_start_msf[2]));
1840 if (res_size > 18 && single_toc.pointb0 > 0xaf)
1841 printk
1842 ("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
1843 "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
1844 single_toc.addressb0,
1845 single_toc.controlb0,
1846 single_toc.pointb0,
1847 bcd_to_int(single_toc.
1848 next_poss_prog_area_msf
1849 [0]),
1850 bcd_to_int(single_toc.
1851 next_poss_prog_area_msf
1852 [1]),
1853 bcd_to_int(single_toc.
1854 next_poss_prog_area_msf
1855 [2]),
1856 single_toc.num_mode_5_pointers,
1857 bcd_to_int(single_toc.
1858 max_start_outer_leadout_msf
1859 [0]),
1860 bcd_to_int(single_toc.
1861 max_start_outer_leadout_msf
1862 [1]),
1863 bcd_to_int(single_toc.
1864 max_start_outer_leadout_msf
1865 [2]));
1866 if (res_size > 27 && single_toc.pointb1 > 0xaf)
1867 printk
1868 ("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
1869 single_toc.addressb1,
1870 single_toc.controlb1,
1871 single_toc.pointb1,
1872 single_toc.dummyb0_1[0],
1873 single_toc.dummyb0_1[1],
1874 single_toc.dummyb0_1[2],
1875 single_toc.dummyb0_1[3],
1876 single_toc.num_skip_interval_pointers,
1877 single_toc.num_skip_track_assignments,
1878 single_toc.dummyb0_2);
1879 if (res_size > 36 && single_toc.pointb2 > 0xaf)
1880 printk
1881 ("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1882 single_toc.addressb2,
1883 single_toc.controlb2,
1884 single_toc.pointb2,
1885 single_toc.tracksb2[0],
1886 single_toc.tracksb2[1],
1887 single_toc.tracksb2[2],
1888 single_toc.tracksb2[3],
1889 single_toc.tracksb2[4],
1890 single_toc.tracksb2[5],
1891 single_toc.tracksb2[6]);
1892 if (res_size > 45 && single_toc.pointb3 > 0xaf)
1893 printk
1894 ("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1895 single_toc.addressb3,
1896 single_toc.controlb3,
1897 single_toc.pointb3,
1898 single_toc.tracksb3[0],
1899 single_toc.tracksb3[1],
1900 single_toc.tracksb3[2],
1901 single_toc.tracksb3[3],
1902 single_toc.tracksb3[4],
1903 single_toc.tracksb3[5],
1904 single_toc.tracksb3[6]);
1905 if (res_size > 54 && single_toc.pointb4 > 0xaf)
1906 printk
1907 ("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1908 single_toc.addressb4,
1909 single_toc.controlb4,
1910 single_toc.pointb4,
1911 single_toc.tracksb4[0],
1912 single_toc.tracksb4[1],
1913 single_toc.tracksb4[2],
1914 single_toc.tracksb4[3],
1915 single_toc.tracksb4[4],
1916 single_toc.tracksb4[5],
1917 single_toc.tracksb4[6]);
1918 if (res_size > 63 && single_toc.pointc0 > 0xaf)
1919 printk
1920 ("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1921 single_toc.addressc0,
1922 single_toc.controlc0,
1923 single_toc.pointc0,
1924 single_toc.dummyc0[0],
1925 single_toc.dummyc0[1],
1926 single_toc.dummyc0[2],
1927 single_toc.dummyc0[3],
1928 single_toc.dummyc0[4],
1929 single_toc.dummyc0[5],
1930 single_toc.dummyc0[6]);
1931#endif
1932#undef DEBUG
1933#define DEBUG 0
1934
1935 sony_toc.lead_out_start_msf[0] =
1936 bcd_to_int(single_toc.lead_out_start_msf[0]);
1937 sony_toc.lead_out_start_msf[1] =
1938 bcd_to_int(single_toc.lead_out_start_msf[1]);
1939 sony_toc.lead_out_start_msf[2] =
1940 bcd_to_int(single_toc.lead_out_start_msf[2]);
1941 sony_toc.lead_out_start_lba =
1942 single_toc.lead_out_start_lba =
1943 msf_to_log(sony_toc.lead_out_start_msf);
1944
1945
1946
1947 if (single_toc.pointb0 != 0xb0) {
1948 memmove(((char *) &single_toc) + 27,
1949 ((char *) &single_toc) + 18,
1950 res_size - 18);
1951 res_size += 9;
1952 } else if (res_size > 18) {
1953 sony_toc.lead_out_start_msf[0] =
1954 bcd_to_int(single_toc.
1955 max_start_outer_leadout_msf
1956 [0]);
1957 sony_toc.lead_out_start_msf[1] =
1958 bcd_to_int(single_toc.
1959 max_start_outer_leadout_msf
1960 [1]);
1961 sony_toc.lead_out_start_msf[2] =
1962 bcd_to_int(single_toc.
1963 max_start_outer_leadout_msf
1964 [2]);
1965 sony_toc.lead_out_start_lba =
1966 msf_to_log(sony_toc.
1967 lead_out_start_msf);
1968 }
1969 if (single_toc.pointb1 != 0xb1) {
1970 memmove(((char *) &single_toc) + 36,
1971 ((char *) &single_toc) + 27,
1972 res_size - 27);
1973 res_size += 9;
1974 }
1975 if (single_toc.pointb2 != 0xb2) {
1976 memmove(((char *) &single_toc) + 45,
1977 ((char *) &single_toc) + 36,
1978 res_size - 36);
1979 res_size += 9;
1980 }
1981 if (single_toc.pointb3 != 0xb3) {
1982 memmove(((char *) &single_toc) + 54,
1983 ((char *) &single_toc) + 45,
1984 res_size - 45);
1985 res_size += 9;
1986 }
1987 if (single_toc.pointb4 != 0xb4) {
1988 memmove(((char *) &single_toc) + 63,
1989 ((char *) &single_toc) + 54,
1990 res_size - 54);
1991 res_size += 9;
1992 }
1993 if (single_toc.pointc0 != 0xc0) {
1994 memmove(((char *) &single_toc) + 72,
1995 ((char *) &single_toc) + 63,
1996 res_size - 63);
1997 res_size += 9;
1998 }
1999#if DEBUG
2000 printk
2001 ("start track lba %u, leadout start lba %u\n",
2002 single_toc.start_track_lba,
2003 single_toc.lead_out_start_lba);
2004 {
2005 int i;
2006 for (i = 0;
2007 i <
2008 1 +
2009 bcd_to_int(single_toc.last_track_num)
2010 -
2011 bcd_to_int(single_toc.
2012 first_track_num); i++) {
2013 printk
2014 ("trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
2015 i,
2016 single_toc.tracks[i].address,
2017 single_toc.tracks[i].control,
2018 bcd_to_int(single_toc.
2019 tracks[i].track),
2020 bcd_to_int(single_toc.
2021 tracks[i].
2022 track_start_msf
2023 [0]),
2024 bcd_to_int(single_toc.
2025 tracks[i].
2026 track_start_msf
2027 [1]),
2028 bcd_to_int(single_toc.
2029 tracks[i].
2030 track_start_msf
2031 [2]));
2032 if (mint >
2033 bcd_to_int(single_toc.
2034 tracks[i].track))
2035 mint =
2036 bcd_to_int(single_toc.
2037 tracks[i].
2038 track);
2039 if (maxt <
2040 bcd_to_int(single_toc.
2041 tracks[i].track))
2042 maxt =
2043 bcd_to_int(single_toc.
2044 tracks[i].
2045 track);
2046 }
2047 printk
2048 ("min track number %d, max track number %d\n",
2049 mint, maxt);
2050 }
2051#endif
2052
2053
2054 if (single_toc.disk_type == 0x10 &&
2055 single_toc.first_track_num == 2 &&
2056 single_toc.last_track_num == 2 ) {
2057 sony_toc.tracks[totaltracks].address = 1;
2058 sony_toc.tracks[totaltracks].control = 4;
2059 sony_toc.tracks[totaltracks].track = 1;
2060 sony_toc.tracks[totaltracks].
2061 track_start_msf[0] = 0;
2062 sony_toc.tracks[totaltracks].
2063 track_start_msf[1] = 2;
2064 sony_toc.tracks[totaltracks].
2065 track_start_msf[2] = 0;
2066 mint = maxt = 1;
2067 totaltracks++;
2068 } else
2069
2070 {
2071 int i;
2072 for (i = 0;
2073 i <
2074 1 +
2075 bcd_to_int(single_toc.last_track_num)
2076 -
2077 bcd_to_int(single_toc.
2078 first_track_num);
2079 i++, totaltracks++) {
2080 sony_toc.tracks[totaltracks].
2081 address =
2082 single_toc.tracks[i].address;
2083 sony_toc.tracks[totaltracks].
2084 control =
2085 single_toc.tracks[i].control;
2086 sony_toc.tracks[totaltracks].
2087 track =
2088 bcd_to_int(single_toc.
2089 tracks[i].track);
2090 sony_toc.tracks[totaltracks].
2091 track_start_msf[0] =
2092 bcd_to_int(single_toc.
2093 tracks[i].
2094 track_start_msf[0]);
2095 sony_toc.tracks[totaltracks].
2096 track_start_msf[1] =
2097 bcd_to_int(single_toc.
2098 tracks[i].
2099 track_start_msf[1]);
2100 sony_toc.tracks[totaltracks].
2101 track_start_msf[2] =
2102 bcd_to_int(single_toc.
2103 tracks[i].
2104 track_start_msf[2]);
2105 if (i == 0)
2106 single_toc.
2107 start_track_lba =
2108 msf_to_log(sony_toc.
2109 tracks
2110 [totaltracks].
2111 track_start_msf);
2112 if (mint >
2113 sony_toc.tracks[totaltracks].
2114 track)
2115 mint =
2116 sony_toc.
2117 tracks[totaltracks].
2118 track;
2119 if (maxt <
2120 sony_toc.tracks[totaltracks].
2121 track)
2122 maxt =
2123 sony_toc.
2124 tracks[totaltracks].
2125 track;
2126 }
2127 }
2128 sony_toc.first_track_num = mint;
2129 sony_toc.last_track_num = maxt;
2130
2131
2132
2133
2134
2135
2136 sony_toc.disk_type = single_toc.disk_type;
2137 sony_toc.sessions = session;
2138
2139
2140 if (session == 1)
2141 single_toc.start_track_lba = 0;
2142 sony_toc.start_track_lba =
2143 single_toc.start_track_lba;
2144
2145 if (session > 1 && single_toc.pointb0 == 0xb0 &&
2146 sony_toc.lead_out_start_lba ==
2147 single_toc.lead_out_start_lba) {
2148 break;
2149 }
2150
2151
2152 if (session > 40) {
2153 printk("cdu31a: too many sessions: %d\n",
2154 session);
2155 break;
2156 }
2157 session++;
2158 }
2159 sony_toc.track_entries = totaltracks;
2160
2161 sony_toc.tracks[totaltracks].address = single_toc.address2;
2162 sony_toc.tracks[totaltracks].control = single_toc.control2;
2163 sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
2164 sony_toc.tracks[totaltracks].track_start_msf[0] =
2165 sony_toc.lead_out_start_msf[0];
2166 sony_toc.tracks[totaltracks].track_start_msf[1] =
2167 sony_toc.lead_out_start_msf[1];
2168 sony_toc.tracks[totaltracks].track_start_msf[2] =
2169 sony_toc.lead_out_start_msf[2];
2170
2171 sony_toc_read = 1;
2172#undef DEBUG
2173#if DEBUG
2174 printk
2175 ("Disk session %d, start track: %d, stop track: %d\n",
2176 session, single_toc.start_track_lba,
2177 single_toc.lead_out_start_lba);
2178#endif
2179 }
2180#if DEBUG
2181 printk("Leaving sony_get_toc\n");
2182#endif
2183}
2184
2185
2186
2187
2188
2189
2190static int scd_get_last_session(struct cdrom_device_info *cdi,
2191 struct cdrom_multisession *ms_info)
2192{
2193 if (ms_info == NULL)
2194 return 1;
2195
2196 if (!sony_toc_read)
2197 sony_get_toc();
2198
2199 ms_info->addr_format = CDROM_LBA;
2200 ms_info->addr.lba = sony_toc.start_track_lba;
2201 ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
2202 sony_toc.disk_type == 0x10 ;
2203
2204 return 0;
2205}
2206
2207
2208
2209
2210static int find_track(int track)
2211{
2212 int i;
2213
2214 for (i = 0; i <= sony_toc.track_entries; i++) {
2215 if (sony_toc.tracks[i].track == track) {
2216 return i;
2217 }
2218 }
2219
2220 return -1;
2221}
2222
2223
2224
2225
2226
2227static int read_subcode(void)
2228{
2229 unsigned int res_size;
2230
2231
2232 do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
2233 NULL,
2234 0, (unsigned char *) &last_sony_subcode, &res_size);
2235 if ((res_size < 2)
2236 || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
2237 printk("Sony CDROM error %s (read_subcode)\n",
2238 translate_error(last_sony_subcode.exec_status[1]));
2239 return -EIO;
2240 }
2241
2242 last_sony_subcode.track_num =
2243 bcd_to_int(last_sony_subcode.track_num);
2244 last_sony_subcode.index_num =
2245 bcd_to_int(last_sony_subcode.index_num);
2246 last_sony_subcode.abs_msf[0] =
2247 bcd_to_int(last_sony_subcode.abs_msf[0]);
2248 last_sony_subcode.abs_msf[1] =
2249 bcd_to_int(last_sony_subcode.abs_msf[1]);
2250 last_sony_subcode.abs_msf[2] =
2251 bcd_to_int(last_sony_subcode.abs_msf[2]);
2252
2253 last_sony_subcode.rel_msf[0] =
2254 bcd_to_int(last_sony_subcode.rel_msf[0]);
2255 last_sony_subcode.rel_msf[1] =
2256 bcd_to_int(last_sony_subcode.rel_msf[1]);
2257 last_sony_subcode.rel_msf[2] =
2258 bcd_to_int(last_sony_subcode.rel_msf[2]);
2259 return 0;
2260}
2261
2262
2263
2264
2265
2266static int
2267scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
2268{
2269 unsigned char resbuffer[2 + 14];
2270 unsigned char *mcnp = mcn->medium_catalog_number;
2271 unsigned char *resp = resbuffer + 3;
2272 unsigned int res_size;
2273
2274 memset(mcn->medium_catalog_number, 0, 14);
2275 do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
2276 NULL, 0, resbuffer, &res_size);
2277 if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
2278 else {
2279
2280 *mcnp++ = (*resp >> 4) + '0';
2281 *mcnp++ = (*resp++ & 0x0f) + '0';
2282 *mcnp++ = (*resp >> 4) + '0';
2283 *mcnp++ = (*resp++ & 0x0f) + '0';
2284 *mcnp++ = (*resp >> 4) + '0';
2285 *mcnp++ = (*resp++ & 0x0f) + '0';
2286 *mcnp++ = (*resp >> 4) + '0';
2287 *mcnp++ = (*resp++ & 0x0f) + '0';
2288 *mcnp++ = (*resp >> 4) + '0';
2289 *mcnp++ = (*resp++ & 0x0f) + '0';
2290 *mcnp++ = (*resp >> 4) + '0';
2291 *mcnp++ = (*resp++ & 0x0f) + '0';
2292 *mcnp++ = (*resp >> 4) + '0';
2293 }
2294 *mcnp = '\0';
2295 return 0;
2296}
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
2307{
2308
2309 while (handle_sony_cd_attention());
2310
2311 sony_get_toc();
2312 if (!sony_toc_read) {
2313 return -EIO;
2314 }
2315
2316 switch (sony_audio_status) {
2317 case CDROM_AUDIO_NO_STATUS:
2318 case CDROM_AUDIO_PLAY:
2319 if (read_subcode() < 0) {
2320 return -EIO;
2321 }
2322 break;
2323
2324 case CDROM_AUDIO_PAUSED:
2325 case CDROM_AUDIO_COMPLETED:
2326 break;
2327
2328#if 0
2329 case CDROM_AUDIO_NO_STATUS:
2330 schi->cdsc_audiostatus = sony_audio_status;
2331 return 0;
2332 break;
2333#endif
2334 case CDROM_AUDIO_INVALID:
2335 case CDROM_AUDIO_ERROR:
2336 default:
2337 return -EIO;
2338 }
2339
2340 schi->cdsc_audiostatus = sony_audio_status;
2341 schi->cdsc_adr = last_sony_subcode.address;
2342 schi->cdsc_ctrl = last_sony_subcode.control;
2343 schi->cdsc_trk = last_sony_subcode.track_num;
2344 schi->cdsc_ind = last_sony_subcode.index_num;
2345 if (schi->cdsc_format == CDROM_MSF) {
2346 schi->cdsc_absaddr.msf.minute =
2347 last_sony_subcode.abs_msf[0];
2348 schi->cdsc_absaddr.msf.second =
2349 last_sony_subcode.abs_msf[1];
2350 schi->cdsc_absaddr.msf.frame =
2351 last_sony_subcode.abs_msf[2];
2352
2353 schi->cdsc_reladdr.msf.minute =
2354 last_sony_subcode.rel_msf[0];
2355 schi->cdsc_reladdr.msf.second =
2356 last_sony_subcode.rel_msf[1];
2357 schi->cdsc_reladdr.msf.frame =
2358 last_sony_subcode.rel_msf[2];
2359 } else if (schi->cdsc_format == CDROM_LBA) {
2360 schi->cdsc_absaddr.lba =
2361 msf_to_log(last_sony_subcode.abs_msf);
2362 schi->cdsc_reladdr.lba =
2363 msf_to_log(last_sony_subcode.rel_msf);
2364 }
2365
2366 return 0;
2367}
2368
2369
2370
2371
2372
2373static void
2374read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
2375{
2376 unsigned long retry_count;
2377 int result_read;
2378
2379
2380 res_reg[0] = 0;
2381 res_reg[1] = 0;
2382 *res_size = 0;
2383 result_read = 0;
2384
2385
2386 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2387 continue_read_audio_wait:
2388 while (time_before(jiffies, retry_count) && !(is_data_ready())
2389 && !(is_result_ready() || result_read)) {
2390 while (handle_sony_cd_attention());
2391
2392 sony_sleep();
2393 }
2394 if (!(is_data_ready())) {
2395 if (is_result_ready() && !result_read) {
2396 get_result(res_reg, res_size);
2397
2398
2399 if ((res_reg[0] & 0xf0) == 0x50) {
2400 result_read = 1;
2401 goto continue_read_audio_wait;
2402 }
2403
2404 else if ((res_reg[0] & 0xf0) != 0x20) {
2405 printk
2406 ("CDU31A: Got result that should have been error: %d\n",
2407 res_reg[0]);
2408 res_reg[0] = 0x20;
2409 res_reg[1] = SONY_BAD_DATA_ERR;
2410 *res_size = 2;
2411 }
2412 abort_read();
2413 } else {
2414#if DEBUG
2415 printk("CDU31A timeout out %d\n", __LINE__);
2416#endif
2417 res_reg[0] = 0x20;
2418 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2419 *res_size = 2;
2420 abort_read();
2421 }
2422 } else {
2423 clear_data_ready();
2424
2425
2426 if (sony_raw_data_mode) {
2427 insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
2428 CD_FRAMESIZE_RAW1);
2429 } else {
2430
2431 insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
2432 }
2433
2434
2435 if (!result_read) {
2436
2437 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2438 while (time_before(jiffies, retry_count)
2439 && !(is_result_ready())) {
2440 while (handle_sony_cd_attention());
2441
2442 sony_sleep();
2443 }
2444
2445 if (!is_result_ready()) {
2446#if DEBUG
2447 printk("CDU31A timeout out %d\n",
2448 __LINE__);
2449#endif
2450 res_reg[0] = 0x20;
2451 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2452 *res_size = 2;
2453 abort_read();
2454 return;
2455 } else {
2456 get_result(res_reg, res_size);
2457 }
2458 }
2459
2460 if ((res_reg[0] & 0xf0) == 0x50) {
2461 if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
2462 || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
2463 || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
2464 || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
2465
2466 } else {
2467 printk("CDU31A: Data block error: 0x%x\n",
2468 res_reg[0]);
2469 res_reg[0] = 0x20;
2470 res_reg[1] = SONY_BAD_DATA_ERR;
2471 *res_size = 2;
2472 }
2473 } else if ((res_reg[0] & 0xf0) != 0x20) {
2474
2475
2476 printk("CDU31A: Invalid block status: 0x%x\n",
2477 res_reg[0]);
2478 restart_on_error();
2479 res_reg[0] = 0x20;
2480 res_reg[1] = SONY_BAD_DATA_ERR;
2481 *res_size = 2;
2482 }
2483 }
2484}
2485
2486
2487
2488static int read_audio(struct cdrom_read_audio *ra)
2489{
2490 int retval;
2491 unsigned char params[2];
2492 unsigned char res_reg[12];
2493 unsigned int res_size;
2494 unsigned int cframe;
2495 unsigned long flags;
2496
2497
2498
2499
2500
2501 save_flags(flags);
2502 cli();
2503 while (sony_inuse) {
2504 interruptible_sleep_on(&sony_wait);
2505 if (signal_pending(current)) {
2506 restore_flags(flags);
2507 return -EAGAIN;
2508 }
2509 }
2510 sony_inuse = 1;
2511 has_cd_task = current;
2512 restore_flags(flags);
2513
2514 if (!sony_spun_up) {
2515 scd_spinup();
2516 }
2517
2518
2519 params[0] = SONY_SD_DECODE_PARAM;
2520 params[1] = 0x06 | sony_raw_data_mode;
2521 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2522 params, 2, res_reg, &res_size);
2523 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2524 printk("CDU31A: Unable to set decode params: 0x%2.2x\n",
2525 res_reg[1]);
2526 return -EIO;
2527 }
2528
2529
2530
2531
2532
2533 retval = 0;
2534
2535 if (start_request(ra->addr.lba, ra->nframes, 1)) {
2536 retval = -EIO;
2537 goto exit_read_audio;
2538 }
2539
2540
2541 cframe = 0;
2542 while (cframe < ra->nframes) {
2543 read_audio_data(readahead_buffer, res_reg, &res_size);
2544 if ((res_reg[0] & 0xf0) == 0x20) {
2545 if (res_reg[1] == SONY_BAD_DATA_ERR) {
2546 printk
2547 ("CDU31A: Data error on audio sector %d\n",
2548 ra->addr.lba + cframe);
2549 } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
2550
2551 sony_raw_data_mode =
2552 (sony_raw_data_mode) ? 0 : 1;
2553
2554
2555 params[0] = SONY_SD_DECODE_PARAM;
2556 params[1] = 0x06 | sony_raw_data_mode;
2557 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2558 params,
2559 2, res_reg, &res_size);
2560 if ((res_size < 2)
2561 || ((res_reg[0] & 0xf0) == 0x20)) {
2562 printk
2563 ("CDU31A: Unable to set decode params: 0x%2.2x\n",
2564 res_reg[1]);
2565 retval = -EIO;
2566 goto exit_read_audio;
2567 }
2568
2569
2570 if (start_request
2571 (ra->addr.lba + cframe,
2572 ra->nframes - cframe, 1)) {
2573 retval = -EIO;
2574 goto exit_read_audio;
2575 }
2576
2577
2578
2579
2580 read_audio_data(readahead_buffer, res_reg,
2581 &res_size);
2582 if ((res_reg[0] & 0xf0) == 0x20) {
2583 if (res_reg[1] ==
2584 SONY_BAD_DATA_ERR) {
2585 printk
2586 ("CDU31A: Data error on audio sector %d\n",
2587 ra->addr.lba +
2588 cframe);
2589 } else {
2590 printk
2591 ("CDU31A: Error reading audio data on sector %d: %s\n",
2592 ra->addr.lba + cframe,
2593 translate_error
2594 (res_reg[1]));
2595 retval = -EIO;
2596 goto exit_read_audio;
2597 }
2598 } else if (copy_to_user(ra->buf +
2599 (CD_FRAMESIZE_RAW
2600 * cframe),
2601 readahead_buffer,
2602 CD_FRAMESIZE_RAW)) {
2603 retval = -EFAULT;
2604 goto exit_read_audio;
2605 }
2606 } else {
2607 printk
2608 ("CDU31A: Error reading audio data on sector %d: %s\n",
2609 ra->addr.lba + cframe,
2610 translate_error(res_reg[1]));
2611 retval = -EIO;
2612 goto exit_read_audio;
2613 }
2614 } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
2615 (char *)readahead_buffer,
2616 CD_FRAMESIZE_RAW)) {
2617 retval = -EFAULT;
2618 goto exit_read_audio;
2619 }
2620
2621 cframe++;
2622 }
2623
2624 get_result(res_reg, &res_size);
2625 if ((res_reg[0] & 0xf0) == 0x20) {
2626 printk("CDU31A: Error return from audio read: %s\n",
2627 translate_error(res_reg[1]));
2628 retval = -EIO;
2629 goto exit_read_audio;
2630 }
2631
2632 exit_read_audio:
2633
2634
2635 params[0] = SONY_SD_DECODE_PARAM;
2636 if (!sony_xa_mode) {
2637 params[1] = 0x0f;
2638 } else {
2639 params[1] = 0x07;
2640 }
2641 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2642 params, 2, res_reg, &res_size);
2643 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2644 printk("CDU31A: Unable to reset decode params: 0x%2.2x\n",
2645 res_reg[1]);
2646 return -EIO;
2647 }
2648
2649 has_cd_task = NULL;
2650 sony_inuse = 0;
2651 wake_up_interruptible(&sony_wait);
2652
2653 return (retval);
2654}
2655
2656static int
2657do_sony_cd_cmd_chk(const char *name,
2658 unsigned char cmd,
2659 unsigned char *params,
2660 unsigned int num_params,
2661 unsigned char *result_buffer, unsigned int *result_size)
2662{
2663 do_sony_cd_cmd(cmd, params, num_params, result_buffer,
2664 result_size);
2665 if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
2666 printk("Sony CDROM error %s (CDROM%s)\n",
2667 translate_error(result_buffer[1]), name);
2668 return -EIO;
2669 }
2670 return 0;
2671}
2672
2673
2674
2675
2676
2677static int scd_tray_move(struct cdrom_device_info *cdi, int position)
2678{
2679 if (position == 1 ) {
2680 unsigned char res_reg[12];
2681 unsigned int res_size;
2682
2683 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2684 &res_size);
2685 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2686 &res_size);
2687
2688 sony_audio_status = CDROM_AUDIO_INVALID;
2689 return do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
2690 res_reg, &res_size);
2691 } else {
2692 if (0 == scd_spinup())
2693 sony_spun_up = 1;
2694 return 0;
2695 }
2696}
2697
2698
2699
2700
2701static int scd_audio_ioctl(struct cdrom_device_info *cdi,
2702 unsigned int cmd, void *arg)
2703{
2704 unsigned char res_reg[12];
2705 unsigned int res_size;
2706 unsigned char params[7];
2707 int i;
2708
2709
2710 switch (cmd) {
2711 case CDROMSTART:
2712 return do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
2713 0, res_reg, &res_size);
2714 break;
2715
2716 case CDROMSTOP:
2717 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2718 &res_size);
2719
2720
2721
2722
2723
2724 sony_audio_status = CDROM_AUDIO_NO_STATUS;
2725 return do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
2726 0, res_reg, &res_size);
2727
2728 case CDROMPAUSE:
2729 if (do_sony_cd_cmd_chk
2730 ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2731 &res_size))
2732 return -EIO;
2733
2734 if (read_subcode() < 0) {
2735 return -EIO;
2736 }
2737 cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
2738 cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
2739 cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
2740 sony_audio_status = CDROM_AUDIO_PAUSED;
2741 return 0;
2742 break;
2743
2744 case CDROMRESUME:
2745 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
2746 return -EINVAL;
2747 }
2748
2749 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2750 &res_size);
2751
2752
2753 params[1] = int_to_bcd(cur_pos_msf[0]);
2754 params[2] = int_to_bcd(cur_pos_msf[1]);
2755 params[3] = int_to_bcd(cur_pos_msf[2]);
2756 params[4] = int_to_bcd(final_pos_msf[0]);
2757 params[5] = int_to_bcd(final_pos_msf[1]);
2758 params[6] = int_to_bcd(final_pos_msf[2]);
2759 params[0] = 0x03;
2760 if (do_sony_cd_cmd_chk
2761 ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
2762 &res_size) < 0)
2763 return -EIO;
2764 sony_audio_status = CDROM_AUDIO_PLAY;
2765 return 0;
2766
2767 case CDROMPLAYMSF:
2768 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2769 &res_size);
2770
2771
2772 for (i = 1; i < 7; i++) {
2773 params[i] =
2774 int_to_bcd(((unsigned char *) arg)[i - 1]);
2775 }
2776 params[0] = 0x03;
2777 if (do_sony_cd_cmd_chk
2778 ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
2779 res_reg, &res_size) < 0)
2780 return -EIO;
2781
2782
2783 final_pos_msf[0] = bcd_to_int(params[4]);
2784 final_pos_msf[1] = bcd_to_int(params[5]);
2785 final_pos_msf[2] = bcd_to_int(params[6]);
2786 sony_audio_status = CDROM_AUDIO_PLAY;
2787 return 0;
2788
2789 case CDROMREADTOCHDR:
2790 {
2791 struct cdrom_tochdr *hdr;
2792
2793 sony_get_toc();
2794 if (!sony_toc_read) {
2795 return -EIO;
2796 }
2797
2798 hdr = (struct cdrom_tochdr *) arg;
2799 hdr->cdth_trk0 = sony_toc.first_track_num;
2800 hdr->cdth_trk1 = sony_toc.last_track_num;
2801 }
2802 return 0;
2803
2804 case CDROMREADTOCENTRY:
2805 {
2806 struct cdrom_tocentry *entry;
2807 int track_idx;
2808 unsigned char *msf_val = NULL;
2809
2810 sony_get_toc();
2811 if (!sony_toc_read) {
2812 return -EIO;
2813 }
2814
2815 entry = (struct cdrom_tocentry *) arg;
2816
2817 track_idx = find_track(entry->cdte_track);
2818 if (track_idx < 0) {
2819 return -EINVAL;
2820 }
2821
2822 entry->cdte_adr =
2823 sony_toc.tracks[track_idx].address;
2824 entry->cdte_ctrl =
2825 sony_toc.tracks[track_idx].control;
2826 msf_val =
2827 sony_toc.tracks[track_idx].track_start_msf;
2828
2829
2830 if (entry->cdte_format == CDROM_LBA) {
2831 entry->cdte_addr.lba = msf_to_log(msf_val);
2832 } else if (entry->cdte_format == CDROM_MSF) {
2833 entry->cdte_addr.msf.minute = *msf_val;
2834 entry->cdte_addr.msf.second =
2835 *(msf_val + 1);
2836 entry->cdte_addr.msf.frame =
2837 *(msf_val + 2);
2838 }
2839 }
2840 return 0;
2841 break;
2842
2843 case CDROMPLAYTRKIND:
2844 {
2845 struct cdrom_ti *ti = (struct cdrom_ti *) arg;
2846 int track_idx;
2847
2848 sony_get_toc();
2849 if (!sony_toc_read) {
2850 return -EIO;
2851 }
2852
2853 if ((ti->cdti_trk0 < sony_toc.first_track_num)
2854 || (ti->cdti_trk0 > sony_toc.last_track_num)
2855 || (ti->cdti_trk1 < ti->cdti_trk0)) {
2856 return -EINVAL;
2857 }
2858
2859 track_idx = find_track(ti->cdti_trk0);
2860 if (track_idx < 0) {
2861 return -EINVAL;
2862 }
2863 params[1] =
2864 int_to_bcd(sony_toc.tracks[track_idx].
2865 track_start_msf[0]);
2866 params[2] =
2867 int_to_bcd(sony_toc.tracks[track_idx].
2868 track_start_msf[1]);
2869 params[3] =
2870 int_to_bcd(sony_toc.tracks[track_idx].
2871 track_start_msf[2]);
2872
2873
2874
2875
2876
2877 if (ti->cdti_trk1 >= sony_toc.last_track_num) {
2878 track_idx = find_track(CDROM_LEADOUT);
2879 } else {
2880 track_idx = find_track(ti->cdti_trk1 + 1);
2881 }
2882 if (track_idx < 0) {
2883 return -EINVAL;
2884 }
2885 params[4] =
2886 int_to_bcd(sony_toc.tracks[track_idx].
2887 track_start_msf[0]);
2888 params[5] =
2889 int_to_bcd(sony_toc.tracks[track_idx].
2890 track_start_msf[1]);
2891 params[6] =
2892 int_to_bcd(sony_toc.tracks[track_idx].
2893 track_start_msf[2]);
2894 params[0] = 0x03;
2895
2896 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2897 &res_size);
2898
2899 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
2900 res_reg, &res_size);
2901
2902 if ((res_size < 2)
2903 || ((res_reg[0] & 0xf0) == 0x20)) {
2904 printk("Params: %x %x %x %x %x %x %x\n",
2905 params[0], params[1], params[2],
2906 params[3], params[4], params[5],
2907 params[6]);
2908 printk
2909 ("Sony CDROM error %s (CDROMPLAYTRKIND)\n",
2910 translate_error(res_reg[1]));
2911 return -EIO;
2912 }
2913
2914
2915 final_pos_msf[0] = bcd_to_int(params[4]);
2916 final_pos_msf[1] = bcd_to_int(params[5]);
2917 final_pos_msf[2] = bcd_to_int(params[6]);
2918 sony_audio_status = CDROM_AUDIO_PLAY;
2919 return 0;
2920 }
2921
2922 case CDROMVOLCTRL:
2923 {
2924 struct cdrom_volctrl *volctrl =
2925 (struct cdrom_volctrl *) arg;
2926
2927 params[0] = SONY_SD_AUDIO_VOLUME;
2928 params[1] = volctrl->channel0;
2929 params[2] = volctrl->channel1;
2930 return do_sony_cd_cmd_chk("VOLCTRL",
2931 SONY_SET_DRIVE_PARAM_CMD,
2932 params, 3, res_reg,
2933 &res_size);
2934 }
2935 case CDROMSUBCHNL:
2936 return sony_get_subchnl_info((struct cdrom_subchnl *) arg);
2937
2938 default:
2939 return -EINVAL;
2940 }
2941}
2942
2943static int scd_dev_ioctl(struct cdrom_device_info *cdi,
2944 unsigned int cmd, unsigned long arg)
2945{
2946 void __user *argp = (void __user *)arg;
2947 int i;
2948
2949 switch (cmd) {
2950 case CDROMREADAUDIO:
2951
2952 {
2953 struct cdrom_read_audio ra;
2954
2955
2956 sony_get_toc();
2957 if (!sony_toc_read) {
2958 return -EIO;
2959 }
2960
2961 if (copy_from_user(&ra, argp, sizeof(ra)))
2962 return -EFAULT;
2963
2964 if (ra.nframes == 0) {
2965 return 0;
2966 }
2967
2968 i = verify_area(VERIFY_WRITE, ra.buf,
2969 CD_FRAMESIZE_RAW * ra.nframes);
2970 if (i < 0)
2971 return i;
2972
2973 if (ra.addr_format == CDROM_LBA) {
2974 if ((ra.addr.lba >=
2975 sony_toc.lead_out_start_lba)
2976 || (ra.addr.lba + ra.nframes >=
2977 sony_toc.lead_out_start_lba)) {
2978 return -EINVAL;
2979 }
2980 } else if (ra.addr_format == CDROM_MSF) {
2981 if ((ra.addr.msf.minute >= 75)
2982 || (ra.addr.msf.second >= 60)
2983 || (ra.addr.msf.frame >= 75)) {
2984 return -EINVAL;
2985 }
2986
2987 ra.addr.lba = ((ra.addr.msf.minute * 4500)
2988 + (ra.addr.msf.second * 75)
2989 + ra.addr.msf.frame);
2990 if ((ra.addr.lba >=
2991 sony_toc.lead_out_start_lba)
2992 || (ra.addr.lba + ra.nframes >=
2993 sony_toc.lead_out_start_lba)) {
2994 return -EINVAL;
2995 }
2996
2997
2998
2999
3000 ra.addr.lba -= LOG_START_OFFSET;
3001 } else {
3002 return -EINVAL;
3003 }
3004
3005 return (read_audio(&ra));
3006 }
3007 return 0;
3008 break;
3009
3010 default:
3011 return -EINVAL;
3012 }
3013}
3014
3015static int scd_spinup(void)
3016{
3017 unsigned char res_reg[12];
3018 unsigned int res_size;
3019 int num_spin_ups;
3020
3021 num_spin_ups = 0;
3022
3023 respinup_on_open:
3024 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
3025
3026
3027
3028 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
3029 printk("Sony CDROM %s error (scd_open, spin up)\n",
3030 translate_error(res_reg[1]));
3031 return 1;
3032 }
3033
3034 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
3035
3036
3037
3038 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
3039
3040 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
3041 || (res_reg[1] == 0)) {
3042 return 0;
3043 }
3044
3045
3046
3047 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
3048 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
3049 num_spin_ups++;
3050 goto respinup_on_open;
3051 }
3052
3053 printk("Sony CDROM error %s (scd_open, read toc)\n",
3054 translate_error(res_reg[1]));
3055 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
3056 &res_size);
3057 return 1;
3058 }
3059 return 0;
3060}
3061
3062
3063
3064
3065
3066static int scd_open(struct cdrom_device_info *cdi, int openmode)
3067{
3068 unsigned char res_reg[12];
3069 unsigned int res_size;
3070 unsigned char params[2];
3071
3072 if (sony_usage == 0) {
3073 if (scd_spinup() != 0)
3074 return -EIO;
3075 sony_get_toc();
3076 if (!sony_toc_read) {
3077 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
3078 res_reg, &res_size);
3079 return -EIO;
3080 }
3081
3082
3083
3084
3085 if ((sony_toc.disk_type != 0x00)
3086 && (!is_double_speed)) {
3087 params[0] = SONY_SD_DECODE_PARAM;
3088 params[1] = 0x07;
3089 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
3090 params, 2, res_reg, &res_size);
3091 if ((res_size < 2)
3092 || ((res_reg[0] & 0xf0) == 0x20)) {
3093 printk
3094 ("CDU31A: Unable to set XA params: 0x%2.2x\n",
3095 res_reg[1]);
3096 }
3097 sony_xa_mode = 1;
3098 }
3099
3100 else if (sony_xa_mode) {
3101 params[0] = SONY_SD_DECODE_PARAM;
3102 params[1] = 0x0f;
3103 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
3104 params, 2, res_reg, &res_size);
3105 if ((res_size < 2)
3106 || ((res_reg[0] & 0xf0) == 0x20)) {
3107 printk
3108 ("CDU31A: Unable to reset XA params: 0x%2.2x\n",
3109 res_reg[1]);
3110 }
3111 sony_xa_mode = 0;
3112 }
3113
3114 sony_spun_up = 1;
3115 }
3116
3117 sony_usage++;
3118
3119 return 0;
3120}
3121
3122
3123
3124
3125
3126
3127static void scd_release(struct cdrom_device_info *cdi)
3128{
3129 if (sony_usage == 1) {
3130 unsigned char res_reg[12];
3131 unsigned int res_size;
3132
3133 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
3134 &res_size);
3135
3136 sony_spun_up = 0;
3137 }
3138 sony_usage--;
3139}
3140
3141static struct cdrom_device_ops scd_dops = {
3142 .open = scd_open,
3143 .release = scd_release,
3144 .drive_status = scd_drive_status,
3145 .media_changed = scd_media_changed,
3146 .tray_move = scd_tray_move,
3147 .lock_door = scd_lock_door,
3148 .select_speed = scd_select_speed,
3149 .get_last_session = scd_get_last_session,
3150 .get_mcn = scd_get_mcn,
3151 .reset = scd_reset,
3152 .audio_ioctl = scd_audio_ioctl,
3153 .dev_ioctl = scd_dev_ioctl,
3154 .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
3155 CDC_SELECT_SPEED | CDC_MULTI_SESSION |
3156 CDC_MULTI_SESSION | CDC_MCN |
3157 CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
3158 CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
3159 .n_minors = 1,
3160};
3161
3162static struct cdrom_device_info scd_info = {
3163 .ops = &scd_dops,
3164 .speed = 2,
3165 .capacity = 1,
3166 .name = "cdu31a"
3167};
3168
3169static int scd_block_open(struct inode *inode, struct file *file)
3170{
3171 return cdrom_open(&scd_info, inode, file);
3172}
3173
3174static int scd_block_release(struct inode *inode, struct file *file)
3175{
3176 return cdrom_release(&scd_info, file);
3177}
3178
3179static int scd_block_ioctl(struct inode *inode, struct file *file,
3180 unsigned cmd, unsigned long arg)
3181{
3182 return cdrom_ioctl(file, &scd_info, inode, cmd, arg);
3183}
3184
3185static int scd_block_media_changed(struct gendisk *disk)
3186{
3187 return cdrom_media_changed(&scd_info);
3188}
3189
3190struct block_device_operations scd_bdops =
3191{
3192 .owner = THIS_MODULE,
3193 .open = scd_block_open,
3194 .release = scd_block_release,
3195 .ioctl = scd_block_ioctl,
3196 .media_changed = scd_block_media_changed,
3197};
3198
3199static struct gendisk *scd_gendisk;
3200
3201
3202static char *load_mech[] __initdata =
3203 { "caddy", "tray", "pop-up", "unknown" };
3204
3205static int __init
3206get_drive_configuration(unsigned short base_io,
3207 unsigned char res_reg[], unsigned int *res_size)
3208{
3209 unsigned long retry_count;
3210
3211
3212 if (!request_region(base_io, 4, "cdu31a"))
3213 return 0;
3214
3215
3216 cdu31a_port = base_io;
3217
3218
3219 sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
3220 sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
3221 sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
3222 sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
3223 sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
3224 sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
3225 sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
3226 sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
3227
3228
3229
3230
3231
3232
3233 if (read_status_register() != 0xff) {
3234
3235
3236
3237
3238 reset_drive();
3239 retry_count = jiffies + SONY_RESET_TIMEOUT;
3240 while (time_before(jiffies, retry_count)
3241 && (!is_attention())) {
3242 sony_sleep();
3243 }
3244
3245#if 0
3246
3247 if (!is_attention()) {
3248 res_reg[0] = 0x20;
3249 goto out_err;
3250 }
3251#endif
3252
3253
3254
3255
3256 do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
3257 NULL,
3258 0, (unsigned char *) res_reg, res_size);
3259 if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
3260 goto out_err;
3261 return 1;
3262 }
3263
3264
3265 res_reg[0] = 0x20;
3266out_err:
3267 release_region(cdu31a_port, 4);
3268 cdu31a_port = 0;
3269 return 0;
3270}
3271
3272#ifndef MODULE
3273
3274
3275
3276
3277
3278static int __init cdu31a_setup(char *strings)
3279{
3280 int ints[4];
3281
3282 (void) get_options(strings, ARRAY_SIZE(ints), ints);
3283
3284 if (ints[0] > 0) {
3285 cdu31a_port = ints[1];
3286 }
3287 if (ints[0] > 1) {
3288 cdu31a_irq = ints[2];
3289 }
3290 if ((strings != NULL) && (*strings != '\0')) {
3291 if (strcmp(strings, "PAS") == 0) {
3292 sony_pas_init = 1;
3293 } else {
3294 printk("CDU31A: Unknown interface type: %s\n",
3295 strings);
3296 }
3297 }
3298
3299 return 1;
3300}
3301
3302__setup("cdu31a=", cdu31a_setup);
3303
3304#endif
3305
3306
3307
3308
3309int __init cdu31a_init(void)
3310{
3311 struct s_sony_drive_config drive_config;
3312 struct gendisk *disk;
3313 int deficiency = 0;
3314 unsigned int res_size;
3315 char msg[255];
3316 char buf[40];
3317 int i;
3318 int tmp_irq;
3319
3320
3321
3322
3323
3324
3325
3326
3327 if (sony_pas_init) {
3328 outb(0xbc, 0x9a01);
3329 outb(0xe2, 0x9a01);
3330 }
3331
3332
3333 if (cdu31a_port == 0xffff)
3334 goto errout3;
3335
3336 if (cdu31a_port != 0) {
3337
3338 tmp_irq = cdu31a_irq;
3339 cdu31a_irq = 0;
3340 if (!get_drive_configuration(cdu31a_port,
3341 drive_config.exec_status,
3342 &res_size))
3343 goto errout3;
3344 cdu31a_irq = tmp_irq;
3345 } else {
3346 cdu31a_irq = 0;
3347 for (i = 0; cdu31a_addresses[i].base; i++) {
3348 if (get_drive_configuration(cdu31a_addresses[i].base,
3349 drive_config.exec_status,
3350 &res_size)) {
3351 cdu31a_irq = cdu31a_addresses[i].int_num;
3352 break;
3353 }
3354 }
3355 if (!cdu31a_port)
3356 goto errout3;
3357 }
3358
3359 if (register_blkdev(MAJOR_NR, "cdu31a"))
3360 goto errout2;
3361
3362 disk = alloc_disk(1);
3363 if (!disk)
3364 goto errout1;
3365 disk->major = MAJOR_NR;
3366 disk->first_minor = 0;
3367 sprintf(disk->disk_name, "cdu31a");
3368 disk->fops = &scd_bdops;
3369 disk->flags = GENHD_FL_CD;
3370
3371 if (SONY_HWC_DOUBLE_SPEED(drive_config))
3372 is_double_speed = 1;
3373
3374 tmp_irq = cdu31a_irq;
3375 cdu31a_irq = 0;
3376
3377 set_drive_params(sony_speed);
3378
3379 cdu31a_irq = tmp_irq;
3380
3381 if (cdu31a_irq > 0) {
3382 if (request_irq
3383 (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
3384 "cdu31a", NULL)) {
3385 printk
3386 ("Unable to grab IRQ%d for the CDU31A driver\n",
3387 cdu31a_irq);
3388 cdu31a_irq = 0;
3389 }
3390 }
3391
3392 sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
3393 drive_config.vendor_id,
3394 drive_config.product_id,
3395 drive_config.product_rev_level);
3396 sprintf(buf, " Capabilities: %s",
3397 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
3398 strcat(msg, buf);
3399 if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
3400 strcat(msg, ", audio");
3401 else
3402 deficiency |= CDC_PLAY_AUDIO;
3403 if (SONY_HWC_EJECT(drive_config))
3404 strcat(msg, ", eject");
3405 else
3406 deficiency |= CDC_OPEN_TRAY;
3407 if (SONY_HWC_LED_SUPPORT(drive_config))
3408 strcat(msg, ", LED");
3409 if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
3410 strcat(msg, ", elec. Vol");
3411 if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
3412 strcat(msg, ", sep. Vol");
3413 if (is_double_speed)
3414 strcat(msg, ", double speed");
3415 else
3416 deficiency |= CDC_SELECT_SPEED;
3417 if (cdu31a_irq > 0) {
3418 sprintf(buf, ", irq %d", cdu31a_irq);
3419 strcat(msg, buf);
3420 }
3421 strcat(msg, "\n");
3422
3423 is_a_cdu31a =
3424 strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
3425
3426 cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
3427 if (!cdu31a_queue)
3428 goto errout0;
3429
3430 init_timer(&cdu31a_abort_timer);
3431 cdu31a_abort_timer.function = handle_abort_timeout;
3432
3433 scd_info.mask = deficiency;
3434 scd_gendisk = disk;
3435 if (register_cdrom(&scd_info))
3436 goto err;
3437 disk->queue = cdu31a_queue;
3438 add_disk(disk);
3439
3440 disk_changed = 1;
3441 return (0);
3442
3443err:
3444 blk_cleanup_queue(cdu31a_queue);
3445errout0:
3446 if (cdu31a_irq)
3447 free_irq(cdu31a_irq, NULL);
3448 printk("Unable to register CDU-31a with Uniform cdrom driver\n");
3449 put_disk(disk);
3450errout1:
3451 if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
3452 printk("Can't unregister block device for cdu31a\n");
3453 }
3454errout2:
3455 release_region(cdu31a_port, 4);
3456errout3:
3457 return -EIO;
3458}
3459
3460
3461void __exit cdu31a_exit(void)
3462{
3463 del_gendisk(scd_gendisk);
3464 put_disk(scd_gendisk);
3465 if (unregister_cdrom(&scd_info)) {
3466 printk
3467 ("Can't unregister cdu31a from Uniform cdrom driver\n");
3468 return;
3469 }
3470 if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
3471 printk("Can't unregister cdu31a\n");
3472 return;
3473 }
3474
3475 blk_cleanup_queue(cdu31a_queue);
3476
3477 if (cdu31a_irq > 0)
3478 free_irq(cdu31a_irq, NULL);
3479
3480 release_region(cdu31a_port, 4);
3481 printk(KERN_INFO "cdu31a module released.\n");
3482}
3483
3484#ifdef MODULE
3485module_init(cdu31a_init);
3486#endif
3487module_exit(cdu31a_exit);
3488
3489MODULE_LICENSE("GPL");
3490MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
3491