This source file includes following definitions.
- sbpcd_dprintf
- sbpcd_dbg_ioctl
- sbp_sleep
- lba2msf
- bin2bcdx
- blk2msf
- make16
- make32
- swap_nibbles
- byt2bcd
- bcd2bin
- msf2blk
- msf2lba
- sta2err
- clr_cmdbuf
- mark_timeout
- flush_status
- CDi_stat_loop
- tst_DataReady
- tst_ResultReady
- tst_Attention
- ResponseInfo
- EvaluateStatus
- ResponseStatus
- xx_ReadStatus
- xx_ReadError
- cmd_out
- xx_Seek
- xx_SpinUp
- yy_SpinDown
- yy_SetSpeed
- xx_SetVolume
- GetStatus
- xy_DriveReset
- SetSpeed
- DriveReset
- xx_Pause_Resume
- yy_LockDoor
- yy_CloseTray
- xx_ReadSubQ
- xx_ModeSense
- xx_ModeSelect
- xx_TellVolume
- xx_ReadCapacity
- xx_ReadTocDescr
- xx_ReadTocEntry
- xx_ReadPacket
- convert_UPC
- xx_ReadUPC
- yy_CheckMultiSession
- yy_SubChanInfo
- check_datarate
- teac_reset
- look_for_drive
- find_teac_drives
- check_version
- switch_drive
- check_drives
- timewait
- obey_audio_state
- check_allowed1
- check_allowed2
- check_allowed3
- seek_pos_audio_end
- ReadToC
- DiskInfo
- prepare
- xx_PlayAudio
- sbp_status
- sbpcd_ioctl
- sbp_transfer
- DO_SBPCD_REQUEST
- sbp_read_cmd
- sbp_data
- sbpcd_open
- sbpcd_release
- sbpcd_setup
- config_spea
- SBPCD_INIT
- check_media_change
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 #define SBPCD_ISSUE 1
203
204 #include <linux/config.h>
205 #include <linux/errno.h>
206
207 #include <linux/sched.h>
208
209 #include <linux/timer.h>
210 #include <linux/fs.h>
211 #include <linux/kernel.h>
212 #include <linux/cdrom.h>
213 #include <linux/ioport.h>
214 #include <linux/major.h>
215 #include <linux/sbpcd.h>
216 #include <linux/string.h>
217 #include <asm/system.h>
218 #include <asm/io.h>
219 #include <asm/segment.h>
220 #include <stdarg.h>
221
222 #if !(SBPCD_ISSUE-1)
223 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
224 #endif
225 #if !(SBPCD_ISSUE-2)
226 #define MAJOR_NR MATSUSHITA_CDROM2_MAJOR
227 #endif
228 #if !(SBPCD_ISSUE-3)
229 #define MAJOR_NR MATSUSHITA_CDROM3_MAJOR
230 #endif
231 #if !(SBPCD_ISSUE-4)
232 #define MAJOR_NR MATSUSHITA_CDROM4_MAJOR
233 #endif
234
235 #include "blk.h"
236
237 #define VERSION "2.9 Eberhard Moenkeberg <emoenke@gwdg.de>"
238
239
240
241
242 #define MULTISESSION_BY_DRIVER 0
243
244
245
246 #define TEAC 0
247 #define JUKEBOX 1
248 #define EJECT 1
249 #define LONG_TIMING 0
250 #define MANY_SESSION 0
251 #undef FUTURE
252 #define WORKMAN 1
253 #define CDMKE
254
255 #undef XA_TEST1
256 #define XA_TEST2
257
258 #define TEST_UPC 0
259 #define SPEA_TEST 0
260 #define PRINTK_BUG 0
261 #define TEST_STI 0
262
263 #if 0
264 #define INLINE
265 #else
266 #define INLINE inline
267 #endif
268
269
270
271
272
273
274 #if !(SBPCD_ISSUE-1)
275 #define DO_SBPCD_REQUEST(a) do_sbpcd_request(a)
276 #define SBPCD_INIT(a,b) sbpcd_init(a,b)
277 #endif
278 #if !(SBPCD_ISSUE-2)
279 #define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a)
280 #define SBPCD_INIT(a,b) sbpcd2_init(a,b)
281 #endif
282 #if !(SBPCD_ISSUE-3)
283 #define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a)
284 #define SBPCD_INIT(a,b) sbpcd3_init(a,b)
285 #endif
286 #if !(SBPCD_ISSUE-4)
287 #define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a)
288 #define SBPCD_INIT(a,b) sbpcd4_init(a,b)
289 #endif
290
291 #if MANY_SESSION
292 #undef LONG_TIMING
293 #define LONG_TIMING 1
294 #endif
295
296 #if SBPCD_DIS_IRQ
297 #define SBPCD_CLI cli()
298 #define SBPCD_STI sti()
299 #else
300 #define SBPCD_CLI
301 #define SBPCD_STI
302 #endif SBPCD_DIS_IRQ
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 static int autoprobe[] =
321 {
322 CDROM_PORT, SBPRO,
323 0x230, 1,
324 0x300, 0,
325
326 0x250, 1,
327 0x260, 1,
328 0x320, 0,
329
330 0x338, 0,
331 0x340, 0,
332 0x360, 0,
333 0x270, 1,
334 0x670, 0,
335 0x690, 0,
336 0x330, 2,
337 0x320, 2,
338 0x340, 2,
339 0x350, 2,
340
341 0x630, 0,
342 0x650, 0,
343 #if 0
344
345
346
347 0x330, 0,
348 0x350, 0,
349 0x370, 0,
350 0x290, 1,
351 0x310, 0,
352 #endif
353 };
354
355 #define NUM_AUTOPROBE (sizeof(autoprobe) / sizeof(int))
356
357
358
359
360
361
362 #if !(SBPCD_ISSUE-1)
363 #ifdef CONFIG_SBPCD2
364 extern unsigned long sbpcd2_init(unsigned long, unsigned long);
365 #endif
366 #ifdef CONFIG_SBPCD3
367 extern unsigned long sbpcd3_init(unsigned long, unsigned long);
368 #endif
369 #ifdef CONFIG_SBPCD4
370 extern unsigned long sbpcd4_init(unsigned long, unsigned long);
371 #endif
372 #endif
373
374
375
376
377
378
379 static void sbp_read_cmd(void);
380 static int sbp_data(void);
381 static int cmd_out(void);
382 static int DiskInfo(void);
383 static int check_media_change(dev_t);
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 #if 1
421 static int sbpcd_debug = (1<<DBG_INF) |
422 (1<<DBG_WRN) |
423 (1<<DBG_MUL);
424 #else
425 static int sbpcd_debug = (1<<DBG_INF) |
426 (1<<DBG_TOC) |
427 (1<<DBG_MUL) |
428 (1<<DBG_LCS) |
429 (1<<DBG_TEA) |
430 (1<<DBG_UPC);
431 #endif
432 static unsigned char setup_done = 0;
433 static int sbpcd_ioaddr = CDROM_PORT;
434 static int sbpro_type = SBPRO;
435 static int CDo_command, CDo_reset;
436 static int CDo_sel_d_i, CDo_enable;
437 static int CDi_info, CDi_status, CDi_data;
438 static int MIXER_addr, MIXER_data;
439 static struct cdrom_msf msf;
440 static struct cdrom_ti ti;
441 static struct cdrom_tochdr tochdr;
442 static struct cdrom_tocentry tocentry;
443 static struct cdrom_subchnl SC;
444 static struct cdrom_volctrl volctrl;
445 static struct cdrom_read_audio read_audio;
446 static struct cdrom_multisession ms_info;
447
448 static char *str_sb = "SoundBlaster";
449 static char *str_lm = "LaserMate";
450 static char *str_sp = "SPEA";
451 char *type;
452 #if !(SBPCD_ISSUE-1)
453 static char *major_name="sbpcd";
454 #endif
455 #if !(SBPCD_ISSUE-2)
456 static char *major_name="sbpcd2";
457 #endif
458 #if !(SBPCD_ISSUE-3)
459 static char *major_name="sbpcd3";
460 #endif
461 #if !(SBPCD_ISSUE-4)
462 static char *major_name="sbpcd4";
463 #endif
464
465
466
467 #if FUTURE
468 static struct wait_queue *sbp_waitq = NULL;
469 #endif FUTURE
470
471
472
473 #define SBP_BUFFER_FRAMES 4
474 #define SBP_BUFFER_AUDIO_FRAMES 4
475
476
477
478 static u_char drive_family[]="CR-5";
479 static u_char lcs_family[]="LCS-7260";
480 static u_char drive_vendor[]="MATSHITA";
481
482 static u_int response_count=0;
483 static u_int flags_cmd_out;
484 static u_char cmd_type=0;
485 static u_char drvcmd[7];
486 static u_char infobuf[20];
487 static u_char xa_head_buf[CD_XA_HEAD];
488 static u_char xa_tail_buf[CD_XA_TAIL];
489
490 static u_char busy_data=0, busy_audio=0;
491 static u_char timed_out=0;
492 static u_int datarate= 1000000;
493 static u_int maxtim16=16000000;
494 static u_int maxtim04= 4000000;
495 static u_int maxtim02= 2000000;
496 static u_int maxtim_8= 30000;
497 #if LONG_TIMING
498 static u_int maxtim_data= 9000;
499 #else
500 static u_int maxtim_data= 3000;
501 #endif LONG_TIMING
502
503
504
505 static int ndrives=0;
506 static u_char drv_pattern[4]={ 0x80, 0x80, 0x80, 0x80 };
507
508
509
510
511 static int sbpcd_blocksizes[NR_SBPCD] = {0, };
512
513
514
515
516
517 static int d=0;
518
519 static struct {
520 char drv_minor;
521
522 char drive_model[9];
523 char firmware_version[4];
524 char f_eject;
525 u_char *sbp_buf;
526
527 int sbp_first_frame;
528 int sbp_last_frame;
529 int sbp_read_frames;
530 int sbp_current;
531
532 u_char mode;
533 u_char *aud_buf;
534
535 u_char drv_type;
536 u_char drv_options;
537 u_char status_byte;
538 u_char diskstate_flags;
539 u_char sense_byte;
540
541 u_char CD_changed;
542 u_char open_count;
543 u_char error_byte;
544
545 u_char f_multisession;
546 u_int lba_multi;
547 u_int last_redirect;
548
549 u_char audio_state;
550 u_int pos_audio_start;
551 u_int pos_audio_end;
552 char vol_chan0;
553 u_char vol_ctrl0;
554 char vol_chan1;
555 u_char vol_ctrl1;
556 #if 000
557 char vol_chan2;
558 u_char vol_ctrl2;
559 char vol_chan3;
560 u_char vol_ctrl3;
561 #endif 000
562
563 u_char SubQ_ctl_adr;
564 u_char SubQ_trk;
565 u_char SubQ_pnt_idx;
566 u_int SubQ_run_tot;
567 u_int SubQ_run_trk;
568 u_char SubQ_whatisthis;
569
570 u_char UPC_ctl_adr;
571 u_char UPC_buf[7];
572
573 int CDsize_blk;
574 int frame_size;
575 int CDsize_frm;
576
577 u_char xa_byte;
578 u_char n_first_track;
579 u_char n_last_track;
580 u_int size_msf;
581 u_int size_blk;
582
583 u_char TocEnt_nixbyte;
584 u_char TocEnt_ctl_adr;
585 u_char TocEnt_number;
586 u_char TocEnt_format;
587 u_int TocEnt_address;
588 u_char ored_ctl_adr;
589
590 struct {
591 u_char nixbyte;
592 u_char ctl_adr;
593 u_char number;
594 u_char format;
595 u_int address;
596 } TocBuffer[MAX_TRACKS+1];
597
598 int in_SpinUp;
599
600 } DriveStruct[NR_SBPCD];
601
602
603
604
605
606
607
608
609
610 static void sbpcd_dprintf(int level, char *fmt, ...)
611 {
612 char buff[256];
613 va_list args;
614 extern int vsprintf(char *buf, const char *fmt, va_list args);
615
616 if (! (sbpcd_debug & (1 << level))) return;
617
618 va_start(args, fmt);
619 vsprintf(buff, fmt, args);
620 va_end(args);
621 printk(buff);
622 #if PRINTK_BUG
623 sti();
624 #endif
625 }
626
627
628
629
630 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
631 {
632 int val;
633
634 val = get_fs_long((int *) arg);
635 switch(val)
636 {
637 case 0:
638 sbpcd_debug = 0;
639 break;
640
641 default:
642 if (val >= 128) sbpcd_debug &= ~(1 << (val - 128));
643 else sbpcd_debug |= (1 << val);
644 }
645 return(0);
646 }
647
648
649
650
651
652
653
654 static INLINE void sbp_sleep(u_int jifs)
655 {
656 current->state = TASK_INTERRUPTIBLE;
657 current->timeout = jiffies + jifs;
658 schedule();
659 }
660
661
662
663
664
665
666 static INLINE void lba2msf(int lba, u_char *msf)
667 {
668 lba += CD_BLOCK_OFFSET;
669 msf[0] = lba / (CD_SECS*CD_FRAMES);
670 lba %= CD_SECS*CD_FRAMES;
671 msf[1] = lba / CD_FRAMES;
672 msf[2] = lba % CD_FRAMES;
673 }
674
675
676
677
678
679 static INLINE void bin2bcdx(u_char *p)
680 {
681 *p=((*p/10)<<4)|(*p%10);
682 }
683
684 static INLINE u_int blk2msf(u_int blk)
685 {
686 MSF msf;
687 u_int mm;
688
689 msf.c[3] = 0;
690 msf.c[2] = (blk + CD_BLOCK_OFFSET) / (CD_SECS * CD_FRAMES);
691 mm = (blk + CD_BLOCK_OFFSET) % (CD_SECS * CD_FRAMES);
692 msf.c[1] = mm / CD_FRAMES;
693 msf.c[0] = mm % CD_FRAMES;
694 return (msf.n);
695 }
696
697 static INLINE u_int make16(u_char rh, u_char rl)
698 {
699 return ((rh<<8)|rl);
700 }
701
702 static INLINE u_int make32(u_int rh, u_int rl)
703 {
704 return ((rh<<16)|rl);
705 }
706
707 static INLINE u_char swap_nibbles(u_char i)
708 {
709 return ((i<<4)|(i>>4));
710 }
711
712 static INLINE u_char byt2bcd(u_char i)
713 {
714 return (((i/10)<<4)+i%10);
715 }
716
717 static INLINE u_char bcd2bin(u_char bcd)
718 {
719 return ((bcd>>4)*10+(bcd&0x0F));
720 }
721
722 static INLINE int msf2blk(int msfx)
723 {
724 MSF msf;
725 int i;
726
727 msf.n=msfx;
728 i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_BLOCK_OFFSET;
729 if (i<0) return (0);
730 return (i);
731 }
732
733
734
735
736 static INLINE int msf2lba(u_char *msf)
737 {
738 int i;
739
740 i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;
741 if (i<0) return (0);
742 return (i);
743 }
744
745
746 static int sta2err(int sta)
747 {
748 if (sta<=2) return (sta);
749 if (sta==0x05) return (-4);
750 if (sta==0x06) return (-6);
751 if (sta==0x0d) return (-6);
752 if (sta==0x0e) return (-3);
753 if (sta==0x14) return (-3);
754 if (sta==0x0c) return (-11);
755 if (sta==0x0f) return (-11);
756 if (sta==0x10) return (-11);
757 if (sta>=0x16) return (-12);
758 DriveStruct[d].CD_changed=0xFF;
759 if (sta==0x11) return (-15);
760 if (lcs_drive)
761 if (sta==0x12) return (-15);
762 return (-2);
763 }
764
765 static INLINE void clr_cmdbuf(void)
766 {
767 int i;
768
769 for (i=0;i<7;i++) drvcmd[i]=0;
770 cmd_type=0;
771 }
772
773 static void mark_timeout(unsigned long i)
774 {
775 timed_out=1;
776 DPRINTF((DBG_TIM,"SBPCD: timer expired.\n"));
777 }
778
779 static struct timer_list delay_timer = { NULL, NULL, 0, 0, mark_timeout};
780 #if 0
781 static struct timer_list data_timer = { NULL, NULL, 0, 0, mark_timeout};
782 static struct timer_list audio_timer = { NULL, NULL, 0, 0, mark_timeout};
783 #endif
784
785 static void flush_status(void)
786 {
787 #ifdef CDMKE
788 int i;
789
790 if (current == task[0])
791 for (i=maxtim02;i!=0;i--) inb(CDi_status);
792 else
793 {
794 sbp_sleep(150);
795 for (i=maxtim_data;i!=0;i--) inb(CDi_status);
796 }
797 #else
798 timed_out=0;
799 #if 0
800 del_timer(&delay_timer);
801 #endif
802 delay_timer.expires = 150;
803 add_timer(&delay_timer);
804 do { }
805 while (!timed_out);
806 #if 0
807 del_timer(&delay_timer);
808 #endif 0
809 inb(CDi_status);
810 #endif CDMKE
811 }
812
813 static int CDi_stat_loop(void)
814 {
815 int i,j;
816 u_long timeout;
817
818 if (current == task[0])
819 for(i=maxtim16;i!=0;i--)
820 {
821 j=inb(CDi_status);
822 if (!(j&s_not_data_ready)) return (j);
823 if (!(j&s_not_result_ready)) return (j);
824 if (!new_drive) if (j&s_attention) return (j);
825 }
826 else
827 for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; )
828 {
829 for ( ;i!=0;i--)
830 {
831 j=inb(CDi_status);
832 if (!(j&s_not_data_ready)) return (j);
833 if (!(j&s_not_result_ready)) return (j);
834 if (!new_drive) if (j&s_attention) return (j);
835 }
836 sbp_sleep(1);
837 i = 1;
838 }
839 DPRINTF((DBG_LCS,"SBPCD: CDi_stat_loop failed\n"));
840 return (-1);
841 }
842
843 #if TEAC
844
845 static int tst_DataReady(void)
846 {
847 int i;
848
849 i=inb(CDi_status);
850 if (i&s_not_data_ready) return (0);
851 return (1);
852 }
853
854 static int tst_ResultReady(void)
855 {
856 int i;
857
858 i=inb(CDi_status);
859 if (i&s_not_result_ready) return (0);
860 return (1);
861 }
862
863 static int tst_Attention(void)
864 {
865 int i;
866
867 i=inb(CDi_status);
868 if (i&s_attention) return (1);
869 return (0);
870 }
871
872 #endif TEAC
873
874 static int ResponseInfo(void)
875 {
876 int i,j, st=0;
877 u_long timeout;
878
879 DPRINTF((DBG_000,"SBPCD: ResponseInfo entered.\n"));
880 if (current == task[0])
881 for (i=0;i<response_count;i++)
882 {
883 for (j=maxtim_8;j!=0;j--)
884 {
885 st=inb(CDi_status);
886 if (!(st&s_not_result_ready)) break;
887 }
888 if (j==0)
889 {
890 DPRINTF((DBG_SEQ,"SBPCD: ResponseInfo: not_result_ready (got %d of %d bytes).\n", i, response_count));
891 return (-1);
892 }
893 infobuf[i]=inb(CDi_info);
894 }
895 else
896 {
897 for (i=0, timeout = jiffies + 100; i < response_count; i++)
898 {
899 for (j=maxtim_data; ; )
900 {
901 for ( ;j!=0;j-- )
902 {
903 st=inb(CDi_status);
904 if (!(st&s_not_result_ready)) break;
905 }
906 if (j != 0 || timeout <= jiffies) break;
907 sbp_sleep(0);
908 j = 1;
909 }
910 if (timeout <= jiffies) return (-1);
911 infobuf[i]=inb(CDi_info);
912 }
913 }
914 DPRINTF((DBG_000,"SBPCD: ResponseInfo: done.\n"));
915 return (0);
916 }
917
918 static int EvaluateStatus(int st)
919 {
920 if (old_drive)
921 {
922 DriveStruct[d].status_byte=0;
923 if (st&p_caddin_old) DriveStruct[d].status_byte |= p_door_closed|p_caddy_in;
924 if (st&p_spinning) DriveStruct[d].status_byte |= p_spinning;
925 if (st&p_check) DriveStruct[d].status_byte |= p_check;
926 if (st&p_busy_old) DriveStruct[d].status_byte |= p_busy_new;
927 if (st&p_disk_ok) DriveStruct[d].status_byte |= p_disk_ok;
928 }
929 else if (lcs_drive)
930 {
931 DriveStruct[d].status_byte=0;
932 if (st&p_caddin_old) DriveStruct[d].status_byte |= p_disk_ok|p_caddy_in;
933 if (st&p_spinning) DriveStruct[d].status_byte |= p_spinning;
934 if (st&p_check) DriveStruct[d].status_byte |= p_check;
935 if (st&p_busy_old) DriveStruct[d].status_byte |= p_busy_new;
936 if (st&p_lcs_door_closed) DriveStruct[d].status_byte |= p_door_closed;
937 if (st&p_lcs_door_locked) DriveStruct[d].status_byte |= p_door_locked;
938 }
939 else
940 {
941 DriveStruct[d].status_byte=st;
942 st=p_success_old;
943 }
944 return (st);
945 }
946
947 static int ResponseStatus(void)
948 {
949 int i,j;
950 u_long timeout;
951
952 DPRINTF((DBG_STA,"SBPCD: doing ResponseStatus...\n"));
953
954 if (current == task[0])
955 {
956 if (flags_cmd_out & f_respo3) j = maxtim_8;
957 else if (flags_cmd_out&f_respo2) j=maxtim16;
958 else j=maxtim04;
959 for (;j!=0;j--)
960 {
961 i=inb(CDi_status);
962 if (!(i&s_not_result_ready)) break;
963 }
964 }
965 else
966 {
967 if (flags_cmd_out & f_respo3) timeout = jiffies;
968 else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600;
969 else timeout = jiffies + 400;
970 j=maxtim_8;
971 do
972 {
973 for ( ;j!=0;j--)
974 {
975 i=inb(CDi_status);
976 if (!(i&s_not_result_ready)) break;
977 }
978 if (j != 0 || timeout <= jiffies) break;
979 sbp_sleep(0);
980 j = 1;
981 }
982 while (1);
983 }
984 if (j==0)
985 { if ((flags_cmd_out & f_respo3) == 0)
986 DPRINTF((DBG_STA,"SBPCD: ResponseStatus: timeout.\n"));
987 EvaluateStatus(0);
988 return (-1);
989 }
990 i=inb(CDi_info);
991 DPRINTF((DBG_STA,"SBPCD: ResponseStatus: response %2X.\n", i));
992 i=EvaluateStatus(i);
993 return (i);
994 }
995
996 static void xx_ReadStatus(void)
997 {
998 int i;
999
1000 DPRINTF((DBG_STA,"SBPCD: giving xx_ReadStatus command\n"));
1001 SBPCD_CLI;
1002 if (new_drive) OUT(CDo_command,0x05);
1003 else OUT(CDo_command,0x81);
1004 if (!old_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
1005 SBPCD_STI;
1006 }
1007
1008 static int xx_ReadError(void)
1009 {
1010 int i;
1011
1012 clr_cmdbuf();
1013 DPRINTF((DBG_ERR,"SBPCD: giving xx_ReadError command.\n"));
1014 if (new_drive)
1015 {
1016 drvcmd[0]=0x82;
1017 response_count=8;
1018 flags_cmd_out=f_putcmd|f_ResponseStatus;
1019 }
1020 else
1021 {
1022 drvcmd[0]=0x82;
1023 response_count=6;
1024 if (lcs_drive)
1025 flags_cmd_out=f_putcmd;
1026 else
1027 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
1028 }
1029 i=cmd_out();
1030 DriveStruct[d].error_byte=0;
1031 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
1032 if (i<0) return (i);
1033 if (old_drive) i=1;
1034 else i=2;
1035 DriveStruct[d].error_byte=infobuf[i];
1036 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DriveStruct[d].error_byte,DriveStruct[d].error_byte));
1037 i=sta2err(infobuf[i]);
1038 return (i);
1039 }
1040
1041 static int cmd_out(void)
1042 {
1043 int i=0;
1044
1045 if (flags_cmd_out&f_putcmd)
1046 {
1047 DPRINTF((DBG_CMD,"SBPCD: cmd_out: put"));
1048 for (i=0;i<7;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i]));
1049 DPRINTF((DBG_CMD,"\n"));
1050
1051 SBPCD_CLI;
1052 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
1053 SBPCD_STI;
1054 }
1055 if (response_count!=0)
1056 {
1057 if (cmd_type!=0)
1058 {
1059 if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
1060 DPRINTF((DBG_INF,"SBPCD: misleaded to try ResponseData.\n"));
1061 if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
1062 return (-22);
1063 }
1064 else i=ResponseInfo();
1065 if (i<0) return (-9);
1066 }
1067 if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to CDi_stat_loop.\n"));
1068 if (flags_cmd_out&f_lopsta)
1069 {
1070 i=CDi_stat_loop();
1071 if ((i<0)||!(i&s_attention)) return (-9);
1072 }
1073 if (!(flags_cmd_out&f_getsta)) goto LOC_229;
1074
1075 LOC_228:
1076 if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadStatus.\n"));
1077 xx_ReadStatus();
1078
1079 LOC_229:
1080 if (flags_cmd_out&f_ResponseStatus)
1081 {
1082 if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to ResponseStatus.\n"));
1083 i=ResponseStatus();
1084
1085 if (i<0) return (-9);
1086 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
1087 {
1088 if (!st_check)
1089 {
1090 if (flags_cmd_out&f_bit1) if (i&p_success_old) goto LOC_232;
1091 if (!(flags_cmd_out&f_wait_if_busy)) goto LOC_228;
1092 if (!st_busy) goto LOC_228;
1093 }
1094 }
1095 }
1096 LOC_232:
1097 if (!(flags_cmd_out&f_obey_p_check)) return (0);
1098 if (!st_check) return (0);
1099 if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadError.\n"));
1100 i=xx_ReadError();
1101 if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to cmd_out OK.\n"));
1102 return (i);
1103 }
1104
1105 static int xx_Seek(u_int pos, char f_blk_msf)
1106 {
1107 int i;
1108
1109 clr_cmdbuf();
1110 if (f_blk_msf>1) return (-3);
1111 if (old_drive)
1112 {
1113 if (f_blk_msf==1) pos=msf2blk(pos);
1114 drvcmd[2]=(pos>>16)&0x00FF;
1115 drvcmd[3]=(pos>>8)&0x00FF;
1116 drvcmd[4]=pos&0x00FF;
1117 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1118 f_ResponseStatus | f_obey_p_check | f_bit1;
1119 }
1120 else
1121 {
1122 if (f_blk_msf==0) pos=blk2msf(pos);
1123 drvcmd[1]=(pos>>16)&0x00FF;
1124 drvcmd[2]=(pos>>8)&0x00FF;
1125 drvcmd[3]=pos&0x00FF;
1126 if (lcs_drive)
1127 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1128 else
1129 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1130 }
1131 drvcmd[0]=0x01;
1132 response_count=0;
1133 i=cmd_out();
1134 return (i);
1135 }
1136
1137 static int xx_SpinUp(void)
1138 {
1139 int i;
1140
1141 DPRINTF((DBG_SPI,"SBPCD: SpinUp.\n"));
1142 DriveStruct[d].in_SpinUp = 1;
1143 clr_cmdbuf();
1144 if (!new_drive)
1145 {
1146 drvcmd[0]=0x05;
1147 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1148 f_ResponseStatus|f_obey_p_check|f_bit1;
1149 }
1150 else
1151 {
1152 drvcmd[0]=0x02;
1153 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1154 }
1155 response_count=0;
1156 i=cmd_out();
1157 DriveStruct[d].in_SpinUp = 0;
1158 return (i);
1159 }
1160
1161 static int yy_SpinDown(void)
1162 {
1163 int i;
1164
1165 if (old_drive) return (-3);
1166 clr_cmdbuf();
1167 if (new_drive)
1168 {
1169 drvcmd[0]=0x06;
1170 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1171 response_count=0;
1172 }
1173 else
1174 {
1175 drvcmd[0]=0x0D;
1176 drvcmd[1]=1;
1177 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1178 response_count=0;
1179 }
1180 i=cmd_out();
1181 return (i);
1182 }
1183
1184 static int yy_SetSpeed(u_char speed, u_char x1, u_char x2)
1185 {
1186 int i;
1187
1188 if (!new_drive) return (-3);
1189 clr_cmdbuf();
1190 drvcmd[0]=0x09;
1191 drvcmd[1]=0x03;
1192 drvcmd[2]=speed;
1193 drvcmd[3]=x1;
1194 drvcmd[4]=x2;
1195 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1196 response_count=0;
1197 i=cmd_out();
1198 return (i);
1199 }
1200
1201 static int xx_SetVolume(void)
1202 {
1203 int i;
1204 u_char channel0,channel1,volume0,volume1;
1205 u_char control0,value0,control1,value1;
1206
1207 DriveStruct[d].diskstate_flags &= ~volume_bit;
1208 clr_cmdbuf();
1209 channel0=DriveStruct[d].vol_chan0;
1210 volume0=DriveStruct[d].vol_ctrl0;
1211 channel1=control1=DriveStruct[d].vol_chan1;
1212 volume1=value1=DriveStruct[d].vol_ctrl1;
1213 control0=value0=0;
1214
1215 if (((DriveStruct[d].drv_options&sax_a)!=0)&&(DriveStruct[d].drv_type>=drv_211))
1216 {
1217 if ((volume0!=0)&&(volume1==0))
1218 {
1219 volume1=volume0;
1220 channel1=channel0;
1221 }
1222 else if ((volume0==0)&&(volume1!=0))
1223 {
1224 volume0=volume1;
1225 channel0=channel1;
1226 }
1227 }
1228 if (channel0>1)
1229 {
1230 channel0=0;
1231 volume0=0;
1232 }
1233 if (channel1>1)
1234 {
1235 channel1=1;
1236 volume1=0;
1237 }
1238
1239 if (new_drive)
1240 {
1241 control0=channel0+1;
1242 control1=channel1+1;
1243 value0=(volume0>volume1)?volume0:volume1;
1244 value1=value0;
1245 if (volume0==0) control0=0;
1246 if (volume1==0) control1=0;
1247 drvcmd[0]=0x09;
1248 drvcmd[1]=0x05;
1249 drvcmd[3]=control0;
1250 drvcmd[4]=value0;
1251 drvcmd[5]=control1;
1252 drvcmd[6]=value1;
1253 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1254 }
1255 else if (lcs_drive)
1256 {
1257 if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
1258 if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
1259 if (volume0|volume1) value0=0x80;
1260 drvcmd[0]=0x84;
1261 drvcmd[1]=0x03;
1262 drvcmd[4]=control0;
1263 drvcmd[5]=value0;
1264 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1265 }
1266 else
1267 {
1268 if (DriveStruct[d].drv_type>=drv_300)
1269 {
1270 control0=volume0&0xFC;
1271 value0=volume1&0xFC;
1272 if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
1273 if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
1274 if (channel0!=0) control0 |= 0x01;
1275 if (channel1==1) value0 |= 0x01;
1276 }
1277 else
1278 {
1279 value0=(volume0>volume1)?volume0:volume1;
1280 if (DriveStruct[d].drv_type<drv_211)
1281 {
1282 if (channel0!=0)
1283 {
1284 i=channel1;
1285 channel1=channel0;
1286 channel0=i;
1287 i=volume1;
1288 volume1=volume0;
1289 volume0=i;
1290 }
1291 if (channel0==channel1)
1292 {
1293 if (channel0==0)
1294 {
1295 channel1=1;
1296 volume1=0;
1297 volume0=value0;
1298 }
1299 else
1300 {
1301 channel0=0;
1302 volume0=0;
1303 volume1=value0;
1304 }
1305 }
1306 }
1307
1308 if ((volume0!=0)&&(volume1!=0))
1309 {
1310 if (volume0==0xFF) volume1=0xFF;
1311 else if (volume1==0xFF) volume0=0xFF;
1312 }
1313 else if (DriveStruct[d].drv_type<drv_201) volume0=volume1=value0;
1314
1315 if (DriveStruct[d].drv_type>=drv_201)
1316 {
1317 if (volume0==0) control0 |= 0x80;
1318 if (volume1==0) control0 |= 0x40;
1319 }
1320 if (DriveStruct[d].drv_type>=drv_211)
1321 {
1322 if (channel0!=0) control0 |= 0x20;
1323 if (channel1!=1) control0 |= 0x10;
1324 }
1325 }
1326 drvcmd[0]=0x84;
1327 drvcmd[1]=0x83;
1328 drvcmd[4]=control0;
1329 drvcmd[5]=value0;
1330 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1331 }
1332
1333 response_count=0;
1334 i=cmd_out();
1335 if (i>0) return (i);
1336 DriveStruct[d].diskstate_flags |= volume_bit;
1337 return (0);
1338 }
1339
1340 static int GetStatus(void)
1341 {
1342 int i;
1343
1344 flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1345 response_count=0;
1346 cmd_type=0;
1347 i=cmd_out();
1348 return (i);
1349 }
1350
1351 static int xy_DriveReset(void)
1352 {
1353 int i;
1354
1355 DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
1356 if (!new_drive) OUT(CDo_reset,0x00);
1357 else
1358 {
1359 clr_cmdbuf();
1360 drvcmd[0]=0x0A;
1361 flags_cmd_out=f_putcmd;
1362 response_count=0;
1363 i=cmd_out();
1364 }
1365 if (lcs_drive) sbp_sleep(500);
1366 else sbp_sleep(100);
1367 flush_status();
1368 i=GetStatus();
1369 if (i>=0) return -1;
1370 if (DriveStruct[d].error_byte!=aud_12) return -1;
1371 return (0);
1372 }
1373
1374 static int SetSpeed(void)
1375 {
1376 int i, speed;
1377
1378 if (!(DriveStruct[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
1379 speed=speed_auto;
1380 if (!(DriveStruct[d].drv_options&speed_auto))
1381 {
1382 speed |= speed_300;
1383 if (!(DriveStruct[d].drv_options&speed_300)) speed=0;
1384 }
1385 i=yy_SetSpeed(speed,0,0);
1386 return (i);
1387 }
1388
1389 static int DriveReset(void)
1390 {
1391 int i;
1392
1393 i=xy_DriveReset();
1394 if (i<0) return (-2);
1395 do
1396 {
1397 i=GetStatus();
1398 if ((i<0)&&(i!=-15)) return (-2);
1399 if (!st_caddy_in) break;
1400 }
1401 while (!st_diskok);
1402 #if 000
1403 DriveStruct[d].CD_changed=1;
1404 #endif
1405 if ((st_door_closed) && (st_caddy_in))
1406 {
1407 i=DiskInfo();
1408 if (i<0) return (-2);
1409 }
1410 return (0);
1411 }
1412
1413 static int xx_Pause_Resume(int pau_res)
1414 {
1415 int i;
1416
1417 clr_cmdbuf();
1418 if (new_drive)
1419 {
1420 drvcmd[0]=0x0D;
1421 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1422 }
1423 else
1424 {
1425 drvcmd[0]=0x8D;
1426 if (lcs_drive)
1427 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
1428 f_obey_p_check|f_bit1;
1429 else
1430 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
1431 f_obey_p_check;
1432 }
1433 if (pau_res!=1) drvcmd[1]=0x80;
1434 response_count=0;
1435 i=cmd_out();
1436 return (i);
1437 }
1438
1439 static int yy_LockDoor(char lock)
1440 {
1441 int i;
1442
1443 if (old_drive) return (0);
1444 DPRINTF((DBG_LCK,"SBPCD: yy_LockDoor: %d (drive %d)\n", lock, d));
1445 DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d before\n", st_door_locked));
1446 clr_cmdbuf();
1447 if (new_drive)
1448 {
1449 drvcmd[0]=0x0C;
1450 if (lock==1) drvcmd[1]=0x01;
1451 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1452 response_count=0;
1453 }
1454 else
1455 {
1456 drvcmd[0]=0x0E;
1457 if (lock==1) drvcmd[1]=0x01;
1458 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1459 response_count=0;
1460 }
1461 i=cmd_out();
1462 DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d after\n", st_door_locked));
1463 return (i);
1464 }
1465
1466 static int yy_CloseTray(void)
1467 {
1468 int i;
1469
1470 if (old_drive) return (0);
1471 DPRINTF((DBG_LCK,"SBPCD: yy_CloseTray (drive %d)\n", d));
1472 DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d before\n", st_door_closed));
1473
1474 clr_cmdbuf();
1475 if (new_drive)
1476 {
1477 drvcmd[0]=0x07;
1478 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1479 }
1480 else
1481 {
1482 drvcmd[0]=0x0D;
1483 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1484 f_ResponseStatus|f_obey_p_check|f_bit1;
1485 }
1486 response_count=0;
1487 i=cmd_out();
1488 DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d after\n", st_door_closed));
1489 return (i);
1490 }
1491
1492 static int xx_ReadSubQ(void)
1493 {
1494 int i,j;
1495
1496 DriveStruct[d].diskstate_flags &= ~subq_bit;
1497 for (j=255;j>0;j--)
1498 {
1499 clr_cmdbuf();
1500 if (new_drive)
1501 {
1502 drvcmd[0]=0x87;
1503 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1504 response_count=11;
1505 }
1506 else
1507 {
1508 drvcmd[0]=0x89;
1509 drvcmd[1]=0x02;
1510 if (lcs_drive)
1511 flags_cmd_out=f_putcmd;
1512 else
1513 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1514 response_count=13;
1515 }
1516 i=cmd_out();
1517 if (i<0) return (i);
1518 DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:"));
1519 for (i=0;i<(new_drive?11:13);i++)
1520 {
1521 DPRINTF((DBG_SQ," %02X", infobuf[i]));
1522 }
1523 DPRINTF((DBG_SQ,"\n"));
1524 if (infobuf[0]!=0) break;
1525 if ((!st_spinning) || (j==1))
1526 {
1527 DriveStruct[d].SubQ_ctl_adr=DriveStruct[d].SubQ_trk=DriveStruct[d].SubQ_pnt_idx=DriveStruct[d].SubQ_whatisthis=0;
1528 DriveStruct[d].SubQ_run_tot=DriveStruct[d].SubQ_run_trk=0;
1529 return (0);
1530 }
1531 }
1532 DriveStruct[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
1533 DriveStruct[d].SubQ_trk=byt2bcd(infobuf[2]);
1534 DriveStruct[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
1535 i=4;
1536 if (!new_drive) i=5;
1537 DriveStruct[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1538 i=7;
1539 if (!new_drive) i=9;
1540 DriveStruct[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1541 DriveStruct[d].SubQ_whatisthis=infobuf[i+3];
1542 DriveStruct[d].diskstate_flags |= subq_bit;
1543 return (0);
1544 }
1545
1546 static int xx_ModeSense(void)
1547 {
1548 int i;
1549
1550 DriveStruct[d].diskstate_flags &= ~frame_size_bit;
1551 clr_cmdbuf();
1552 if (new_drive)
1553 {
1554 drvcmd[0]=0x84;
1555 drvcmd[1]=0x00;
1556 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1557 response_count=5;
1558 }
1559 else
1560 {
1561 drvcmd[0]=0x85;
1562 drvcmd[1]=0x00;
1563 if (lcs_drive)
1564 flags_cmd_out=f_putcmd;
1565 else
1566 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1567 response_count=2;
1568 }
1569 i=cmd_out();
1570 if (i<0) return (i);
1571 i=0;
1572 if (new_drive) DriveStruct[d].sense_byte=infobuf[i++];
1573 DriveStruct[d].frame_size=make16(infobuf[i],infobuf[i+1]);
1574
1575 DPRINTF((DBG_XA,"SBPCD: xx_ModeSense: "));
1576 for (i=0;i<(new_drive?5:2);i++)
1577 {
1578 DPRINTF((DBG_XA,"%02X ", infobuf[i]));
1579 }
1580 DPRINTF((DBG_XA,"\n"));
1581
1582 DriveStruct[d].diskstate_flags |= frame_size_bit;
1583 return (0);
1584 }
1585
1586
1587 static int xx_ModeSelect(int framesize)
1588 {
1589 int i;
1590
1591 DriveStruct[d].diskstate_flags &= ~frame_size_bit;
1592 clr_cmdbuf();
1593 DriveStruct[d].frame_size=framesize;
1594 if (framesize==CD_FRAMESIZE_RAW) DriveStruct[d].sense_byte=0x82;
1595 else DriveStruct[d].sense_byte=0x00;
1596
1597 DPRINTF((DBG_XA,"SBPCD: xx_ModeSelect: %02X %04X\n",
1598 DriveStruct[d].sense_byte, DriveStruct[d].frame_size));
1599
1600 if (new_drive)
1601 {
1602 drvcmd[0]=0x09;
1603 drvcmd[1]=0x00;
1604 drvcmd[2]=DriveStruct[d].sense_byte;
1605 drvcmd[3]=(DriveStruct[d].frame_size>>8)&0xFF;
1606 drvcmd[4]=DriveStruct[d].frame_size&0xFF;
1607 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1608 }
1609 else
1610 {
1611 drvcmd[0]=0x84;
1612 drvcmd[1]=0x00;
1613 drvcmd[2]=(DriveStruct[d].frame_size>>8)&0xFF;
1614 drvcmd[3]=DriveStruct[d].frame_size&0xFF;
1615 drvcmd[4]=0x00;
1616 if(lcs_drive)
1617 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
1618 else
1619 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1620 }
1621 response_count=0;
1622 i=cmd_out();
1623 if (i<0) return (i);
1624 DriveStruct[d].diskstate_flags |= frame_size_bit;
1625 return (0);
1626 }
1627
1628 #if 0000
1629 static int xx_TellVolume(void)
1630 {
1631 int i;
1632 u_char switches;
1633 u_char chan0,vol0,chan1,vol1;
1634
1635 DriveStruct[d].diskstate_flags &= ~volume_bit;
1636 clr_cmdbuf();
1637 if (new_drive)
1638 {
1639 drvcmd[0]=0x84;
1640 drvcmd[1]=0x05;
1641 response_count=5;
1642 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1643 }
1644 else
1645 {
1646 drvcmd[0]=0x85;
1647 drvcmd[1]=0x03;
1648 response_count=2;
1649 if(lcs_drive)
1650 flags_cmd_out=f_putcmd;
1651 else
1652 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1653 }
1654 i=cmd_out();
1655 if (i<0) return (i);
1656 if (new_drive)
1657 {
1658 chan0=infobuf[1]&0x0F;
1659 vol0=infobuf[2];
1660 chan1=infobuf[3]&0x0F;
1661 vol1=infobuf[4];
1662 if (chan0==0)
1663 {
1664 chan0=1;
1665 vol0=0;
1666 }
1667 if (chan1==0)
1668 {
1669 chan1=2;
1670 vol1=0;
1671 }
1672 chan0 >>= 1;
1673 chan1 >>= 1;
1674 }
1675 else if (lcs_drive)
1676 {
1677 chan0=0;
1678 chan1=1;
1679 vol0=vol1=infobuf[1];
1680 switches=infobuf[0];
1681 if ((switches&0x80)!=0) chan0=1;
1682 if ((switches&0x40)!=0) chan1=0;
1683 }
1684 else
1685 {
1686 chan0=0;
1687 chan1=1;
1688 vol0=vol1=infobuf[1];
1689 if (DriveStruct[d].drv_type>=drv_201)
1690 {
1691 if (DriveStruct[d].drv_type<drv_300)
1692 {
1693 switches=infobuf[0];
1694 if ((switches&0x80)!=0) vol0=0;
1695 if ((switches&0x40)!=0) vol1=0;
1696 if (DriveStruct[d].drv_type>=drv_211)
1697 {
1698 if ((switches&0x20)!=0) chan0=1;
1699 if ((switches&0x10)!=0) chan1=0;
1700 }
1701 }
1702 else
1703 {
1704 vol0=infobuf[0];
1705 if ((vol0&0x01)!=0) chan0=1;
1706 if ((vol1&0x01)==0) chan1=0;
1707 vol0 &= 0xFC;
1708 vol1 &= 0xFC;
1709 if (vol0!=0) vol0 += 3;
1710 if (vol1!=0) vol1 += 3;
1711 }
1712 }
1713 }
1714 DriveStruct[d].vol_chan0=chan0;
1715 DriveStruct[d].vol_ctrl0=vol0;
1716 DriveStruct[d].vol_chan1=chan1;
1717 DriveStruct[d].vol_ctrl1=vol1;
1718 if (!lcs_drive)
1719 {
1720 DriveStruct[d].vol_chan2=2;
1721 DriveStruct[d].vol_ctrl2=0xFF;
1722 DriveStruct[d].vol_chan3=3;
1723 DriveStruct[d].vol_ctrl3=0xFF;
1724 }
1725 DriveStruct[d].diskstate_flags |= volume_bit;
1726 return (0);
1727 }
1728 #endif
1729
1730 static int xx_ReadCapacity(void)
1731 {
1732 int i;
1733
1734 DriveStruct[d].diskstate_flags &= ~cd_size_bit;
1735 clr_cmdbuf();
1736 if (new_drive)
1737 {
1738 drvcmd[0]=0x85;
1739 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1740 }
1741 else
1742 {
1743 drvcmd[0]=0x88;
1744 if(lcs_drive)
1745 flags_cmd_out=f_putcmd;
1746 else
1747 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1748 }
1749 response_count=5;
1750 i=cmd_out();
1751 if (i<0) return (i);
1752 DriveStruct[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
1753 if (new_drive) DriveStruct[d].CDsize_blk=msf2blk(DriveStruct[d].CDsize_blk);
1754 DriveStruct[d].CDsize_frm = (DriveStruct[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
1755 DriveStruct[d].CDsize_blk += 151;
1756 DriveStruct[d].diskstate_flags |= cd_size_bit;
1757 return (0);
1758 }
1759
1760 static int xx_ReadTocDescr(void)
1761 {
1762 int i;
1763
1764 DriveStruct[d].diskstate_flags &= ~toc_bit;
1765 clr_cmdbuf();
1766 if (new_drive)
1767 {
1768 drvcmd[0]=0x8B;
1769 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1770 }
1771 else
1772 {
1773 drvcmd[0]=0x8B;
1774 if(lcs_drive)
1775 flags_cmd_out=f_putcmd;
1776 else
1777 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1778 }
1779 response_count=6;
1780 i=cmd_out();
1781 if (i<0) return (i);
1782 DriveStruct[d].xa_byte=infobuf[0];
1783 DriveStruct[d].n_first_track=infobuf[1];
1784 DriveStruct[d].n_last_track=infobuf[2];
1785 DriveStruct[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
1786 DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
1787 DriveStruct[d].diskstate_flags |= toc_bit;
1788 DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
1789 DriveStruct[d].xa_byte,DriveStruct[d].n_first_track,DriveStruct[d].n_last_track,DriveStruct[d].size_msf));
1790 return (0);
1791 }
1792
1793 static int xx_ReadTocEntry(int num)
1794 {
1795 int i;
1796
1797 clr_cmdbuf();
1798 if (new_drive)
1799 {
1800 drvcmd[0]=0x8C;
1801 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1802 }
1803 else
1804 {
1805 drvcmd[0]=0x8C;
1806 drvcmd[1]=0x02;
1807 if(lcs_drive)
1808 flags_cmd_out=f_putcmd;
1809 else
1810 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1811 }
1812 drvcmd[2]=num;
1813 response_count=8;
1814 i=cmd_out();
1815 if (i<0) return (i);
1816 DriveStruct[d].TocEnt_nixbyte=infobuf[0];
1817 DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
1818 DriveStruct[d].TocEnt_number=infobuf[2];
1819 DriveStruct[d].TocEnt_format=infobuf[3];
1820 if (new_drive) i=4;
1821 else i=5;
1822 DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]),
1823 make16(infobuf[i+1],infobuf[i+2]));
1824 DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
1825 DriveStruct[d].TocEnt_nixbyte, DriveStruct[d].TocEnt_ctl_adr,
1826 DriveStruct[d].TocEnt_number, DriveStruct[d].TocEnt_format,
1827 DriveStruct[d].TocEnt_address));
1828 return (0);
1829 }
1830
1831 static int xx_ReadPacket(void)
1832 {
1833 int i;
1834
1835 clr_cmdbuf();
1836 drvcmd[0]=0x8E;
1837 drvcmd[1]=response_count;
1838 if(lcs_drive)
1839 flags_cmd_out=f_putcmd;
1840 else
1841 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1842 i=cmd_out();
1843 return (i);
1844 }
1845
1846 static int convert_UPC(u_char *p)
1847 {
1848 int i;
1849
1850 p++;
1851 if (!new_drive) p[13]=0;
1852 for (i=0;i<7;i++)
1853 {
1854 if (new_drive) DriveStruct[d].UPC_buf[i]=swap_nibbles(*p++);
1855 else
1856 {
1857 DriveStruct[d].UPC_buf[i]=((*p++)<<4)&0xFF;
1858 DriveStruct[d].UPC_buf[i] |= *p++;
1859 }
1860 }
1861 DriveStruct[d].UPC_buf[6] &= 0xF0;
1862 return (0);
1863 }
1864
1865 static int xx_ReadUPC(void)
1866 {
1867 int i;
1868 #if TEST_UPC
1869 int block, checksum;
1870 #endif TEST_UPC
1871
1872 DriveStruct[d].diskstate_flags &= ~upc_bit;
1873 #if TEST_UPC
1874 for (block=CD_BLOCK_OFFSET+1;block<CD_BLOCK_OFFSET+200;block++)
1875 {
1876 #endif TEST_UPC
1877 clr_cmdbuf();
1878 if (new_drive)
1879 {
1880 drvcmd[0]=0x88;
1881 #if TEST_UPC
1882 drvcmd[1]=(block>>16)&0xFF;
1883 drvcmd[2]=(block>>8)&0xFF;
1884 drvcmd[3]=block&0xFF;
1885 #endif TEST_UPC
1886 response_count=8;
1887 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1888 }
1889 else
1890 {
1891 drvcmd[0]=0x08;
1892 #if TEST_UPC
1893 drvcmd[2]=(block>>16)&0xFF;
1894 drvcmd[3]=(block>>8)&0xFF;
1895 drvcmd[4]=block&0xFF;
1896 #endif TEST_UPC
1897 response_count=0;
1898 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1899 }
1900 i=cmd_out();
1901 if (i<0) return (i);
1902 if (!new_drive)
1903 {
1904 response_count=16;
1905 if (lcs_drive) flags_cmd_out=f_putcmd;
1906 i=xx_ReadPacket();
1907 if (i<0) return (i);
1908 }
1909 #if TEST_UPC
1910 checksum=0;
1911 #endif TEST_UPC
1912 DPRINTF((DBG_UPC,"SBPCD: UPC info: "));
1913 for (i=0;i<(new_drive?8:16);i++)
1914 {
1915 #if TEST_UPC
1916 checksum |= infobuf[i];
1917 #endif TEST_UPC
1918 DPRINTF((DBG_UPC,"%02X ", infobuf[i]));
1919 }
1920 DPRINTF((DBG_UPC,"\n"));
1921 #if TEST_UPC
1922 if ((checksum&0x7F)!=0) break;
1923 }
1924 #endif TEST_UPC
1925 DriveStruct[d].UPC_ctl_adr=0;
1926 if (new_drive) i=0;
1927 else i=2;
1928 if ((infobuf[i]&0x80)!=0)
1929 {
1930 convert_UPC(&infobuf[i]);
1931 DriveStruct[d].UPC_ctl_adr = (DriveStruct[d].TocEnt_ctl_adr & 0xF0) | 0x02;
1932 }
1933
1934 DPRINTF((DBG_UPC,"SBPCD: UPC code: "));
1935 DPRINTF((DBG_UPC,"(%02X) ", DriveStruct[d].UPC_ctl_adr));
1936 for (i=0;i<7;i++)
1937 {
1938 DPRINTF((DBG_UPC,"%02X ", DriveStruct[d].UPC_buf[i]));
1939 }
1940 DPRINTF((DBG_UPC,"\n"));
1941
1942 DriveStruct[d].diskstate_flags |= upc_bit;
1943 return (0);
1944 }
1945
1946 static int yy_CheckMultiSession(void)
1947 {
1948 int i;
1949
1950 DriveStruct[d].f_multisession=0;
1951 clr_cmdbuf();
1952 DriveStruct[d].lba_multi=0;
1953 if (new_drive)
1954 {
1955 drvcmd[0]=0x8D;
1956 response_count=6;
1957 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1958 i=cmd_out();
1959 if (i<0) return (i);
1960 if ((infobuf[0]&0x80)!=0)
1961 {
1962 DriveStruct[d].f_multisession=1;
1963 DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
1964 make16(infobuf[2],infobuf[3])));
1965 DriveStruct[d].last_redirect=19;
1966
1967
1968
1969
1970 DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X (%d)\n",
1971 infobuf[0], infobuf[1], infobuf[2],
1972 infobuf[3], infobuf[4], infobuf[5],
1973 DriveStruct[d].lba_multi));
1974 }
1975 }
1976 else if (lcs_drive)
1977 {
1978 drvcmd[0]=0x8C;
1979 drvcmd[1]=3;
1980 drvcmd[2]=1;
1981 response_count=8;
1982 flags_cmd_out=f_putcmd;
1983 i=cmd_out();
1984 if (i<0) return (i);
1985 DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),
1986 make16(infobuf[6],infobuf[7])));
1987 DPRINTF((DBG_MUL,"SBPCD: MultiSession Info: %02X %02X %02X %02X %02X %02X %02X %02X (%d)\n",
1988 infobuf[0], infobuf[1], infobuf[2], infobuf[3],
1989 infobuf[4], infobuf[5], infobuf[6], infobuf[7],
1990 DriveStruct[d].lba_multi));
1991 if (DriveStruct[d].lba_multi>200)
1992 {
1993 DPRINTF((DBG_MUL,"SBPCD: MultiSession base: %06X\n", DriveStruct[d].lba_multi));
1994 DriveStruct[d].f_multisession=1;
1995 DriveStruct[d].last_redirect=19;
1996
1997
1998
1999
2000 }
2001 }
2002 return (0);
2003 }
2004
2005 #if FUTURE
2006 static int yy_SubChanInfo(int frame, int count, u_char *buffer)
2007
2008 {
2009 int i;
2010
2011 if (!new_drive) return (-ENOSYS);
2012 #if 0
2013 if (DriveStruct[d].audio_state!=audio_playing) return (-ENODATA);
2014 #endif
2015 clr_cmdbuf();
2016 drvcmd[0]=0x11;
2017 drvcmd[1]=(frame>>16)&0xFF;
2018 drvcmd[2]=(frame>>8)&0xFF;
2019 drvcmd[3]=frame&0xFF;
2020 drvcmd[5]=(count>>8)&0xFF;
2021 drvcmd[6]=count&0xFF;
2022 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2023 cmd_type=READ_SC;
2024 DriveStruct[d].frame_size=CD_FRAMESIZE_SUB;
2025 i=cmd_out();
2026 return (i);
2027 }
2028 #endif FUTURE
2029
2030 static void check_datarate(void)
2031 {
2032 #ifdef CDMKE
2033 int i=0;
2034
2035 DPRINTF((DBG_IOX,"SBPCD: check_datarate entered.\n"));
2036 datarate=0;
2037 #if TEST_STI
2038 for (i=0;i<=1000;i++) printk(".");
2039 #endif
2040
2041 #if 0
2042 del_timer(&delay_timer);
2043 #endif
2044 delay_timer.expires = 110;
2045 timed_out=0;
2046 add_timer(&delay_timer);
2047 DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
2048 do
2049 {
2050 i=inb(CDi_status);
2051 datarate++;
2052 #if 00000
2053 if (datarate>0x0FFFFFFF) break;
2054 #endif 00000
2055 }
2056 while (!timed_out);
2057 #if 0
2058 del_timer(&delay_timer);
2059 #endif 0
2060 DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
2061 if (datarate<65536) datarate=65536;
2062
2063 maxtim16=datarate*16;
2064 maxtim04=datarate*4;
2065 maxtim02=datarate*2;
2066 maxtim_8=datarate/32;
2067 #if LONG_TIMING
2068 maxtim_data=datarate/100;
2069 #else
2070 maxtim_data=datarate/300;
2071 #endif LONG_TIMING
2072 DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
2073 maxtim_8, maxtim_data));
2074 #endif CDMKE
2075 }
2076
2077 #if TEAC
2078
2079 static void teac_reset(int drv_id)
2080 {
2081 int i;
2082 #define CMD_TEAC_RESET 0xc0
2083
2084 OUT(CDo_sel_d_i,0);
2085 OUT(CDo_enable,drv_id);
2086 OUT(CDo_command,CMD_TEAC_RESET);
2087 for (i=0;i<9;i++) OUT(CDo_command,0);
2088 DPRINTF((DBG_TEA,"SBPCD: TEAC soft reset.\n"));
2089 sbp_sleep(100);
2090 }
2091
2092 static int look_for_drive(int drv_id)
2093 {
2094 int i;
2095 if (sbpro_type!=1) teac_reset(drv_id);
2096
2097 OUT(CDo_enable,drv_id);
2098 OUT(CDo_sel_d_i,0);
2099 i=inb(CDi_status);
2100 if (i&s_not_result_ready) return (-1);
2101 i=inb(CDi_info);
2102 DPRINTF((DBG_TEA,"SBPCD: TEAC look_for_drive: %02X.\n",i));
2103 if (i!=0x55) return (-2);
2104 return (1);
2105 }
2106
2107 static int find_teac_drives(void)
2108 {
2109 int i, j, found;
2110
2111 found=0;
2112 for (i=0;i<4;i++)
2113 {
2114 j=look_for_drive(i);
2115 if (j<1) continue;
2116 found++;
2117 DPRINTF((DBG_TEA,"SBPCD: TEAC drive (id=%d) found.\n",i));
2118 }
2119 return (found);
2120 }
2121
2122 #endif TEAC
2123
2124 static int check_version(void)
2125 {
2126 int i, j;
2127
2128 DPRINTF((DBG_INI,"SBPCD: check_version entered.\n"));
2129
2130 clr_cmdbuf();
2131 drvcmd[0]=0x82;
2132 response_count=9;
2133 flags_cmd_out=f_putcmd;
2134 i=cmd_out();
2135 if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_82 returns %d (ok anyway).\n",i));
2136
2137
2138 clr_cmdbuf();
2139 for (i=0;i<12;i++) infobuf[i]=0;
2140 drvcmd[0]=0x83;
2141 response_count=12;
2142 flags_cmd_out=f_putcmd;
2143 i=cmd_out();
2144 if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i));
2145
2146 DPRINTF((DBG_INI,"SBPCD: infobuf = \""));
2147 for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i]));
2148 DPRINTF((DBG_INI,"\"\n"));
2149
2150 DriveStruct[d].drv_type=0;
2151 for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break;
2152 if (i==4)
2153 {
2154 DriveStruct[d].drive_model[0]=infobuf[i++];
2155 DriveStruct[d].drive_model[1]=infobuf[i++];
2156 DriveStruct[d].drive_model[2]='-';
2157 DriveStruct[d].drive_model[3]='x';
2158 DriveStruct[d].drive_model[4]=0;
2159 DriveStruct[d].drv_type=drv_new;
2160 }
2161 if (!DriveStruct[d].drv_type)
2162 {
2163 for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
2164 if (i==8)
2165 {
2166 DriveStruct[d].drive_model[0]='2';
2167 DriveStruct[d].drive_model[1]='x';
2168 DriveStruct[d].drive_model[2]='-';
2169 DriveStruct[d].drive_model[3]='x';
2170 DriveStruct[d].drive_model[4]=0;
2171 DriveStruct[d].drv_type=drv_old;
2172 }
2173 }
2174 if (!DriveStruct[d].drv_type)
2175 {
2176 for (i=0;i<8;i++) if (infobuf[i]!=lcs_family[i]) break;
2177 if (i==8)
2178 {
2179 for (j=0;j<8;j++)
2180 DriveStruct[d].drive_model[j]=infobuf[j];
2181 DriveStruct[d].drive_model[8]=0;
2182 DriveStruct[d].drv_type=drv_lcs;
2183 }
2184 }
2185 if (!DriveStruct[d].drv_type)
2186 {
2187 DPRINTF((DBG_INI,"SBPCD: check_version: error.\n"));
2188 return (-1);
2189 }
2190 for (j=0;j<4;j++) DriveStruct[d].firmware_version[j]=infobuf[i+j];
2191 if (lcs_drive)
2192 {
2193 DriveStruct[d].drv_type=drv_260;
2194 if ((DriveStruct[d].firmware_version[0]!='A') ||
2195 (DriveStruct[d].firmware_version[1]!='4') ||
2196 (DriveStruct[d].firmware_version[2]!='F') ||
2197 (DriveStruct[d].firmware_version[3]!='4'))
2198 printk("SBPCD: please mail me your LCS-7260 DOS driver.\n");
2199 }
2200 else
2201 {
2202 j = (DriveStruct[d].firmware_version[0] & 0x0F) * 100 +
2203 (DriveStruct[d].firmware_version[2] & 0x0F) *10 +
2204 (DriveStruct[d].firmware_version[3] & 0x0F);
2205 if (new_drive)
2206 {
2207 if (j<100) DriveStruct[d].drv_type=drv_099;
2208 else DriveStruct[d].drv_type=drv_100;
2209 }
2210 else if (j<200) DriveStruct[d].drv_type=drv_199;
2211 else if (j<201) DriveStruct[d].drv_type=drv_200;
2212 else if (j<210) DriveStruct[d].drv_type=drv_201;
2213 else if (j<211) DriveStruct[d].drv_type=drv_210;
2214 else if (j<300) DriveStruct[d].drv_type=drv_211;
2215 else DriveStruct[d].drv_type=drv_300;
2216 }
2217 DPRINTF((DBG_LCS,"SBPCD: drive type %02X\n",DriveStruct[d].drv_type));
2218 DPRINTF((DBG_INI,"SBPCD: check_version done.\n"));
2219 return (0);
2220 }
2221
2222 static int switch_drive(int num)
2223 {
2224 int i;
2225
2226 d=num;
2227
2228 i=num;
2229 if (sbpro_type==1) i=(i&0x01)<<1|(i&0x02)>>1;
2230 OUT(CDo_enable,i);
2231 DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DriveStruct[d].drv_minor));
2232 return (0);
2233 }
2234
2235
2236
2237
2238 static int check_drives(void)
2239 {
2240 int i, j;
2241 char *printk_header="";
2242
2243 DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
2244
2245 ndrives=0;
2246 for (j=0;j<NR_SBPCD;j++)
2247 {
2248 DriveStruct[j].drv_minor=j;
2249 switch_drive(j);
2250 DPRINTF((DBG_ID,"SBPCD: check_drives: drive %d activated.\n",j));
2251 i=check_version();
2252 DPRINTF((DBG_ID,"SBPCD: check_version returns %d.\n",i));
2253 if (i>=0)
2254 {
2255 ndrives++;
2256 DriveStruct[d].drv_options=drv_pattern[j];
2257 if (!new_drive)
2258 DriveStruct[d].drv_options&=~(speed_auto|speed_300|speed_150);
2259 if (lcs_drive)
2260 {
2261 printk("%sDrive %d: %s (%.4s)\n", printk_header,
2262 DriveStruct[d].drv_minor,
2263 DriveStruct[d].drive_model,
2264 DriveStruct[d].firmware_version);
2265 }
2266 else
2267 {
2268 printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header,
2269 DriveStruct[d].drv_minor,
2270 drive_family,
2271 DriveStruct[d].drive_model,
2272 DriveStruct[d].firmware_version);
2273 }
2274 printk_header=" - ";
2275 }
2276 else DriveStruct[d].drv_minor=-1;
2277 }
2278 if (ndrives==0) return (-1);
2279 return (0);
2280 }
2281
2282 #if 000
2283 static void timewait(void)
2284 {
2285 int i;
2286 for (i=0; i<65500; i++);
2287 }
2288 #endif 000
2289
2290 #if FUTURE
2291
2292
2293
2294 static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
2295 {
2296 switch (audio_state)
2297 {
2298 case aud_11:
2299 case audx11:
2300 switch (func)
2301 {
2302 case cmd_07:
2303 case cmd_0d:
2304 case cmd_0e:
2305 case cmd_0c:
2306 return (1);
2307 case cmd_03:
2308 switch (subfunc)
2309
2310 {
2311 case cxi_00:
2312 case cxi_06:
2313 case cxi_09:
2314 return (1);
2315 default:
2316 return (ERROR15);
2317 }
2318 return (1);
2319 default:
2320 return (ERROR15);
2321 }
2322 return (1);
2323 case aud_12:
2324 case audx12:
2325 return (1);
2326 default:
2327 return (2);
2328 }
2329 }
2330 #endif FUTURE
2331
2332
2333
2334
2335
2336
2337 static int check_allowed1(u_char func1, u_char func2)
2338 {
2339 #if 000
2340 if (func1==ioctl_o) return (0);
2341 if (func1==read_long) return (-1);
2342 if (func1==read_long_prefetch) return (-1);
2343 if (func1==seek) return (-1);
2344 if (func1==audio_play) return (-1);
2345 if (func1==audio_pause) return (-1);
2346 if (func1==audio_resume) return (-1);
2347 if (func1!=ioctl_i) return (0);
2348 if (func2==tell_SubQ_run_tot) return (-1);
2349 if (func2==tell_cdsize) return (-1);
2350 if (func2==tell_TocDescrip) return (-1);
2351 if (func2==tell_TocEntry) return (-1);
2352 if (func2==tell_subQ_info) return (-1);
2353 if (new_drive) if (func2==tell_SubChanInfo) return (-1);
2354 if (func2==tell_UPC) return (-1);
2355 #else
2356 return (0);
2357 #endif 000
2358 }
2359
2360 static int check_allowed2(u_char func1, u_char func2)
2361 {
2362 #if 000
2363 if (func1==read_long) return (-1);
2364 if (func1==read_long_prefetch) return (-1);
2365 if (func1==seek) return (-1);
2366 if (func1==audio_play) return (-1);
2367 if (func1!=ioctl_o) return (0);
2368 if (new_drive)
2369 {
2370 if (func2==EjectDisk) return (-1);
2371 if (func2==CloseTray) return (-1);
2372 }
2373 #else
2374 return (0);
2375 #endif 000
2376 }
2377
2378 static int check_allowed3(u_char func1, u_char func2)
2379 {
2380 #if 000
2381 if (func1==ioctl_i)
2382 {
2383 if (func2==tell_address) return (0);
2384 if (func2==tell_capabiliti) return (0);
2385 if (func2==tell_CD_changed) return (0);
2386 if (!new_drive) if (func2==tell_SubChanInfo) return (0);
2387 return (-1);
2388 }
2389 if (func1==ioctl_o)
2390 {
2391 if (func2==DriveReset) return (0);
2392 if (!new_drive)
2393 {
2394 if (func2==EjectDisk) return (0);
2395 if (func2==LockDoor) return (0);
2396 if (func2==CloseTray) return (0);
2397 }
2398 return (-1);
2399 }
2400 if (func1==flush_input) return (-1);
2401 if (func1==read_long) return (-1);
2402 if (func1==read_long_prefetch) return (-1);
2403 if (func1==seek) return (-1);
2404 if (func1==audio_play) return (-1);
2405 if (func1==audio_pause) return (-1);
2406 if (func1==audio_resume) return (-1);
2407 #else
2408 return (0);
2409 #endif 000
2410 }
2411
2412 static int seek_pos_audio_end(void)
2413 {
2414 int i;
2415
2416 i=msf2blk(DriveStruct[d].pos_audio_end)-1;
2417 if (i<0) return (-1);
2418 i=xx_Seek(i,0);
2419 return (i);
2420 }
2421
2422 static int ReadToC(void)
2423 {
2424 int i, j;
2425 DriveStruct[d].diskstate_flags &= ~toc_bit;
2426 DriveStruct[d].ored_ctl_adr=0;
2427 for (j=DriveStruct[d].n_first_track;j<=DriveStruct[d].n_last_track;j++)
2428 {
2429 i=xx_ReadTocEntry(j);
2430 if (i<0) return (i);
2431 DriveStruct[d].TocBuffer[j].nixbyte=DriveStruct[d].TocEnt_nixbyte;
2432 DriveStruct[d].TocBuffer[j].ctl_adr=DriveStruct[d].TocEnt_ctl_adr;
2433 DriveStruct[d].TocBuffer[j].number=DriveStruct[d].TocEnt_number;
2434 DriveStruct[d].TocBuffer[j].format=DriveStruct[d].TocEnt_format;
2435 DriveStruct[d].TocBuffer[j].address=DriveStruct[d].TocEnt_address;
2436 DriveStruct[d].ored_ctl_adr |= DriveStruct[d].TocEnt_ctl_adr;
2437 }
2438
2439 DriveStruct[d].TocBuffer[j].nixbyte=0;
2440 DriveStruct[d].TocBuffer[j].ctl_adr=0;
2441 DriveStruct[d].TocBuffer[j].number=CDROM_LEADOUT;
2442 DriveStruct[d].TocBuffer[j].format=0;
2443 DriveStruct[d].TocBuffer[j].address=DriveStruct[d].size_msf;
2444
2445 DriveStruct[d].diskstate_flags |= toc_bit;
2446 return (0);
2447 }
2448
2449 static int DiskInfo(void)
2450 {
2451 int i, j;
2452
2453 DriveStruct[d].mode=READ_M1;
2454
2455 #undef LOOP_COUNT
2456 #define LOOP_COUNT 20
2457
2458 for (j=1;j<LOOP_COUNT;j++)
2459 {
2460 i=SetSpeed();
2461 if (i<0)
2462 {
2463 DPRINTF((DBG_INF,"SBPCD: DiskInfo: SetSpeed returns %d\n", i));
2464 continue;
2465 }
2466 i=xx_ModeSense();
2467 if (i<0)
2468 {
2469 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ModeSense returns %d\n", i));
2470 continue;
2471 }
2472 i=xx_ReadCapacity();
2473 if (i>=0) break;
2474 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadCapacity #%d returns %d\n", j, i));
2475 i=DriveReset();
2476 }
2477 if (j==LOOP_COUNT) return (-2);
2478
2479 i=xx_ReadTocDescr();
2480 if (i<0)
2481 {
2482 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i));
2483 return (i);
2484 }
2485 i=ReadToC();
2486 if (i<0)
2487 {
2488 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i));
2489 return (i);
2490 }
2491 i=yy_CheckMultiSession();
2492 if (i<0)
2493 {
2494 DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i));
2495 return (i);
2496 }
2497 i=xx_ReadTocEntry(DriveStruct[d].n_first_track);
2498 if (i<0)
2499 {
2500 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadTocEntry(1) returns %d\n", i));
2501 return (i);
2502 }
2503 i=xx_ReadUPC();
2504 if (i<0)
2505 {
2506 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadUPC returns %d\n", i));
2507 return (i);
2508 }
2509 #ifdef XA_TEST2
2510 if ((!new_drive) && (DriveStruct[d].xa_byte==0x20))
2511 {
2512 xx_ModeSelect(CD_FRAMESIZE_XA);
2513 xx_ModeSense();
2514 }
2515 #endif XA_TEST2
2516
2517 return (0);
2518 }
2519
2520
2521
2522
2523
2524 static int prepare(u_char func, u_char subfunc)
2525 {
2526 int i;
2527
2528 if (!new_drive)
2529 {
2530 i=inb(CDi_status);
2531 if (i&s_attention) GetStatus();
2532 }
2533 else GetStatus();
2534 if (DriveStruct[d].CD_changed==0xFF)
2535 {
2536 #if MANY_SESSION
2537 #else
2538 DriveStruct[d].diskstate_flags=0;
2539 #endif MANY_SESSION
2540 DriveStruct[d].audio_state=0;
2541 if (!st_diskok)
2542 {
2543 i=check_allowed1(func,subfunc);
2544 if (i<0) return (-2);
2545 }
2546 else
2547 {
2548 i=check_allowed3(func,subfunc);
2549 if (i<0)
2550 {
2551 DriveStruct[d].CD_changed=1;
2552 return (-15);
2553 }
2554 }
2555 }
2556 else
2557 {
2558 if (!st_diskok)
2559 {
2560 #if MANY_SESSION
2561 #else
2562 DriveStruct[d].diskstate_flags=0;
2563 #endif MANY_SESSION
2564 DriveStruct[d].audio_state=0;
2565 i=check_allowed1(func,subfunc);
2566 if (i<0) return (-2);
2567 }
2568 else
2569 {
2570 if (st_busy)
2571 {
2572 if (DriveStruct[d].audio_state!=audio_pausing)
2573 {
2574 i=check_allowed2(func,subfunc);
2575 if (i<0) return (-2);
2576 }
2577 }
2578 else
2579 {
2580 if (DriveStruct[d].audio_state==audio_playing) seek_pos_audio_end();
2581 DriveStruct[d].audio_state=0;
2582 }
2583 if (!frame_size_valid)
2584 {
2585 i=DiskInfo();
2586 if (i<0)
2587 {
2588 #if MANY_SESSION
2589 #else
2590 DriveStruct[d].diskstate_flags=0;
2591 #endif MANY_SESSION
2592 DriveStruct[d].audio_state=0;
2593 i=check_allowed1(func,subfunc);
2594 if (i<0) return (-2);
2595 }
2596 }
2597 }
2598 }
2599 return (0);
2600 }
2601
2602 static int xx_PlayAudio(int pos_audio_start,int pos_audio_end)
2603 {
2604 int i, n;
2605
2606 if (DriveStruct[d].audio_state==audio_playing) return (-EINVAL);
2607 clr_cmdbuf();
2608 if (lcs_drive)
2609 {
2610 drvcmd[0]=0x0A;
2611 i=msf2blk(pos_audio_start);
2612 n=msf2blk(pos_audio_end)+1-i;
2613 drvcmd[1]=(i>>16)&0x00FF;
2614 drvcmd[2]=(i>>8)&0x00FF;
2615 drvcmd[3]=i&0x00FF;
2616 drvcmd[4]=(n>>16)&0x00FF;
2617 drvcmd[5]=(n>>8)&0x00FF;
2618 drvcmd[6]=n&0x00FF;
2619 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2620 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2621 }
2622 else
2623 {
2624 if (new_drive)
2625 {
2626 drvcmd[0]=0x0E;
2627 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
2628 f_obey_p_check | f_wait_if_busy;
2629 }
2630 else
2631 {
2632 drvcmd[0]=0x0B;
2633 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2634 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2635 }
2636 drvcmd[1]=(pos_audio_start>>16)&0x00FF;
2637 drvcmd[2]=(pos_audio_start>>8)&0x00FF;
2638 drvcmd[3]=pos_audio_start&0x00FF;
2639 drvcmd[4]=(pos_audio_end>>16)&0x00FF;
2640 drvcmd[5]=(pos_audio_end>>8)&0x00FF;
2641 drvcmd[6]=pos_audio_end&0x00FF;
2642 }
2643 response_count=0;
2644 i=cmd_out();
2645 return (i);
2646 }
2647
2648
2649
2650
2651
2652
2653 static int sbp_status(void)
2654 {
2655 int st;
2656
2657 st=ResponseStatus();
2658 if (st<0)
2659 {
2660 DPRINTF((DBG_INF,"SBPCD: sbp_status: timeout.\n"));
2661 return (0);
2662 }
2663
2664 if (!st_spinning) DPRINTF((DBG_SPI,"SBPCD: motor got off - ignoring.\n"));
2665
2666 if (st_check)
2667 {
2668 DPRINTF((DBG_INF,"SBPCD: st_check detected - retrying.\n"));
2669 return (0);
2670 }
2671 if (!st_door_closed)
2672 {
2673 DPRINTF((DBG_INF,"SBPCD: door is open - retrying.\n"));
2674 return (0);
2675 }
2676 if (!st_caddy_in)
2677 {
2678 DPRINTF((DBG_INF,"SBPCD: disk removed - retrying.\n"));
2679 return (0);
2680 }
2681 if (!st_diskok)
2682 {
2683 DPRINTF((DBG_INF,"SBPCD: !st_diskok detected - retrying.\n"));
2684 return (0);
2685 }
2686 if (st_busy)
2687 {
2688 DPRINTF((DBG_INF,"SBPCD: st_busy detected - retrying.\n"));
2689 return (0);
2690 }
2691 return (1);
2692 }
2693
2694
2695
2696
2697
2698
2699
2700 static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
2701 u_long arg)
2702 {
2703 int i, st;
2704 unsigned int *p_lba;
2705
2706 DPRINTF((DBG_IO2,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
2707 MINOR(inode->i_rdev), cmd, arg));
2708 if (!inode) return (-EINVAL);
2709 i=MINOR(inode->i_rdev);
2710 if ( (i<0) || (i>=NR_SBPCD) )
2711 {
2712 printk("SBPCD: ioctl: bad device: %d\n", i);
2713 return (-ENODEV);
2714 }
2715 switch_drive(i);
2716
2717 st=GetStatus();
2718 if (st<0) return (-EIO);
2719
2720 if (!toc_valid)
2721 {
2722 i=DiskInfo();
2723 if (i<0) return (-EIO);
2724 }
2725
2726 DPRINTF((DBG_IO2,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
2727 switch (cmd)
2728 {
2729 case DDIOCSDBG:
2730 if (! suser()) return (-EPERM);
2731 i = verify_area(VERIFY_READ, (int *) arg, sizeof(int));
2732 if (i>=0) i=sbpcd_dbg_ioctl(arg,1);
2733 return (i);
2734
2735 case CDROMPAUSE:
2736 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPAUSE entered.\n"));
2737
2738
2739
2740
2741 switch (DriveStruct[d].audio_state)
2742 {
2743 case audio_playing:
2744 if (lcs_drive) i=xx_ReadSubQ();
2745 else i=xx_Pause_Resume(1);
2746 if (i<0) return (-EIO);
2747 if (lcs_drive) i=xx_Pause_Resume(1);
2748 else i=xx_ReadSubQ();
2749 if (i<0) return (-EIO);
2750 DriveStruct[d].pos_audio_start=DriveStruct[d].SubQ_run_tot;
2751 DriveStruct[d].audio_state=audio_pausing;
2752 return (0);
2753 case audio_pausing:
2754 i=xx_Seek(DriveStruct[d].pos_audio_start,1);
2755 if (i<0) return (-EIO);
2756 return (0);
2757 default:
2758 return (-EINVAL);
2759 }
2760
2761 case CDROMRESUME:
2762 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMRESUME entered.\n"));
2763
2764
2765
2766 if (DriveStruct[d].audio_state!=audio_pausing) return -EINVAL;
2767 if (lcs_drive)
2768 i=xx_PlayAudio(DriveStruct[d].pos_audio_start,
2769 DriveStruct[d].pos_audio_end);
2770 else i=xx_Pause_Resume(3);
2771 if (i<0) return (-EIO);
2772 DriveStruct[d].audio_state=audio_playing;
2773 return (0);
2774
2775 case CDROMPLAYMSF:
2776 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYMSF entered.\n"));
2777 if (DriveStruct[d].audio_state==audio_playing)
2778 {
2779 i=xx_Pause_Resume(1);
2780 if (i<0) return (-EIO);
2781 i=xx_ReadSubQ();
2782 if (i<0) return (-EIO);
2783 DriveStruct[d].pos_audio_start=DriveStruct[d].SubQ_run_tot;
2784 i=xx_Seek(DriveStruct[d].pos_audio_start,1);
2785 }
2786 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_msf));
2787 if (st) return (st);
2788 memcpy_fromfs(&msf, (void *) arg, sizeof(struct cdrom_msf));
2789
2790 DriveStruct[d].pos_audio_start = (msf.cdmsf_min0<<16) |
2791 (msf.cdmsf_sec0<<8) |
2792 msf.cdmsf_frame0;
2793 DriveStruct[d].pos_audio_end = (msf.cdmsf_min1<<16) |
2794 (msf.cdmsf_sec1<<8) |
2795 msf.cdmsf_frame1;
2796 DPRINTF((DBG_IOX,"SBPCD: ioctl: CDROMPLAYMSF %08X %08X\n",
2797 DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end));
2798 i=xx_PlayAudio(DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end);
2799 DPRINTF((DBG_IOC,"SBPCD: ioctl: xx_PlayAudio returns %d\n",i));
2800 #if 0
2801 if (i<0) return (-EIO);
2802 #endif 0
2803 DriveStruct[d].audio_state=audio_playing;
2804 return (0);
2805
2806 case CDROMPLAYTRKIND:
2807 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYTRKIND entered.\n"));
2808 if (DriveStruct[d].audio_state==audio_playing)
2809 {
2810 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: already audio_playing.\n"));
2811 return (0);
2812 return (-EINVAL);
2813 }
2814 st=verify_area(VERIFY_READ,(void *) arg,sizeof(struct cdrom_ti));
2815 if (st<0)
2816 {
2817 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: verify_area error.\n"));
2818 return (st);
2819 }
2820 memcpy_fromfs(&ti,(void *) arg,sizeof(struct cdrom_ti));
2821 DPRINTF((DBG_IOX,"SBPCD: ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
2822 ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1));
2823 if (ti.cdti_trk0<DriveStruct[d].n_first_track) return (-EINVAL);
2824 if (ti.cdti_trk0>DriveStruct[d].n_last_track) return (-EINVAL);
2825 if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
2826 if (ti.cdti_trk1>DriveStruct[d].n_last_track) ti.cdti_trk1=DriveStruct[d].n_last_track;
2827 DriveStruct[d].pos_audio_start=DriveStruct[d].TocBuffer[ti.cdti_trk0].address;
2828 DriveStruct[d].pos_audio_end=DriveStruct[d].TocBuffer[ti.cdti_trk1+1].address;
2829 i=xx_PlayAudio(DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end);
2830 #if 0
2831 if (i<0) return (-EIO);
2832 #endif 0
2833 DriveStruct[d].audio_state=audio_playing;
2834 return (0);
2835
2836 case CDROMREADTOCHDR:
2837 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCHDR entered.\n"));
2838 tochdr.cdth_trk0=DriveStruct[d].n_first_track;
2839 tochdr.cdth_trk1=DriveStruct[d].n_last_track;
2840 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_tochdr));
2841 if (st) return (st);
2842 memcpy_tofs((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
2843 return (0);
2844
2845 case CDROMREADTOCENTRY:
2846 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCENTRY entered.\n"));
2847 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_tocentry));
2848 if (st) return (st);
2849 memcpy_fromfs(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
2850 i=tocentry.cdte_track;
2851 if (i==CDROM_LEADOUT) i=DriveStruct[d].n_last_track+1;
2852 else if (i<DriveStruct[d].n_first_track||i>DriveStruct[d].n_last_track) return (-EINVAL);
2853 tocentry.cdte_adr=DriveStruct[d].TocBuffer[i].ctl_adr&0x0F;
2854 tocentry.cdte_ctrl=(DriveStruct[d].TocBuffer[i].ctl_adr>>4)&0x0F;
2855 tocentry.cdte_datamode=DriveStruct[d].TocBuffer[i].format;
2856 if (tocentry.cdte_format==CDROM_MSF)
2857 { tocentry.cdte_addr.msf.minute=(DriveStruct[d].TocBuffer[i].address>>16)&0x00FF;
2858 tocentry.cdte_addr.msf.second=(DriveStruct[d].TocBuffer[i].address>>8)&0x00FF;
2859 tocentry.cdte_addr.msf.frame=DriveStruct[d].TocBuffer[i].address&0x00FF;
2860 }
2861 else if (tocentry.cdte_format==CDROM_LBA)
2862 tocentry.cdte_addr.lba=msf2blk(DriveStruct[d].TocBuffer[i].address);
2863 else return (-EINVAL);
2864 st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_tocentry));
2865 if (st) return (st);
2866 memcpy_tofs((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
2867 return (0);
2868
2869 case CDROMSTOP:
2870 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTOP entered.\n"));
2871 i=xx_Pause_Resume(1);
2872 DriveStruct[d].audio_state=0;
2873 return (0);
2874
2875 case CDROMSTART:
2876 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTART entered.\n"));
2877 xx_SpinUp();
2878 DriveStruct[d].audio_state=0;
2879 return (0);
2880
2881 case CDROMEJECT:
2882 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT entered.\n"));
2883 if (old_drive) return (0);
2884 do i=yy_LockDoor(0);
2885 while (i!=0);
2886 DriveStruct[d].open_count=0;
2887 i=yy_SpinDown();
2888 DPRINTF((DBG_IOX,"SBPCD: ioctl: yy_SpinDown returned %d.\n", i));
2889 if (i<0) return (-EIO);
2890 DriveStruct[d].CD_changed=0xFF;
2891 DriveStruct[d].diskstate_flags=0;
2892 DriveStruct[d].audio_state=0;
2893 return (0);
2894
2895 case CDROMEJECT_SW:
2896 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT_SW entered.\n"));
2897 if (old_drive) return (0);
2898 DriveStruct[d].f_eject=arg;
2899 return (0);
2900
2901 case CDROMVOLCTRL:
2902 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMVOLCTRL entered.\n"));
2903 st=verify_area(VERIFY_READ,(void *) arg,sizeof(volctrl));
2904 if (st) return (st);
2905 memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
2906 DriveStruct[d].vol_chan0=0;
2907 DriveStruct[d].vol_ctrl0=volctrl.channel0;
2908 DriveStruct[d].vol_chan1=1;
2909 DriveStruct[d].vol_ctrl1=volctrl.channel1;
2910 i=xx_SetVolume();
2911 return (0);
2912
2913 case CDROMSUBCHNL:
2914 DPRINTF((DBG_IOS,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
2915 if ((st_spinning)||(!subq_valid)) { i=xx_ReadSubQ();
2916 if (i<0) return (-EIO);
2917 }
2918 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
2919 if (st) return (st);
2920 memcpy_fromfs(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
2921 switch (DriveStruct[d].audio_state)
2922 {
2923 case audio_playing:
2924 SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
2925 break;
2926 case audio_pausing:
2927 SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
2928 break;
2929 default:
2930 SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
2931 break;
2932 }
2933 SC.cdsc_adr=DriveStruct[d].SubQ_ctl_adr;
2934 SC.cdsc_ctrl=DriveStruct[d].SubQ_ctl_adr>>4;
2935 SC.cdsc_trk=bcd2bin(DriveStruct[d].SubQ_trk);
2936 SC.cdsc_ind=bcd2bin(DriveStruct[d].SubQ_pnt_idx);
2937 if (SC.cdsc_format==CDROM_LBA)
2938 {
2939 SC.cdsc_absaddr.lba=msf2blk(DriveStruct[d].SubQ_run_tot);
2940 SC.cdsc_reladdr.lba=msf2blk(DriveStruct[d].SubQ_run_trk);
2941 }
2942 else
2943 {
2944 SC.cdsc_absaddr.msf.minute=(DriveStruct[d].SubQ_run_tot>>16)&0x00FF;
2945 SC.cdsc_absaddr.msf.second=(DriveStruct[d].SubQ_run_tot>>8)&0x00FF;
2946 SC.cdsc_absaddr.msf.frame=DriveStruct[d].SubQ_run_tot&0x00FF;
2947 SC.cdsc_reladdr.msf.minute=(DriveStruct[d].SubQ_run_trk>>16)&0x00FF;
2948 SC.cdsc_reladdr.msf.second=(DriveStruct[d].SubQ_run_trk>>8)&0x00FF;
2949 SC.cdsc_reladdr.msf.frame=DriveStruct[d].SubQ_run_trk&0x00FF;
2950 }
2951 memcpy_tofs((void *) arg, &SC, sizeof(struct cdrom_subchnl));
2952 DPRINTF((DBG_IOS,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
2953 SC.cdsc_format,SC.cdsc_audiostatus,
2954 SC.cdsc_adr,SC.cdsc_ctrl,
2955 SC.cdsc_trk,SC.cdsc_ind,
2956 SC.cdsc_absaddr,SC.cdsc_reladdr));
2957 return (0);
2958
2959 case CDROMREADMODE1:
2960 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE1 requested.\n"));
2961 xx_ModeSelect(CD_FRAMESIZE);
2962 xx_ModeSense();
2963 DriveStruct[d].mode=READ_M1;
2964 return (0);
2965
2966 case CDROMREADMODE2:
2967 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n"));
2968 xx_ModeSelect(CD_FRAMESIZE_XA);
2969 xx_ModeSense();
2970 DriveStruct[d].mode=READ_M2;
2971 return (0);
2972
2973 case CDROMREADAUDIO:
2974 {
2975 int i=0, j=0, frame, block;
2976 u_int try=0;
2977 u_long timeout;
2978 u_char *p;
2979 u_int data_tries = 0;
2980 u_int data_waits = 0;
2981 u_int data_retrying = 0;
2982 int status_tries;
2983 int error_flag;
2984
2985 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
2986 #if 0
2987 if (!new_drive) return (-EINVAL);
2988 #endif
2989 if (DriveStruct[d].aud_buf==NULL) return (-EINVAL);
2990 i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
2991 if (i) return (i);
2992 memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio));
2993 if (read_audio.nframes>SBP_BUFFER_AUDIO_FRAMES) return (-EINVAL);
2994 i=verify_area(VERIFY_WRITE, read_audio.buf,
2995 read_audio.nframes*CD_FRAMESIZE_RAW);
2996 if (i) return (i);
2997
2998 if (read_audio.addr_format==CDROM_MSF)
2999 block=msf2lba(&read_audio.addr.msf.minute);
3000 else if (read_audio.addr_format==CDROM_LBA)
3001 block=read_audio.addr.lba;
3002 else return (-EINVAL);
3003 DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n",
3004 block, blk2msf(block)));
3005 DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n"));
3006 while (busy_data) sbp_sleep(10);
3007 busy_audio=1;
3008 error_flag=0;
3009 for (data_tries=5; data_tries>0; data_tries--)
3010 {
3011 DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries));
3012 DriveStruct[d].mode=READ_AU;
3013 xx_ModeSelect(CD_FRAMESIZE_RAW);
3014 xx_ModeSense();
3015 for (status_tries=3; status_tries > 0; status_tries--)
3016 {
3017 flags_cmd_out |= f_respo3;
3018 xx_ReadStatus();
3019 if (sbp_status() != 0) break;
3020 sbp_sleep(1);
3021 }
3022 if (status_tries == 0)
3023 {
3024 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n"));
3025 continue;
3026 }
3027 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n"));
3028
3029 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
3030 if (!new_drive)
3031 {
3032 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
3033 cmd_type=READ_M2;
3034 drvcmd[0]=0x03;
3035 drvcmd[1]=(block>>16)&0x000000ff;
3036 drvcmd[2]=(block>>8)&0x000000ff;
3037 drvcmd[3]=block&0x000000ff;
3038 drvcmd[4]=0;
3039 drvcmd[5]=read_audio.nframes;
3040 drvcmd[6]=0;
3041 }
3042 else
3043 {
3044 drvcmd[0]=0x10;
3045 lba2msf(block,&drvcmd[1]);
3046 drvcmd[4]=0;
3047 drvcmd[5]=0;
3048 drvcmd[6]=1;
3049 }
3050 DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n"));
3051 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
3052 sbp_sleep(0);
3053 DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n"));
3054 for (frame=1;frame<2 && !error_flag; frame++)
3055 {
3056 try=maxtim_data;
3057 for (timeout=jiffies+900; ; )
3058 {
3059 for ( ; try!=0;try--)
3060 {
3061 j=inb(CDi_status);
3062 if (!(j&s_not_data_ready)) break;
3063 if (!(j&s_not_result_ready)) break;
3064 if (!new_drive) if (j&s_attention) break;
3065 }
3066 if (try != 0 || timeout <= jiffies) break;
3067 if (data_retrying == 0) data_waits++;
3068 data_retrying = 1;
3069 sbp_sleep(1);
3070 try = 1;
3071 }
3072 if (try==0)
3073 {
3074 DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n"));
3075 error_flag++;
3076 break;
3077 }
3078 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: CDi_status ok.\n"));
3079 if (j&s_not_data_ready)
3080 {
3081 printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n");
3082 error_flag++;
3083 break;
3084 }
3085 DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n"));
3086 error_flag=0;
3087 p = DriveStruct[d].aud_buf;
3088 if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
3089 #if 0
3090 cli();
3091 #endif
3092 READ_DATA(CDi_data, p, read_audio.nframes*CD_FRAMESIZE_RAW);
3093 #if 0
3094 sti();
3095 #endif
3096 if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
3097 data_retrying = 0;
3098 }
3099 DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n"));
3100 if (error_flag)
3101 {
3102 DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n"));
3103 #if 0000
3104 i=DriveReset();
3105 #endif 0000
3106 continue;
3107 }
3108 if (!new_drive)
3109 {
3110 i=maxtim_data;
3111 for (timeout=jiffies+900; timeout > jiffies; timeout--)
3112 {
3113 for ( ;i!=0;i--)
3114 {
3115 j=inb(CDi_status);
3116 if (!(j&s_not_data_ready)) break;
3117 if (!(j&s_not_result_ready)) break;
3118 if (j&s_attention) break;
3119 }
3120 if (i != 0 || timeout <= jiffies) break;
3121 sbp_sleep(0);
3122 i = 1;
3123 }
3124 if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); }
3125 if (!(j&s_attention))
3126 {
3127 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
3128 i=DriveReset();
3129 continue;
3130 }
3131 }
3132 do
3133 {
3134 if (!new_drive) xx_ReadStatus();
3135 i=ResponseStatus();
3136 if (i<0) { DPRINTF((DBG_AUD,
3137 "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n",
3138 DriveStruct[d].status_byte));
3139 continue;
3140 }
3141 }
3142 while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
3143 if (st_check)
3144 {
3145 i=xx_ReadError();
3146 DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i));
3147 continue;
3148 }
3149 memcpy_tofs((u_char *) read_audio.buf,
3150 (u_char *) DriveStruct[d].aud_buf,
3151 read_audio.nframes*CD_FRAMESIZE_RAW);
3152 DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n"));
3153 break;
3154 }
3155 xx_ModeSelect(CD_FRAMESIZE);
3156 xx_ModeSense();
3157 DriveStruct[d].mode=READ_M1;
3158 busy_audio=0;
3159 if (data_tries == 0)
3160 {
3161 DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n"));
3162 return (-8);
3163 }
3164 DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n"));
3165 return (0);
3166 }
3167
3168 case CDROMMULTISESSION:
3169 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMMULTISESSION entered.\n"));
3170 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_multisession));
3171 if (st) return (st);
3172 memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));
3173 if (ms_info.addr_format==CDROM_MSF)
3174 lba2msf(DriveStruct[d].lba_multi,&ms_info.addr.msf.minute);
3175 else if (ms_info.addr_format==CDROM_LBA)
3176 ms_info.addr.lba=DriveStruct[d].lba_multi;
3177 else return (-EINVAL);
3178 if (DriveStruct[d].f_multisession) ms_info.xa_flag=1;
3179 else ms_info.xa_flag=0;
3180 st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_multisession));
3181 if (st) return (st);
3182 memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));
3183 DPRINTF((DBG_MUL,"SBPCD: ioctl: CDROMMULTISESSION done (%d, %08X).\n",
3184 ms_info.xa_flag, ms_info.addr.lba));
3185 return (0);
3186
3187 case CDROMMULTISESSION_SYS:
3188 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMMULTISESSION_SYS entered.\n"));
3189 if(!suser()) return -EACCES;
3190 p_lba=arg;
3191 if (DriveStruct[d].f_multisession)
3192 *p_lba=DriveStruct[d].lba_multi;
3193 else
3194 *p_lba=0;
3195 DPRINTF((DBG_MUL,"SBPCD: ioctl: CDROMMULTISESSION_SYS done (%d).\n",
3196 p_lba[0]));
3197 return (0);
3198
3199 case BLKRASET:
3200 if(!suser()) return -EACCES;
3201 if(!inode->i_rdev) return -EINVAL;
3202 if(arg > 0xff) return -EINVAL;
3203 read_ahead[MAJOR(inode->i_rdev)] = arg;
3204 return (0);
3205
3206 default:
3207 DPRINTF((DBG_IOC,"SBPCD: ioctl: unknown function request %04X\n", cmd));
3208 return (-EINVAL);
3209 }
3210 }
3211
3212
3213
3214
3215 static void sbp_transfer(void)
3216 {
3217 long offs;
3218
3219 while ( (CURRENT->nr_sectors > 0) &&
3220 (CURRENT->sector/4 >= DriveStruct[d].sbp_first_frame) &&
3221 (CURRENT->sector/4 <= DriveStruct[d].sbp_last_frame) )
3222 {
3223 offs = (CURRENT->sector - DriveStruct[d].sbp_first_frame * 4) * 512;
3224 memcpy(CURRENT->buffer, DriveStruct[d].sbp_buf + offs, 512);
3225 CURRENT->nr_sectors--;
3226 CURRENT->sector++;
3227 CURRENT->buffer += 512;
3228 }
3229 }
3230
3231
3232
3233
3234 static void DO_SBPCD_REQUEST(void)
3235 {
3236 u_int block;
3237 int dev;
3238 u_int nsect;
3239 int i, status_tries, data_tries;
3240
3241 request_loop:
3242
3243 sti();
3244
3245 if ((CURRENT==NULL)||(CURRENT->dev<0)) goto done;
3246 if (CURRENT -> sector == -1) goto done;
3247
3248 dev = MINOR(CURRENT->dev);
3249 if ( (dev<0) || (dev>=NR_SBPCD) )
3250 {
3251 printk("SBPCD: do_request: bad device: %d\n", dev);
3252 goto done;
3253 }
3254 switch_drive(dev);
3255
3256 INIT_REQUEST;
3257 block = CURRENT->sector;
3258 nsect = CURRENT->nr_sectors;
3259 if (CURRENT->cmd != READ)
3260 {
3261 printk("SBPCD: bad cmd %d\n", CURRENT->cmd);
3262 end_request(0);
3263 goto request_loop;
3264 }
3265
3266 DPRINTF((DBG_BSZ,"SBPCD: read sector %d (%d sectors)\n", block, nsect));
3267 #if 0
3268 DPRINTF((DBG_MUL,"SBPCD: read LBA %d\n", block/4));
3269 #endif
3270
3271 sbp_transfer();
3272
3273 if (CURRENT->nr_sectors == 0)
3274 {
3275 end_request(1);
3276 goto request_loop;
3277 }
3278
3279 i=prepare(0,0);
3280 if (i!=0)
3281 DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i));
3282
3283 while (busy_audio) sbp_sleep(100);
3284 busy_data=1;
3285
3286 if (!st_spinning) xx_SpinUp();
3287
3288 #ifdef XA_TEST1
3289 if ((!new_drive) && (DriveStruct[d].xa_byte==0x20))
3290 {
3291 xx_ModeSelect(CD_FRAMESIZE_XA);
3292 xx_ModeSense();
3293 }
3294 #endif XA_TEST1
3295
3296 for (data_tries=3; data_tries > 0; data_tries--)
3297 {
3298 for (status_tries=3; status_tries > 0; status_tries--)
3299 {
3300 flags_cmd_out |= f_respo3;
3301 xx_ReadStatus();
3302 if (sbp_status() != 0) break;
3303 sbp_sleep(1);
3304 }
3305 if (status_tries == 0)
3306 {
3307 DPRINTF((DBG_INF,"SBPCD: sbp_status: failed after 3 tries\n"));
3308 break;
3309 }
3310
3311 sbp_read_cmd();
3312 sbp_sleep(0);
3313 if (sbp_data() != 0)
3314 {
3315 end_request(1);
3316 goto request_loop;
3317 }
3318 }
3319
3320 end_request(0);
3321 sbp_sleep(10);
3322 goto request_loop;
3323
3324 done:
3325 busy_data=0;
3326 return;
3327 }
3328
3329
3330
3331
3332
3333 static void sbp_read_cmd(void)
3334 {
3335 int i;
3336 int block;
3337
3338 DriveStruct[d].sbp_first_frame=DriveStruct[d].sbp_last_frame=-1;
3339 block=CURRENT->sector/4;
3340
3341 #if MULTISESSION_BY_DRIVER
3342 if (!old_drive)
3343 {
3344 #if MANY_SESSION
3345 DPRINTF((DBG_MUL,"SBPCD: read MSF %08X\n", blk2msf(block)));
3346 if (DriveStruct[d].f_multisession)
3347 {
3348 DPRINTF((DBG_MUL,"SBPCD: ManySession: use %08X for %08X (msf)\n",
3349 blk2msf(DriveStruct[d].lba_multi+block),
3350 blk2msf(block)));
3351 block=DriveStruct[d].lba_multi+block;
3352 }
3353 #else
3354 if ((block<=DriveStruct[d].last_redirect)
3355 && (DriveStruct[d].f_multisession))
3356 {
3357 DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
3358 blk2msf(DriveStruct[d].lba_multi+block),
3359 blk2msf(block)));
3360 block=DriveStruct[d].lba_multi+block;
3361 }
3362 #endif MANY_SESSION
3363 }
3364 #endif MULTISESSION_BY_DRIVER
3365
3366 if (block+SBP_BUFFER_FRAMES <= DriveStruct[d].CDsize_frm)
3367 DriveStruct[d].sbp_read_frames = SBP_BUFFER_FRAMES;
3368 else
3369 {
3370 DriveStruct[d].sbp_read_frames=DriveStruct[d].CDsize_frm-block;
3371
3372 if (DriveStruct[d].sbp_read_frames < 1)
3373 {
3374 DPRINTF((DBG_INF,"SBPCD: requested frame %d, CD size %d ???\n",
3375 block, DriveStruct[d].CDsize_frm));
3376 DriveStruct[d].sbp_read_frames=1;
3377 }
3378 }
3379 DriveStruct[d].sbp_current = 0;
3380
3381 flags_cmd_out = f_putcmd |
3382 f_respo2 |
3383 f_ResponseStatus |
3384 f_obey_p_check;
3385
3386 if (!new_drive)
3387 {
3388 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
3389 if (DriveStruct[d].xa_byte==0x20)
3390 {
3391 cmd_type=READ_M2;
3392 drvcmd[0]=0x03;
3393 drvcmd[1]=(block>>16)&0x000000ff;
3394 drvcmd[2]=(block>>8)&0x000000ff;
3395 drvcmd[3]=block&0x000000ff;
3396 drvcmd[4]=0;
3397 drvcmd[5]=DriveStruct[d].sbp_read_frames;
3398 drvcmd[6]=0;
3399 }
3400 else
3401 {
3402 drvcmd[0]=0x02;
3403
3404 if (DriveStruct[d].drv_type>=drv_201)
3405 {
3406 lba2msf(block,&drvcmd[1]);
3407 bin2bcdx(&drvcmd[1]);
3408 bin2bcdx(&drvcmd[2]);
3409 bin2bcdx(&drvcmd[3]);
3410 }
3411 else
3412 {
3413 drvcmd[1]=(block>>16)&0x000000ff;
3414 drvcmd[2]=(block>>8)&0x000000ff;
3415 drvcmd[3]=block&0x000000ff;
3416 }
3417 drvcmd[4]=0;
3418 drvcmd[5]=DriveStruct[d].sbp_read_frames;
3419 drvcmd[6]=(DriveStruct[d].drv_type<drv_201)?0:2;
3420 }
3421 }
3422 else
3423 {
3424 drvcmd[0]=0x10;
3425 lba2msf(block,&drvcmd[1]);
3426 drvcmd[4]=0;
3427 drvcmd[5]=0;
3428 drvcmd[6]=DriveStruct[d].sbp_read_frames;
3429 }
3430 SBPCD_CLI;
3431 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
3432 SBPCD_STI;
3433
3434 return;
3435 }
3436
3437
3438
3439
3440
3441 static int sbp_data(void)
3442 {
3443 int i=0, j=0, frame;
3444 u_int try=0;
3445 u_long timeout;
3446 u_char *p;
3447 u_int data_tries = 0;
3448 u_int data_waits = 0;
3449 u_int data_retrying = 0;
3450 int error_flag;
3451 int xa_count;
3452 error_flag=0;
3453
3454 for (frame=DriveStruct[d].sbp_current;frame<DriveStruct[d].sbp_read_frames&&!error_flag; frame++)
3455 {
3456 SBPCD_CLI;
3457 try=maxtim_data;
3458 #if LONG_TIMING
3459 for (timeout=jiffies+900; ; )
3460 #else
3461 for (timeout=jiffies+ ( (lcs_drive)? 300:100 ); ; )
3462 #endif
3463 {
3464 for ( ; try!=0;try--)
3465 {
3466 j=inb(CDi_status);
3467 if (!(j&s_not_data_ready)) break;
3468 if (!(j&s_not_result_ready)) break;
3469 if (!new_drive) if (j&s_attention) break;
3470 }
3471 if (try != 0 || timeout <= jiffies) break;
3472 if (data_retrying == 0) data_waits++;
3473 data_retrying = 1;
3474 sbp_sleep(1);
3475 try = 1;
3476 }
3477 if (try==0)
3478 {
3479 DPRINTF((DBG_INF,"SBPCD: sbp_data: CDi_status timeout.\n"));
3480 error_flag++;
3481 break;
3482 }
3483
3484 if (j&s_not_data_ready)
3485 {
3486 if ((DriveStruct[d].ored_ctl_adr&0x40)==0)
3487 printk("SBPCD: CD contains no data tracks.\n");
3488 else printk("SBPCD: sbp_data: DATA_READY timeout.\n");
3489 error_flag++;
3490 break;
3491 }
3492
3493 SBPCD_STI;
3494 error_flag=0;
3495 p = DriveStruct[d].sbp_buf + frame * CD_FRAMESIZE;
3496
3497 if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
3498 if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_head_buf, CD_XA_HEAD);
3499 READ_DATA(CDi_data, p, CD_FRAMESIZE);
3500 if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_tail_buf, CD_XA_TAIL);
3501 if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
3502 DriveStruct[d].sbp_current++;
3503 if (cmd_type==READ_M2)
3504 {
3505 DPRINTF((DBG_XA,"SBPCD: xa_head:"));
3506 for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
3507 DPRINTF((DBG_XA," %02X", xa_head_buf[xa_count]));
3508 DPRINTF((DBG_XA,"\n"));
3509 }
3510 data_tries++;
3511 data_retrying = 0;
3512 if (data_tries >= 1000)
3513 {
3514 DPRINTF((DBG_INF,"SBPCD: info: %d waits in %d frames.\n",
3515 data_waits, data_tries));
3516 data_waits = data_tries = 0;
3517 }
3518 }
3519 SBPCD_STI;
3520
3521 if (error_flag)
3522 {
3523 DPRINTF((DBG_INF,"SBPCD: read aborted by drive\n"));
3524 i=DriveReset();
3525 return (0);
3526 }
3527
3528 if (!new_drive)
3529 {
3530 SBPCD_CLI;
3531 i=maxtim_data;
3532 for (timeout=jiffies+100; timeout > jiffies; timeout--)
3533 {
3534 for ( ;i!=0;i--)
3535 {
3536 j=inb(CDi_status);
3537 if (!(j&s_not_data_ready)) break;
3538 if (!(j&s_not_result_ready)) break;
3539 if (j&s_attention) break;
3540 }
3541 if (i != 0 || timeout <= jiffies) break;
3542 sbp_sleep(0);
3543 i = 1;
3544 }
3545 if (i==0) { DPRINTF((DBG_INF,"SBPCD: STATUS TIMEOUT AFTER READ")); }
3546 if (!(j&s_attention))
3547 {
3548 DPRINTF((DBG_INF,"SBPCD: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
3549 i=DriveReset();
3550 SBPCD_STI;
3551 return (0);
3552 }
3553 SBPCD_STI;
3554 }
3555
3556 do
3557 {
3558 if (!new_drive) xx_ReadStatus();
3559 i=ResponseStatus();
3560 if (i<0) { DPRINTF((DBG_INF,"SBPCD: xx_ReadStatus error after read: %02X\n",
3561 DriveStruct[d].status_byte));
3562 return (0);
3563 }
3564 }
3565 while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
3566 if (st_check)
3567 {
3568 i=xx_ReadError();
3569 DPRINTF((DBG_INF,"SBPCD: xx_ReadError was necessary after read: %02X\n",i));
3570 return (0);
3571 }
3572
3573 DriveStruct[d].sbp_first_frame = CURRENT -> sector / 4;
3574 DriveStruct[d].sbp_last_frame = DriveStruct[d].sbp_first_frame + DriveStruct[d].sbp_read_frames - 1;
3575 sbp_transfer();
3576 return (1);
3577 }
3578
3579
3580
3581
3582
3583 static int sbpcd_open(struct inode *ip, struct file *fp)
3584 {
3585 int i;
3586
3587 if (ndrives==0) return (-ENXIO);
3588
3589 if (fp->f_mode & 2)
3590 return -EROFS;
3591
3592 i = MINOR(ip->i_rdev);
3593 if ( (i<0) || (i>=NR_SBPCD) )
3594 {
3595 printk("SBPCD: open: bad device: %d\n", i);
3596 return (-ENODEV);
3597 }
3598 switch_drive(i);
3599
3600 flags_cmd_out |= f_respo2;
3601 xx_ReadStatus();
3602 i=ResponseStatus();
3603 if (!st_door_closed)
3604 {
3605 yy_CloseTray();
3606 flags_cmd_out |= f_respo2;
3607 xx_ReadStatus();
3608 i=ResponseStatus();
3609 }
3610 if (!st_spinning)
3611 {
3612 xx_SpinUp();
3613 flags_cmd_out |= f_respo2;
3614 xx_ReadStatus();
3615 i=ResponseStatus();
3616 }
3617 if (i<0)
3618 {
3619 DPRINTF((DBG_INF,"SBPCD: sbpcd_open: xx_ReadStatus timed out\n"));
3620 return (-EIO);
3621 }
3622 DPRINTF((DBG_STA,"SBPCD: sbpcd_open: status %02X\n", DriveStruct[d].status_byte));
3623 if (!st_door_closed||!st_caddy_in)
3624 {
3625 printk("SBPCD: sbpcd_open: no disk in drive\n");
3626 #if JUKEBOX
3627 do
3628 i=yy_LockDoor(0);
3629 while (i!=0);
3630 if (!old_drive) yy_SpinDown();
3631 #endif
3632 return (-ENXIO);
3633 }
3634
3635
3636
3637 DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
3638 DriveStruct[d].open_count,DriveStruct[d].open_count+1));
3639 if (++DriveStruct[d].open_count==1)
3640 {
3641 do
3642 i=yy_LockDoor(1);
3643 while (i!=0);
3644 }
3645 if (!st_spinning) xx_SpinUp();
3646
3647 i=DiskInfo();
3648 if ((DriveStruct[d].ored_ctl_adr&0x40)==0)
3649 DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
3650 return (0);
3651 }
3652
3653
3654
3655
3656 static void sbpcd_release(struct inode * ip, struct file * file)
3657 {
3658 int i;
3659
3660 i = MINOR(ip->i_rdev);
3661 if ( (i<0) || (i>=NR_SBPCD) )
3662 {
3663 printk("SBPCD: release: bad device: %d\n", i);
3664 return;
3665 }
3666 switch_drive(i);
3667
3668 DriveStruct[d].sbp_first_frame=DriveStruct[d].sbp_last_frame=-1;
3669 sync_dev(ip->i_rdev);
3670 invalidate_buffers(ip->i_rdev);
3671 DriveStruct[d].diskstate_flags &= ~cd_size_bit;
3672
3673
3674
3675
3676 DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
3677 DriveStruct[d].open_count,DriveStruct[d].open_count-1));
3678 if (DriveStruct[d].open_count!=0)
3679 {
3680 if (--DriveStruct[d].open_count==0)
3681 {
3682 do
3683 i=yy_LockDoor(0);
3684 while (i!=0);
3685 if (DriveStruct[d].f_eject) yy_SpinDown();
3686 }
3687 }
3688 }
3689
3690
3691
3692
3693 static struct file_operations sbpcd_fops =
3694 {
3695 NULL,
3696 block_read,
3697 block_write,
3698 NULL,
3699 NULL,
3700 sbpcd_ioctl,
3701 NULL,
3702 sbpcd_open,
3703 sbpcd_release,
3704 NULL,
3705 NULL,
3706 check_media_change,
3707 NULL
3708 };
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730 #if (SBPCD_ISSUE-1)
3731 static
3732 #endif
3733 void sbpcd_setup(char *s, int *p)
3734 {
3735 setup_done++;
3736 DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s));
3737 sbpro_type=0;
3738 if (!strcmp(s,str_sb)) sbpro_type=1;
3739 else if (!strcmp(s,str_sp)) sbpro_type=2;
3740 if (p[0]>0) sbpcd_ioaddr=p[1];
3741
3742 CDo_command=sbpcd_ioaddr;
3743 CDi_info=sbpcd_ioaddr;
3744 CDi_status=sbpcd_ioaddr+1;
3745 CDo_sel_d_i=sbpcd_ioaddr+1;
3746 CDo_reset=sbpcd_ioaddr+2;
3747 CDo_enable=sbpcd_ioaddr+3;
3748 if (sbpro_type==1)
3749 {
3750 MIXER_addr=sbpcd_ioaddr-0x10+0x04;
3751 MIXER_data=sbpcd_ioaddr-0x10+0x05;
3752 CDi_data=sbpcd_ioaddr;
3753 }
3754 else CDi_data=sbpcd_ioaddr+2;
3755 }
3756
3757
3758
3759
3760
3761
3762
3763
3764 static int config_spea(void)
3765 {
3766 int n_ports=0x10;
3767 int irq_number=0;
3768 int dma_channel=0;
3769 int dack_polarity=0;
3770 int drq_polarity=0x40;
3771
3772 int i;
3773
3774 #define SPEA_REG_1 sbpcd_ioaddr+4
3775 #define SPEA_REG_2 sbpcd_ioaddr+5
3776
3777 OUT(SPEA_REG_1,0xFF);
3778 i=inb(SPEA_REG_1);
3779 if (i!=0x0F)
3780 {
3781 DPRINTF((DBG_SEQ,"SBPCD: no SPEA interface at %04X present.\n",
3782 sbpcd_ioaddr));
3783 return (-1);
3784 }
3785 OUT(SPEA_REG_1,0x04);
3786 OUT(SPEA_REG_2,0xC0);
3787
3788 OUT(SPEA_REG_1,0x05);
3789 OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
3790
3791 #if 1
3792 #define SPEA_PATTERN 0x80
3793 #else
3794 #define SPEA_PATTERN 0x00
3795 #endif
3796 OUT(SPEA_REG_1,0x06);
3797 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
3798 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
3799
3800 OUT(SPEA_REG_1,0x09);
3801 i=(inb(SPEA_REG_2)&0xCF)|n_ports;
3802 OUT(SPEA_REG_2,i);
3803
3804 sbpro_type = 0;
3805 DPRINTF((DBG_SEQ,"SBPCD: found SPEA interface at %04X.\n",
3806 sbpcd_ioaddr));
3807 return (0);
3808 }
3809
3810
3811
3812
3813 unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
3814 {
3815 int i=0, j=0;
3816 int addr[2]={1, CDROM_PORT};
3817 int port_index;
3818
3819 sti();
3820
3821 DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION));
3822
3823 if (!setup_done)
3824 {
3825 DPRINTF((DBG_INF,"SBPCD: Looking for Matsushita, Panasonic, CreativeLabs, IBM, Longshine CD-ROM drives\n"));
3826 DPRINTF((DBG_WRN,"SBPCD: \n"));
3827 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = W A R N I N G = = = = = = = = = =\n"));
3828 DPRINTF((DBG_WRN,"SBPCD: Auto-Probing can cause a hang (f.e. touching an ethernet card).\n"));
3829 DPRINTF((DBG_WRN,"SBPCD: If that happens, you have to reboot and use the\n"));
3830 DPRINTF((DBG_WRN,"SBPCD: LILO (kernel) command line feature like:\n"));
3831 DPRINTF((DBG_WRN,"SBPCD: \n"));
3832 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x230,SoundBlaster\n"));
3833 DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
3834 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x300,LaserMate\n"));
3835 DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
3836 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x330,SPEA\n"));
3837 DPRINTF((DBG_WRN,"SBPCD: \n"));
3838 DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n"));
3839 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n"));
3840 DPRINTF((DBG_WRN,"SBPCD: \n"));
3841 }
3842 autoprobe[0]=sbpcd_ioaddr;
3843 autoprobe[1]=sbpro_type;
3844
3845 for (port_index=0;port_index<NUM_AUTOPROBE;port_index+=2)
3846 {
3847 addr[1]=autoprobe[port_index];
3848 if (check_region(addr[1],4)) continue;
3849 DPRINTF((DBG_INI,"SBPCD: check_region: free.\n"));
3850 if (autoprobe[port_index+1]==0) type=str_lm;
3851 else if (autoprobe[port_index+1]==1) type=str_sb;
3852 else type=str_sp;
3853 sbpcd_setup(type, addr);
3854 DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n",
3855 type, CDo_command));
3856
3857 DPRINTF((DBG_INF,"SBPCD: - "));
3858 if (autoprobe[port_index+1]==2)
3859 {
3860 i=config_spea();
3861 if (i<0)
3862 {
3863 DPRINTF((DBG_INF,"\n"));
3864 continue;
3865 }
3866 }
3867 #if TEAC
3868 i=find_teac_drives();
3869 if (i>0)
3870 {
3871 DPRINTF((DBG_INF,"SBPCD: found %d TEAC drives. A wonder.\n",i));
3872 DPRINTF((DBG_INF,"SBPCD: - "));
3873 }
3874 #endif TEAC
3875 i=check_drives();
3876 DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
3877 if (i>=0) break;
3878 DPRINTF((DBG_INF,"\n"));
3879 }
3880
3881 if (ndrives==0)
3882 {
3883 printk("SBPCD: No drive found.\n");
3884 #if PRINTK_BUG
3885 sti();
3886 #endif
3887 goto init_done;
3888 }
3889
3890 if (port_index>0)
3891 {
3892 printk("SBPCD: You should configure sbpcd.h for your hardware.\n");
3893 #if PRINTK_BUG
3894 sti();
3895 #endif
3896 }
3897
3898 printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
3899 ndrives, type, CDo_command);
3900 #if PRINTK_BUG
3901 sti();
3902 #endif
3903 check_datarate();
3904 DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
3905
3906 if (!lcs_drive)
3907 {
3908 OUT(CDo_reset,0);
3909 sbp_sleep(100);
3910 }
3911
3912 for (j=0;j<NR_SBPCD;j++)
3913 {
3914 if (DriveStruct[j].drv_minor==-1) continue;
3915 switch_drive(j);
3916 if (!lcs_drive) xy_DriveReset();
3917 if (!st_spinning) xx_SpinUp();
3918 DriveStruct[d].sbp_first_frame = -1;
3919 DriveStruct[d].sbp_last_frame = -1;
3920 DriveStruct[d].sbp_read_frames = 0;
3921 DriveStruct[d].sbp_current = 0;
3922 DriveStruct[d].CD_changed=1;
3923 DriveStruct[d].frame_size=CD_FRAMESIZE;
3924 #if EJECT
3925 if (!old_drive) DriveStruct[d].f_eject=1;
3926 else DriveStruct[d].f_eject=0;
3927 #else
3928 DriveStruct[d].f_eject=0;
3929 #endif
3930
3931 xx_ReadStatus();
3932 i=ResponseStatus();
3933 if (i<0)
3934 DPRINTF((DBG_INF,"SBPCD: init: ResponseStatus returns %02X\n",i));
3935 else
3936 {
3937 if (st_check)
3938 {
3939 i=xx_ReadError();
3940 DPRINTF((DBG_INI,"SBPCD: init: xx_ReadError returns %d\n",i));
3941 }
3942 }
3943 DPRINTF((DBG_INI,"SBPCD: init: first GetStatus: %d\n",i));
3944 DPRINTF((DBG_LCS,"SBPCD: init: first GetStatus: error_byte=%d\n",
3945 DriveStruct[d].error_byte));
3946 if (DriveStruct[d].error_byte==aud_12)
3947 {
3948 do { i=GetStatus();
3949 DPRINTF((DBG_INI,"SBPCD: init: second GetStatus: %02X\n",i));
3950 DPRINTF((DBG_LCS,
3951 "SBPCD: init: second GetStatus: error_byte=%d\n",
3952 DriveStruct[d].error_byte));
3953 if (i<0) break;
3954 if (!st_caddy_in) break;
3955 }
3956 while (!st_diskok);
3957 }
3958 i=SetSpeed();
3959 if (i>=0) DriveStruct[d].CD_changed=1;
3960 }
3961
3962
3963
3964
3965
3966
3967 if ((sbpro_type==1) || (SOUND_BASE))
3968 {
3969 if (sbpro_type!=1)
3970 {
3971 MIXER_addr=SOUND_BASE+0x04;
3972 MIXER_data=SOUND_BASE+0x05;
3973 }
3974 OUT(MIXER_addr,MIXER_CD_Volume);
3975 OUT(MIXER_data,0xCC);
3976 }
3977
3978 if (register_blkdev(MAJOR_NR, major_name, &sbpcd_fops) != 0)
3979 {
3980 printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
3981 #if PRINTK_BUG
3982 sti();
3983 #endif
3984 goto init_done;
3985 }
3986 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3987 read_ahead[MAJOR_NR] = SBP_BUFFER_FRAMES * (CD_FRAMESIZE / 512);
3988
3989 snarf_region(CDo_command,4);
3990
3991 for (j=0;j<NR_SBPCD;j++)
3992 {
3993 if (DriveStruct[j].drv_minor==-1) continue;
3994
3995
3996
3997 DriveStruct[j].sbp_buf=(u_char *)mem_start;
3998 mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE;
3999 if (new_drive)
4000 {
4001 DriveStruct[j].aud_buf=(u_char *)mem_start;
4002 mem_start += SBP_BUFFER_AUDIO_FRAMES*CD_FRAMESIZE_RAW;
4003 }
4004 else DriveStruct[j].aud_buf=NULL;
4005
4006
4007
4008 sbpcd_blocksizes[j]=CD_FRAMESIZE;
4009 }
4010 blksize_size[MAJOR_NR]=sbpcd_blocksizes;
4011
4012 init_done:
4013 #if !(SBPCD_ISSUE-1)
4014 #ifdef CONFIG_SBPCD2
4015 mem_start=sbpcd2_init(mem_start, mem_end);
4016 #endif
4017 #ifdef CONFIG_SBPCD3
4018 mem_start=sbpcd3_init(mem_start, mem_end);
4019 #endif
4020 #ifdef CONFIG_SBPCD4
4021 mem_start=sbpcd4_init(mem_start, mem_end);
4022 #endif
4023 #endif
4024 #if !(SBPCD_ISSUE-1)
4025 DPRINTF((DBG_INF,"SBPCD: init done.\n"));
4026 #endif
4027 return (mem_start);
4028 }
4029
4030
4031
4032
4033
4034
4035 static int check_media_change(dev_t full_dev)
4036 {
4037 int st;
4038
4039 DPRINTF((DBG_CHK,"SBPCD: media_check (%d) called\n", MINOR(full_dev)));
4040 return (0);
4041
4042 if ((MAJOR(full_dev)!=MAJOR_NR)||(MINOR(full_dev)>=NR_SBPCD))
4043 {
4044 printk("SBPCD: media_check: invalid device %04X.\n", full_dev);
4045 return (-1);
4046 }
4047
4048 switch_drive(MINOR(full_dev));
4049
4050 xx_ReadStatus();
4051 st=ResponseStatus();
4052 DPRINTF((DBG_CHK,"SBPCD: media_check: %02X\n",DriveStruct[d].status_byte));
4053 if (st<0)
4054 {
4055 DPRINTF((DBG_INF,"SBPCD: media_check: ResponseStatus error.\n"));
4056 return (1);
4057 }
4058 if (DriveStruct[d].CD_changed==0xFF) DPRINTF((DBG_CHK,"SBPCD: media_check: \"changed\" assumed.\n"));
4059 if (!st_spinning) DPRINTF((DBG_CHK,"SBPCD: media_check: motor off.\n"));
4060 if (!st_door_closed)
4061 {
4062 DPRINTF((DBG_CHK,"SBPCD: media_check: door open.\n"));
4063 DriveStruct[d].CD_changed=0xFF;
4064 }
4065 if (!st_caddy_in)
4066 {
4067 DPRINTF((DBG_CHK,"SBPCD: media_check: no disk in drive.\n"));
4068 DriveStruct[d].CD_changed=0xFF;
4069 }
4070 if (!st_diskok) DPRINTF((DBG_CHK,"SBPCD: media_check: !st_diskok.\n"));
4071
4072 #if 0000
4073 if (DriveStruct[d].CD_changed==0xFF)
4074 {
4075 DriveStruct[d].CD_changed=1;
4076 return (1);
4077 }
4078 #endif 0000
4079
4080 if (!st_diskok) return (1);
4081 if (!st_caddy_in) return (1);
4082 if (!st_door_closed) return (1);
4083 return (0);
4084 }
4085