This source file includes following definitions.
- sbpcd_dprintf
- sbpcd_dbg_ioctl
- sbp_sleep
- lba2msf
- bin2bcdx
- blk2msf
- make16
- make32
- swap_nibbles
- byt2bcd
- bcd2bin
- msf2blk
- sta2err
- clr_cmdbuf
- mark_timeout
- flush_status
- CDi_stat_loop
- 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
- 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
- check_version
- switch_drive
- check_drives
- timewait
- obey_audio_state
- check_allowed1
- check_allowed2
- check_allowed3
- seek_pos_audio_end
- ReadToC
- DiskInfo
- prepare
- xx_PlayAudioMSF
- sbpcd_ioctl
- sbp_transfer
- sbpcd_interrupt
- sbp_status
- do_sbpcd_request
- sbp_read_cmd
- sbp_data
- sbpcd_open
- sbpcd_release
- sbpcd_setup
- sbpcd_init
- check_sbpcd_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 #include <linux/config.h>
111 #include <linux/errno.h>
112
113 #include <linux/sched.h>
114 #include <linux/timer.h>
115 #include <linux/fs.h>
116 #include <linux/kernel.h>
117 #include <linux/cdrom.h>
118 #include <linux/ioport.h>
119 #include <linux/sbpcd.h>
120 #include <linux/string.h>
121
122 #if SBPCD_USE_IRQ
123 #include <linux/signal.h>
124 #endif SBPCD_USE_IRQ
125
126 #include <linux/major.h>
127
128 #include <asm/system.h>
129 #include <asm/io.h>
130 #include <asm/segment.h>
131 #include <stdarg.h>
132
133 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
134 #include "blk.h"
135
136 #define VERSION "1.5 Eberhard Moenkeberg <emoenke@gwdg.de>"
137
138 #define SBPCD_DEBUG
139
140 #ifndef CONFIG_ISO9660_FS
141 #error "SBPCD: \"make config\" again. File system iso9660 is necessary."
142 #endif
143
144
145
146
147 #define DDIOCSDBG 0x9000
148
149
150
151
152 #define LONG_TIMING 0
153 #define MANY_SESSION 0
154 #undef FUTURE
155 #define WORKMAN 1
156 #define CDMKE
157
158 #undef XA_TEST1
159 #define XA_TEST2
160
161 #define TEST_UPC 0
162
163
164
165
166 #if MANY_SESSION
167 #undef LONG_TIMING
168 #define LONG_TIMING 1
169 #endif
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 static int autoprobe[] =
190 {
191 CDROM_PORT, SBPRO,
192 0x230, 1,
193 0x300, 0,
194 0x250, 1,
195 0x260, 1,
196 0x320, 0,
197 0x340, 0,
198 0x360, 0,
199 0x270, 1,
200 0x630, 0,
201 0x650, 0,
202 0x670, 0,
203 0x690, 0,
204 #if 0
205
206 0x330, 0,
207 0x350, 0,
208 0x370, 0,
209 0x290, 1,
210 0x310, 0,
211 #endif
212 };
213
214 #define NUM_AUTOPROBE (sizeof(autoprobe) / sizeof(int))
215
216
217
218
219
220
221 static void sbp_read_cmd(void);
222 static int sbp_data(void);
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 #if 1
256 static int sbpcd_debug = (1<<DBG_INF) | (1<<DBG_WRN);
257 #else
258 static int sbpcd_debug = (1<<DBG_INF) |
259 (1<<DBG_TOC) |
260 (1<<DBG_UPC) |
261 (1<<DBG_IOC) |
262 (1<<DBG_XA) |
263 (1<<DBG_LCK) |
264 (1<<DBG_SQ) |
265 (1<<DBG_IOX);
266 #endif
267 static int sbpcd_ioaddr = CDROM_PORT;
268 static int sbpro_type = SBPRO;
269 static int CDo_command, CDo_reset;
270 static int CDo_sel_d_i, CDo_enable;
271 static int CDi_info, CDi_status, CDi_data;
272 static int MIXER_addr, MIXER_data;
273 static struct cdrom_msf msf;
274 static struct cdrom_ti ti;
275 static struct cdrom_tochdr tochdr;
276 static struct cdrom_tocentry tocentry;
277 static struct cdrom_subchnl SC;
278 static struct cdrom_volctrl volctrl;
279 char *str_sb = "SoundBlaster";
280 char *str_lm = "LaserMate";
281 char *type;
282
283
284
285 #if FUTURE
286 static struct wait_queue *sbp_waitq = NULL;
287 #endif FUTURE
288
289
290
291 #define SBP_BUFFER_FRAMES 4
292
293
294
295 static u_char drive_family[]="CR-5";
296 static u_char drive_vendor[]="MATSHITA";
297
298 static u_int response_count=0;
299 static u_int flags_cmd_out;
300 static u_char cmd_type=0;
301 static u_char drvcmd[7];
302 static u_char infobuf[20];
303 static u_char xa_head_buf[CD_XA_HEAD];
304 static u_char xa_tail_buf[CD_XA_TAIL];
305
306 static u_char timed_out=0;
307 static u_int datarate= 1000000;
308 static u_int maxtim16=16000000;
309 static u_int maxtim04= 4000000;
310 static u_int maxtim02= 2000000;
311 static u_int maxtim_8= 30000;
312 #if LONG_TIMING
313 static u_int maxtim_data= 9000;
314 #else
315 static u_int maxtim_data= 3000;
316 #endif LONG_TIMING
317
318
319
320 static int ndrives=0;
321 static u_char drv_pattern[4]={ 0x80, 0x80, 0x80, 0x80 };
322
323
324
325
326
327
328
329
330 static int d=0;
331
332 static struct {
333 char drv_minor;
334
335 char drive_model[4];
336 char firmware_version[4];
337 u_char *sbp_buf;
338
339 int sbp_first_frame;
340 int sbp_last_frame;
341 int sbp_read_frames;
342 int sbp_current;
343
344 u_char drv_type;
345 u_char drv_options;
346 u_char status_byte;
347 u_char diskstate_flags;
348 u_char sense_byte;
349
350 u_char CD_changed;
351 u_char open_count;
352 u_char error_byte;
353
354 u_char f_multisession;
355 u_int lba_multi;
356
357 u_char audio_state;
358 u_int pos_audio_start;
359 u_int pos_audio_end;
360 char vol_chan0;
361 u_char vol_ctrl0;
362 char vol_chan1;
363 u_char vol_ctrl1;
364 #if 000
365 char vol_chan2;
366 u_char vol_ctrl2;
367 char vol_chan3;
368 u_char vol_ctrl3;
369 #endif 000
370
371 u_char SubQ_ctl_adr;
372 u_char SubQ_trk;
373 u_char SubQ_pnt_idx;
374 u_int SubQ_run_tot;
375 u_int SubQ_run_trk;
376 u_char SubQ_whatisthis;
377
378 u_char UPC_ctl_adr;
379 u_char UPC_buf[7];
380
381 int CDsize_blk;
382 int frame_size;
383 int CDsize_frm;
384
385 u_char xa_byte;
386 u_char n_first_track;
387 u_char n_last_track;
388 u_int size_msf;
389 u_int size_blk;
390
391 u_char TocEnt_nixbyte;
392 u_char TocEnt_ctl_adr;
393 u_char TocEnt_number;
394 u_char TocEnt_format;
395 u_int TocEnt_address;
396 u_char ored_ctl_adr;
397
398 struct {
399 u_char nixbyte;
400 u_char ctl_adr;
401 u_char number;
402 u_char format;
403 u_int address;
404 } TocBuffer[MAX_TRACKS+1];
405
406 int in_SpinUp;
407
408 } DS[4];
409
410
411
412
413
414
415
416
417
418 #ifdef SBPCD_DEBUG
419 # define DPRINTF(x) sbpcd_dprintf x
420
421 void sbpcd_dprintf(int level, char *fmt, ...)
422 {
423 char buff[256];
424 va_list args;
425 extern int vsprintf(char *buf, const char *fmt, va_list args);
426
427 if (! (sbpcd_debug & (1 << level))) return;
428
429 va_start(args, fmt);
430 vsprintf(buff, fmt, args);
431 va_end(args);
432 printk(buff);
433 }
434
435 #else
436 # define DPRINTF(x)
437
438 #endif SBPCD_DEBUG
439
440
441
442
443 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
444 {
445 int val;
446
447 val = get_fs_long((int *) arg);
448 switch(val)
449 {
450 case 0:
451 sbpcd_debug = 0;
452 break;
453
454 default:
455 if (val >= 128) sbpcd_debug &= ~(1 << (val - 128));
456 else sbpcd_debug |= (1 << val);
457 }
458 return(0);
459 }
460
461
462
463
464
465
466
467
468 static inline void sbp_sleep(u_int jifs)
469 {
470 current->state = TASK_INTERRUPTIBLE;
471 current->timeout = jiffies + jifs;
472 schedule();
473 }
474
475
476
477
478
479
480 static void lba2msf(int lba, u_char *msf)
481 {
482 lba += CD_BLOCK_OFFSET;
483 msf[0] = lba / (CD_SECS*CD_FRAMES);
484 lba %= CD_SECS*CD_FRAMES;
485 msf[1] = lba / CD_FRAMES;
486 msf[2] = lba % CD_FRAMES;
487 }
488
489
490
491
492
493 static void bin2bcdx(u_char *p)
494 {
495 *p=((*p/10)<<4)|(*p%10);
496 }
497
498 static u_int blk2msf(u_int blk)
499 {
500 MSF msf;
501 u_int mm;
502
503 msf.c[3] = 0;
504 msf.c[2] = (blk + CD_BLOCK_OFFSET) / (CD_SECS * CD_FRAMES);
505 mm = (blk + CD_BLOCK_OFFSET) % (CD_SECS * CD_FRAMES);
506 msf.c[1] = mm / CD_FRAMES;
507 msf.c[0] = mm % CD_FRAMES;
508 return (msf.n);
509 }
510
511 static u_int make16(u_char rh, u_char rl)
512 {
513 return ((rh<<8)|rl);
514 }
515
516 static u_int make32(u_int rh, u_int rl)
517 {
518 return ((rh<<16)|rl);
519 }
520
521 static u_char swap_nibbles(u_char i)
522 {
523 return ((i<<4)|(i>>4));
524 }
525
526 static u_char byt2bcd(u_char i)
527 {
528 return (((i/10)<<4)+i%10);
529 }
530
531 static u_char bcd2bin(u_char bcd)
532 {
533 return ((bcd>>4)*10+(bcd&0x0F));
534 }
535
536 static int msf2blk(int msfx)
537 {
538 MSF msf;
539 int i;
540
541 msf.n=msfx;
542 i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_BLOCK_OFFSET;
543 if (i<0) return (0);
544 return (i);
545 }
546
547
548 static int sta2err(int sta)
549 {
550 if (sta<=2) return (sta);
551 if (sta==0x05) return (-4);
552 if (sta==0x06) return (-6);
553 if (sta==0x0d) return (-6);
554 if (sta==0x0e) return (-3);
555 if (sta==0x14) return (-3);
556 if (sta==0x0c) return (-11);
557 if (sta==0x0f) return (-11);
558 if (sta==0x10) return (-11);
559 if (sta>=0x16) return (-12);
560 DS[d].CD_changed=0xFF;
561 if (sta==0x11) return (-15);
562 return (-2);
563 }
564
565 static void clr_cmdbuf(void)
566 {
567 int i;
568
569 for (i=0;i<7;i++) drvcmd[i]=0;
570 cmd_type=0;
571 }
572
573 static void mark_timeout(void)
574 {
575 timed_out=1;
576 DPRINTF((DBG_TIM,"SBPCD: timer stopped.\n"));
577 }
578
579 static void flush_status(void)
580 {
581 #ifdef CDMKE
582 int i;
583
584 if (current == task[0])
585 for (i=maxtim02;i!=0;i--) inb(CDi_status);
586 else
587 {
588 sbp_sleep(150);
589 for (i=maxtim_data;i!=0;i--) inb(CDi_status);
590 }
591 #else
592 timed_out=0;
593 SET_TIMER(mark_timeout,150);
594 do { }
595 while (!timed_out);
596 CLEAR_TIMER;
597 inb(CDi_status);
598 #endif CDMKE
599 }
600
601 static int CDi_stat_loop(void)
602 {
603 int i,j;
604 u_long timeout;
605
606 if (current == task[0])
607 for(i=maxtim16;i!=0;i--)
608 {
609 j=inb(CDi_status);
610 if (!(j&s_not_data_ready)) return (j);
611 if (!(j&s_not_result_ready)) return (j);
612 if (!new_drive) if (j&s_attention) return (j);
613 }
614 else
615 for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; )
616 {
617 for ( ;i!=0;i--)
618 {
619 j=inb(CDi_status);
620 if (!(j&s_not_data_ready)) return (j);
621 if (!(j&s_not_result_ready)) return (j);
622 if (!new_drive) if (j&s_attention) return (j);
623 }
624 sbp_sleep(1);
625 i = 1;
626 }
627 return (-1);
628 }
629
630 static int ResponseInfo(void)
631 {
632 int i,j, st=0;
633 u_long timeout;
634
635 if (current == task[0])
636 for (i=0;i<response_count;i++)
637 {
638 for (j=maxtim_8;j!=0;j--)
639 {
640 st=inb(CDi_status);
641 if (!(st&s_not_result_ready)) break;
642 }
643 if (j==0) return (-1);
644 infobuf[i]=inb(CDi_info);
645 }
646 else
647 {
648 for (i=0, timeout = jiffies + 100; i < response_count; i++)
649 {
650 for (j=maxtim_data; ; )
651 {
652 for ( ;j!=0;j-- )
653 {
654 st=inb(CDi_status);
655 if (!(st&s_not_result_ready)) break;
656 }
657 if (j != 0 || timeout <= jiffies) break;
658 sbp_sleep(0);
659 j = 1;
660 }
661 if (timeout <= jiffies) return (-1);
662 infobuf[i]=inb(CDi_info);
663 }
664 }
665 return (0);
666 }
667
668 static int EvaluateStatus(int st)
669 {
670 if (!new_drive)
671 {
672 DS[d].status_byte=0;
673 if (st&p_caddin_old) DS[d].status_byte |= p_door_closed|p_caddy_in;
674 if (st&p_spinning) DS[d].status_byte |= p_spinning;
675 if (st&p_check) DS[d].status_byte |= p_check;
676 if (st&p_busy_old) DS[d].status_byte |= p_busy_new;
677 if (st&p_disk_ok) DS[d].status_byte |= p_disk_ok;
678 }
679 else { DS[d].status_byte=st;
680 st=p_success_old;
681 }
682 return (st);
683 }
684
685 static int ResponseStatus(void)
686 {
687 int i,j;
688 u_long timeout;
689
690 DPRINTF((DBG_STA,"SBPCD: doing ResponseStatus...\n"));
691
692 if (current == task[0])
693 {
694 if (flags_cmd_out & f_respo3) j = maxtim_8;
695 else if (flags_cmd_out&f_respo2) j=maxtim16;
696 else j=maxtim04;
697 for (;j!=0;j--)
698 {
699 i=inb(CDi_status);
700 if (!(i&s_not_result_ready)) break;
701 }
702 }
703 else
704 {
705 if (flags_cmd_out & f_respo3) timeout = jiffies;
706 else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600;
707 else timeout = jiffies + 400;
708 j=maxtim_8;
709 do
710 {
711 for ( ;j!=0;j--)
712 {
713 i=inb(CDi_status);
714 if (!(i&s_not_result_ready)) break;
715 }
716 if (j != 0 || timeout <= jiffies) break;
717 sbp_sleep(0);
718 j = 1;
719 }
720 while (1);
721 }
722 if (j==0)
723 { if ((flags_cmd_out & f_respo3) == 0)
724 DPRINTF((DBG_STA,"SBPCD: ResponseStatus: timeout.\n"));
725 EvaluateStatus(0);
726 return (-1);
727 }
728 i=inb(CDi_info);
729 i=EvaluateStatus(i);
730 return (i);
731 }
732
733 static void xx_ReadStatus(void)
734 {
735 int i;
736
737 DPRINTF((DBG_STA,"SBPCD: giving xx_ReadStatus command\n"));
738
739 if (!new_drive) OUT(CDo_command,0x81);
740 else
741 {
742 #if SBPCD_DIS_IRQ
743 cli();
744 #endif SBPCD_DIS_IRQ
745 OUT(CDo_command,0x05);
746 for (i=0;i<6;i++) OUT(CDo_command,0);
747 #if SBPCD_DIS_IRQ
748 sti();
749 #endif SBPCD_DIS_IRQ
750 }
751 }
752
753 int xx_ReadError(void)
754 {
755 int cmd_out(void);
756 int i;
757
758 clr_cmdbuf();
759 DPRINTF((DBG_ERR,"SBPCD: giving xx_ReadError command.\n"));
760 if (new_drive)
761 {
762 drvcmd[0]=0x82;
763 response_count=8;
764 flags_cmd_out=f_putcmd|f_ResponseStatus;
765 }
766 else
767 {
768 drvcmd[0]=0x82;
769 response_count=6;
770 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
771 }
772 i=cmd_out();
773 DS[d].error_byte=0;
774 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
775 if (i<0) return (i);
776 if (new_drive) i=2;
777 else i=1;
778 DS[d].error_byte=infobuf[i];
779 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DS[d].error_byte,DS[d].error_byte));
780 i=sta2err(infobuf[i]);
781 return (i);
782 }
783
784 int cmd_out(void)
785 {
786 int i=0;
787
788 if (flags_cmd_out&f_putcmd)
789 {
790 DPRINTF((DBG_CMD,"SBPCD: cmd_out: put"));
791 for (i=0;i<7;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i]));
792 DPRINTF((DBG_CMD,"\n"));
793
794 #if SBPCD_DIS_IRQ
795 cli();
796 #endif SBPCD_DIS_IRQ
797 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
798 #if SBPCD_DIS_IRQ
799 sti();
800 #endif SBPCD_DIS_IRQ
801 }
802 if (response_count!=0)
803 {
804 if (cmd_type!=0)
805 {
806 if (sbpro_type) OUT(CDo_sel_d_i,0x01);
807 DPRINTF((DBG_INF,"SBPCD: misleaded to try ResponseData.\n"));
808 if (sbpro_type) OUT(CDo_sel_d_i,0x00);
809 return (-22);
810 }
811 else i=ResponseInfo();
812 if (i<0) return (-9);
813 }
814 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to CDi_stat_loop.\n"));
815 if (flags_cmd_out&f_lopsta)
816 {
817 i=CDi_stat_loop();
818 if ((i<0)||!(i&s_attention)) return (-9);
819 }
820 if (!(flags_cmd_out&f_getsta)) goto LOC_229;
821
822 LOC_228:
823 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadStatus.\n"));
824 xx_ReadStatus();
825
826 LOC_229:
827 if (flags_cmd_out&f_ResponseStatus)
828 {
829 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to ResponseStatus.\n"));
830 i=ResponseStatus();
831
832 if (i<0) return (-9);
833 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
834 {
835 if (!st_check)
836 {
837 if (flags_cmd_out&f_bit1) if (i&p_success_old) goto LOC_232;
838 if (!(flags_cmd_out&f_wait_if_busy)) goto LOC_228;
839 if (!st_busy) goto LOC_228;
840 }
841 }
842 }
843 LOC_232:
844 if (!(flags_cmd_out&f_obey_p_check)) return (0);
845 if (!st_check) return (0);
846 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadError.\n"));
847 i=xx_ReadError();
848 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to cmd_out OK.\n"));
849 return (i);
850 }
851
852 static int xx_Seek(u_int pos, char f_blk_msf)
853 {
854 int i;
855
856 clr_cmdbuf();
857 if (f_blk_msf>1) return (-3);
858 if (!new_drive)
859 {
860 if (f_blk_msf==1) pos=msf2blk(pos);
861 drvcmd[2]=(pos>>16)&0x00FF;
862 drvcmd[3]=(pos>>8)&0x00FF;
863 drvcmd[4]=pos&0x00FF;
864 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
865 f_ResponseStatus | f_obey_p_check | f_bit1;
866 }
867 else
868 {
869 if (f_blk_msf==0) pos=blk2msf(pos);
870 drvcmd[1]=(pos>>16)&0x00FF;
871 drvcmd[2]=(pos>>8)&0x00FF;
872 drvcmd[3]=pos&0x00FF;
873 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
874 }
875 drvcmd[0]=0x01;
876 response_count=0;
877 i=cmd_out();
878 return (i);
879 }
880
881 static int xx_SpinUp(void)
882 {
883 int i;
884
885 DPRINTF((DBG_SPI,"SBPCD: SpinUp.\n"));
886 DS[d].in_SpinUp = 1;
887 clr_cmdbuf();
888 if (!new_drive)
889 {
890 drvcmd[0]=0x05;
891 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
892 }
893 else
894 {
895 drvcmd[0]=0x02;
896 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
897 }
898 response_count=0;
899 i=cmd_out();
900 DS[d].in_SpinUp = 0;
901 return (i);
902 }
903
904 static int yy_SpinDown(void)
905 {
906 int i;
907
908 if (!new_drive) return (-3);
909 clr_cmdbuf();
910 drvcmd[0]=0x06;
911 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
912 response_count=0;
913 i=cmd_out();
914 return (i);
915 }
916
917 static int yy_SetSpeed(u_char speed, u_char x1, u_char x2)
918 {
919 int i;
920
921 if (!new_drive) return (-3);
922 clr_cmdbuf();
923 drvcmd[0]=0x09;
924 drvcmd[1]=0x03;
925 drvcmd[2]=speed;
926 drvcmd[3]=x1;
927 drvcmd[4]=x2;
928 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
929 response_count=0;
930 i=cmd_out();
931 return (i);
932 }
933
934 static int xx_SetVolume(void)
935 {
936 int i;
937 u_char channel0,channel1,volume0,volume1;
938 u_char control0,value0,control1,value1;
939
940 DS[d].diskstate_flags &= ~volume_bit;
941 clr_cmdbuf();
942 channel0=DS[d].vol_chan0;
943 volume0=DS[d].vol_ctrl0;
944 channel1=control1=DS[d].vol_chan1;
945 volume1=value1=DS[d].vol_ctrl1;
946 control0=value0=0;
947
948 if (((DS[d].drv_options&sax_a)!=0)&&(DS[d].drv_type>=drv_211))
949 {
950 if ((volume0!=0)&&(volume1==0))
951 {
952 volume1=volume0;
953 channel1=channel0;
954 }
955 else if ((volume0==0)&&(volume1!=0))
956 {
957 volume0=volume1;
958 channel0=channel1;
959 }
960 }
961 if (channel0>1)
962 {
963 channel0=0;
964 volume0=0;
965 }
966 if (channel1>1)
967 {
968 channel1=1;
969 volume1=0;
970 }
971
972 if (new_drive)
973 {
974 control0=channel0+1;
975 control1=channel1+1;
976 value0=(volume0>volume1)?volume0:volume1;
977 value1=value0;
978 if (volume0==0) control0=0;
979 if (volume1==0) control1=0;
980 drvcmd[0]=0x09;
981 drvcmd[1]=0x05;
982 drvcmd[3]=control0;
983 drvcmd[4]=value0;
984 drvcmd[5]=control1;
985 drvcmd[6]=value1;
986 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
987 }
988 else
989 {
990 if (DS[d].drv_type>=drv_300)
991 {
992 control0=volume0&0xFC;
993 value0=volume1&0xFC;
994 if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
995 if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
996 if (channel0!=0) control0 |= 0x01;
997 if (channel1==1) value0 |= 0x01;
998 }
999 else
1000 {
1001 value0=(volume0>volume1)?volume0:volume1;
1002 if (DS[d].drv_type<drv_211)
1003 {
1004 if (channel0!=0)
1005 {
1006 i=channel1;
1007 channel1=channel0;
1008 channel0=i;
1009 i=volume1;
1010 volume1=volume0;
1011 volume0=i;
1012 }
1013 if (channel0==channel1)
1014 {
1015 if (channel0==0)
1016 {
1017 channel1=1;
1018 volume1=0;
1019 volume0=value0;
1020 }
1021 else
1022 {
1023 channel0=0;
1024 volume0=0;
1025 volume1=value0;
1026 }
1027 }
1028 }
1029
1030 if ((volume0!=0)&&(volume1!=0))
1031 {
1032 if (volume0==0xFF) volume1=0xFF;
1033 else if (volume1==0xFF) volume0=0xFF;
1034 }
1035 else if (DS[d].drv_type<drv_201) volume0=volume1=value0;
1036
1037 if (DS[d].drv_type>=drv_201)
1038 {
1039 if (volume0==0) control0 |= 0x80;
1040 if (volume1==0) control0 |= 0x40;
1041 }
1042 if (DS[d].drv_type>=drv_211)
1043 {
1044 if (channel0!=0) control0 |= 0x20;
1045 if (channel1!=1) control0 |= 0x10;
1046 }
1047 }
1048 drvcmd[0]=0x84;
1049 drvcmd[1]=0x83;
1050 drvcmd[4]=control0;
1051 drvcmd[5]=value0;
1052 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1053 }
1054
1055 response_count=0;
1056 i=cmd_out();
1057 if (i>0) return (i);
1058 DS[d].diskstate_flags |= volume_bit;
1059 return (0);
1060 }
1061
1062 static int GetStatus(void)
1063 {
1064 int i;
1065
1066 flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1067 response_count=0;
1068 cmd_type=0;
1069 i=cmd_out();
1070 return (i);
1071 }
1072
1073 static int xy_DriveReset(void)
1074 {
1075 int i;
1076
1077 DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
1078 if (!new_drive) OUT(CDo_reset,0x00);
1079 else
1080 {
1081 clr_cmdbuf();
1082 drvcmd[0]=0x0A;
1083 flags_cmd_out=f_putcmd;
1084 response_count=0;
1085 i=cmd_out();
1086 }
1087 flush_status();
1088 i=GetStatus();
1089 if (i>=0) return -1;
1090 if (DS[d].error_byte!=aud_12) return -1;
1091 return (0);
1092 }
1093
1094 static int SetSpeed(void)
1095 {
1096 int i, speed;
1097
1098 if (!(DS[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
1099 speed=speed_auto;
1100 if (!(DS[d].drv_options&speed_auto))
1101 {
1102 speed |= speed_300;
1103 if (!(DS[d].drv_options&speed_300)) speed=0;
1104 }
1105 i=yy_SetSpeed(speed,0,0);
1106 return (i);
1107 }
1108
1109 static int DriveReset(void)
1110 {
1111 int i;
1112
1113 i=xy_DriveReset();
1114 if (i<0) return (-2);
1115 do
1116 {
1117 i=GetStatus();
1118 if ((i<0)&&(i!=-15)) return (-2);
1119 if (!st_caddy_in) break;
1120 }
1121 while (!st_diskok);
1122 DS[d].CD_changed=1;
1123 i=SetSpeed();
1124 if (i<0) return (-2);
1125 return (0);
1126 }
1127
1128 static int xx_Pause_Resume(int pau_res)
1129 {
1130 int i;
1131
1132 clr_cmdbuf();
1133 if (new_drive)
1134 {
1135 drvcmd[0]=0x0D;
1136 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1137 }
1138 else
1139 {
1140 drvcmd[0]=0x8D;
1141 flags_cmd_out=f_putcmd|f_respo2|f_getsta|f_ResponseStatus|f_obey_p_check;
1142 }
1143 if (pau_res!=1) drvcmd[1]=0x80;
1144 response_count=0;
1145 i=cmd_out();
1146 return (i);
1147 }
1148
1149 static int yy_LockDoor(char lock)
1150 {
1151 int i;
1152
1153 if (!new_drive) return (0);
1154 DPRINTF((DBG_LCK,"SBPCD: yy_LockDoor: %d (drive %d)\n", lock, d));
1155 clr_cmdbuf();
1156 drvcmd[0]=0x0C;
1157 if (lock==1) drvcmd[1]=0x01;
1158 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1159 response_count=0;
1160 i=cmd_out();
1161 return (i);
1162 }
1163
1164 static int xx_ReadSubQ(void)
1165 {
1166 int i,j;
1167
1168 DS[d].diskstate_flags &= ~subq_bit;
1169 for (j=255;j>0;j--)
1170 {
1171 clr_cmdbuf();
1172 if (new_drive)
1173 {
1174 drvcmd[0]=0x87;
1175 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1176 response_count=11;
1177 }
1178 else
1179 {
1180 drvcmd[0]=0x89;
1181 drvcmd[1]=0x02;
1182 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1183 response_count=13;
1184 }
1185 i=cmd_out();
1186 if (i<0) return (i);
1187 DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:"));
1188 for (i=0;i<(new_drive?11:13);i++)
1189 {
1190 DPRINTF((DBG_SQ," %02X", infobuf[i]));
1191 }
1192 DPRINTF((DBG_SQ,"\n"));
1193 if (infobuf[0]!=0) break;
1194 if ((!st_spinning) || (j==1))
1195 {
1196 DS[d].SubQ_ctl_adr=DS[d].SubQ_trk=DS[d].SubQ_pnt_idx=DS[d].SubQ_whatisthis=0;
1197 DS[d].SubQ_run_tot=DS[d].SubQ_run_trk=0;
1198 return (0);
1199 }
1200 }
1201 DS[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
1202 DS[d].SubQ_trk=byt2bcd(infobuf[2]);
1203 DS[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
1204 i=4;
1205 if (!new_drive) i=5;
1206 DS[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1207 i=7;
1208 if (!new_drive) i=9;
1209 DS[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1210 DS[d].SubQ_whatisthis=infobuf[i+3];
1211 DS[d].diskstate_flags |= subq_bit;
1212 return (0);
1213 }
1214
1215 static int xx_ModeSense(void)
1216 {
1217 int i;
1218
1219 DS[d].diskstate_flags &= ~frame_size_bit;
1220 clr_cmdbuf();
1221 if (new_drive)
1222 {
1223 drvcmd[0]=0x84;
1224 drvcmd[1]=0x00;
1225 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1226 response_count=5;
1227 }
1228 else
1229 {
1230 drvcmd[0]=0x85;
1231 drvcmd[1]=0x00;
1232 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1233 response_count=2;
1234 }
1235 i=cmd_out();
1236 if (i<0) return (i);
1237 i=0;
1238 if (new_drive) DS[d].sense_byte=infobuf[i++];
1239 DS[d].frame_size=make16(infobuf[i],infobuf[i+1]);
1240
1241 DPRINTF((DBG_XA,"SBPCD: xx_ModeSense: "));
1242 for (i=0;i<(new_drive?5:2);i++)
1243 {
1244 DPRINTF((DBG_XA,"%02X ", infobuf[i]));
1245 }
1246 DPRINTF((DBG_XA,"\n"));
1247
1248 DS[d].diskstate_flags |= frame_size_bit;
1249 return (0);
1250 }
1251
1252
1253 static int xx_ModeSelect(int framesize)
1254 {
1255 int i;
1256
1257 DS[d].diskstate_flags &= ~frame_size_bit;
1258 clr_cmdbuf();
1259 DS[d].frame_size=framesize;
1260
1261 DPRINTF((DBG_XA,"SBPCD: xx_ModeSelect: %02X %04X\n",
1262 DS[d].sense_byte, DS[d].frame_size));
1263
1264 if (new_drive)
1265 {
1266 drvcmd[0]=0x09;
1267 drvcmd[1]=0x00;
1268 drvcmd[2]=DS[d].sense_byte;
1269 drvcmd[3]=(DS[d].frame_size>>8)&0xFF;
1270 drvcmd[4]=DS[d].frame_size&0xFF;
1271 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1272 }
1273 else
1274 {
1275 drvcmd[0]=0x84;
1276 drvcmd[1]=0x00;
1277 drvcmd[2]=(DS[d].frame_size>>8)&0xFF;
1278 drvcmd[3]=DS[d].frame_size&0xFF;
1279 drvcmd[4]=0x00;
1280 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1281 }
1282 response_count=0;
1283 i=cmd_out();
1284 if (i<0) return (i);
1285 DS[d].diskstate_flags |= frame_size_bit;
1286 return (0);
1287 }
1288
1289 #if 0000
1290 static int xx_TellVolume(void)
1291 {
1292 int i;
1293 u_char switches;
1294 u_char chan0,vol0,chan1,vol1;
1295
1296 DS[d].diskstate_flags &= ~volume_bit;
1297 clr_cmdbuf();
1298 if (new_drive)
1299 {
1300 drvcmd[0]=0x84;
1301 drvcmd[1]=0x05;
1302 response_count=5;
1303 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1304 }
1305 else
1306 {
1307 drvcmd[0]=0x85;
1308 drvcmd[1]=0x03;
1309 response_count=2;
1310 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1311 }
1312 i=cmd_out();
1313 if (i<0) return (i);
1314 if (new_drive)
1315 {
1316 chan0=infobuf[1]&0x0F;
1317 vol0=infobuf[2];
1318 chan1=infobuf[3]&0x0F;
1319 vol1=infobuf[4];
1320 if (chan0==0)
1321 {
1322 chan0=1;
1323 vol0=0;
1324 }
1325 if (chan1==0)
1326 {
1327 chan1=2;
1328 vol1=0;
1329 }
1330 chan0 >>= 1;
1331 chan1 >>= 1;
1332 }
1333 else
1334 {
1335 chan0=0;
1336 chan1=1;
1337 vol0=vol1=infobuf[1];
1338 if (DS[d].drv_type>=drv_201)
1339 {
1340 if (DS[d].drv_type<drv_300)
1341 {
1342 switches=infobuf[0];
1343 if ((switches&0x80)!=0) vol0=0;
1344 if ((switches&0x40)!=0) vol1=0;
1345 if (DS[d].drv_type>=drv_211)
1346 {
1347 if ((switches&0x20)!=0) chan0=1;
1348 if ((switches&0x10)!=0) chan1=0;
1349 }
1350 }
1351 else
1352 {
1353 vol0=infobuf[0];
1354 if ((vol0&0x01)!=0) chan0=1;
1355 if ((vol1&0x01)==0) chan1=0;
1356 vol0 &= 0xFC;
1357 vol1 &= 0xFC;
1358 if (vol0!=0) vol0 += 3;
1359 if (vol1!=0) vol1 += 3;
1360 }
1361 }
1362 }
1363 DS[d].vol_chan0=chan0;
1364 DS[d].vol_ctrl0=vol0;
1365 DS[d].vol_chan1=chan1;
1366 DS[d].vol_ctrl1=vol1;
1367 DS[d].vol_chan2=2;
1368 DS[d].vol_ctrl2=0xFF;
1369 DS[d].vol_chan3=3;
1370 DS[d].vol_ctrl3=0xFF;
1371 DS[d].diskstate_flags |= volume_bit;
1372 return (0);
1373 }
1374 #endif
1375
1376 static int xx_ReadCapacity(void)
1377 {
1378 int i;
1379
1380 DS[d].diskstate_flags &= ~cd_size_bit;
1381 clr_cmdbuf();
1382 if (new_drive)
1383 {
1384 drvcmd[0]=0x85;
1385 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1386 }
1387 else
1388 {
1389 drvcmd[0]=0x88;
1390 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1391 }
1392 response_count=5;
1393 i=cmd_out();
1394 if (i<0) return (i);
1395 DS[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
1396 if (new_drive) DS[d].CDsize_blk=msf2blk(DS[d].CDsize_blk);
1397 DS[d].CDsize_frm = (DS[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
1398 DS[d].CDsize_blk += 151;
1399 DS[d].diskstate_flags |= cd_size_bit;
1400 return (0);
1401 }
1402
1403 static int xx_ReadTocDescr(void)
1404 {
1405 int i;
1406
1407 DS[d].diskstate_flags &= ~toc_bit;
1408 clr_cmdbuf();
1409 if (new_drive)
1410 {
1411 drvcmd[0]=0x8B;
1412 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1413 }
1414 else
1415 {
1416 drvcmd[0]=0x8B;
1417 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1418 }
1419 response_count=6;
1420 i=cmd_out();
1421 if (i<0) return (i);
1422 DS[d].xa_byte=infobuf[0];
1423 DS[d].n_first_track=infobuf[1];
1424 DS[d].n_last_track=infobuf[2];
1425 DS[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
1426 DS[d].size_blk=msf2blk(DS[d].size_msf);
1427 DS[d].diskstate_flags |= toc_bit;
1428 DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
1429 DS[d].xa_byte,DS[d].n_first_track,DS[d].n_last_track,DS[d].size_msf));
1430 return (0);
1431 }
1432
1433 static int xx_ReadTocEntry(int num)
1434 {
1435 int i;
1436
1437 clr_cmdbuf();
1438 if (new_drive)
1439 {
1440 drvcmd[0]=0x8C;
1441 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1442 }
1443 else
1444 {
1445 drvcmd[0]=0x8C;
1446 drvcmd[1]=0x02;
1447 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1448 }
1449 drvcmd[2]=num;
1450 response_count=8;
1451 i=cmd_out();
1452 if (i<0) return (i);
1453 DS[d].TocEnt_nixbyte=infobuf[0];
1454 DS[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
1455 DS[d].TocEnt_number=infobuf[2];
1456 DS[d].TocEnt_format=infobuf[3];
1457 if (new_drive) i=4;
1458 else i=5;
1459 DS[d].TocEnt_address=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1460 DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
1461 DS[d].TocEnt_nixbyte,DS[d].TocEnt_ctl_adr,DS[d].TocEnt_number,
1462 DS[d].TocEnt_format,DS[d].TocEnt_address));
1463 return (0);
1464 }
1465
1466 static int xx_ReadPacket(void)
1467 {
1468 int i;
1469
1470 clr_cmdbuf();
1471 drvcmd[0]=0x8E;
1472 drvcmd[1]=response_count;
1473 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1474 i=cmd_out();
1475 return (i);
1476 }
1477
1478 static int convert_UPC(u_char *p)
1479 {
1480 int i;
1481
1482 p++;
1483 if (!new_drive) p[13]=0;
1484 for (i=0;i<7;i++)
1485 {
1486 if (new_drive) DS[d].UPC_buf[i]=swap_nibbles(*p++);
1487 else
1488 {
1489 DS[d].UPC_buf[i]=((*p++)<<4)&0xFF;
1490 DS[d].UPC_buf[i] |= *p++;
1491 }
1492 }
1493 DS[d].UPC_buf[6] &= 0xF0;
1494 return (0);
1495 }
1496
1497 static int xx_ReadUPC(void)
1498 {
1499 int i;
1500 #if TEST_UPC
1501 int block, checksum;
1502 #endif TEST_UPC
1503
1504 DS[d].diskstate_flags &= ~upc_bit;
1505 #if TEST_UPC
1506 for (block=CD_BLOCK_OFFSET+1;block<CD_BLOCK_OFFSET+200;block++)
1507 {
1508 #endif TEST_UPC
1509 clr_cmdbuf();
1510 if (new_drive)
1511 {
1512 drvcmd[0]=0x88;
1513 #if TEST_UPC
1514 drvcmd[1]=(block>>16)&0xFF;
1515 drvcmd[2]=(block>>8)&0xFF;
1516 drvcmd[3]=block&0xFF;
1517 #endif TEST_UPC
1518 response_count=8;
1519 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1520 }
1521 else
1522 {
1523 drvcmd[0]=0x08;
1524 #if TEST_UPC
1525 drvcmd[2]=(block>>16)&0xFF;
1526 drvcmd[3]=(block>>8)&0xFF;
1527 drvcmd[4]=block&0xFF;
1528 #endif TEST_UPC
1529 response_count=0;
1530 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1531 }
1532 i=cmd_out();
1533 if (i<0) return (i);
1534 if (!new_drive)
1535 {
1536 response_count=16;
1537 i=xx_ReadPacket();
1538 if (i<0) return (i);
1539 }
1540 #if TEST_UPC
1541 checksum=0;
1542 #endif TEST_UPC
1543 DPRINTF((DBG_UPC,"SBPCD: UPC info: "));
1544 for (i=0;i<(new_drive?8:16);i++)
1545 {
1546 #if TEST_UPC
1547 checksum |= infobuf[i];
1548 #endif TEST_UPC
1549 DPRINTF((DBG_UPC,"%02X ", infobuf[i]));
1550 }
1551 DPRINTF((DBG_UPC,"\n"));
1552 #if TEST_UPC
1553 if ((checksum&0x7F)!=0) break;
1554 }
1555 #endif TEST_UPC
1556 DS[d].UPC_ctl_adr=0;
1557 if (new_drive) i=0;
1558 else i=2;
1559 if ((infobuf[i]&0x80)!=0)
1560 {
1561 convert_UPC(&infobuf[i]);
1562 DS[d].UPC_ctl_adr = (DS[d].TocEnt_ctl_adr & 0xF0) | 0x02;
1563 }
1564
1565 DPRINTF((DBG_UPC,"SBPCD: UPC code: "));
1566 DPRINTF((DBG_UPC,"(%02X) ", DS[d].UPC_ctl_adr));
1567 for (i=0;i<7;i++)
1568 {
1569 DPRINTF((DBG_UPC,"%02X ", DS[d].UPC_buf[i]));
1570 }
1571 DPRINTF((DBG_UPC,"\n"));
1572
1573 DS[d].diskstate_flags |= upc_bit;
1574 return (0);
1575 }
1576
1577 static int yy_CheckMultiSession(void)
1578 {
1579 int i;
1580
1581 DS[d].diskstate_flags &= ~multisession_bit;
1582 DS[d].f_multisession=0;
1583 clr_cmdbuf();
1584 if (new_drive)
1585 {
1586 drvcmd[0]=0x8D;
1587 response_count=6;
1588 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1589 i=cmd_out();
1590 if (i<0) return (i);
1591 if ((infobuf[0]&0x80)!=0)
1592 {
1593 DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X\n",
1594 infobuf[0], infobuf[1], infobuf[2],
1595 infobuf[3], infobuf[4], infobuf[5]));
1596 DS[d].f_multisession=1;
1597 DS[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
1598 make16(infobuf[2],infobuf[3])));
1599 }
1600 }
1601 DS[d].diskstate_flags |= multisession_bit;
1602 return (0);
1603 }
1604
1605 #if FUTURE
1606 static int yy_SubChanInfo(int frame, int count, u_char *buffer)
1607
1608 {
1609 int i;
1610
1611 if (!new_drive) return (-3);
1612 #if 0
1613 if (DS[d].audio_state!=audio_playing) return (-2);
1614 #endif
1615 clr_cmdbuf();
1616 drvcmd[0]=0x11;
1617 drvcmd[1]=(frame>>16)&0xFF;
1618 drvcmd[2]=(frame>>8)&0xFF;
1619 drvcmd[3]=frame&0xFF;
1620 drvcmd[5]=(count>>8)&0xFF;
1621 drvcmd[6]=count&0xFF;
1622 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1623 cmd_type=READ_SC;
1624 DS[d].frame_size=CD_FRAMESIZE_SUB;
1625 i=cmd_out();
1626 return (i);
1627 }
1628 #endif FUTURE
1629
1630 static void check_datarate(void)
1631 {
1632 #ifdef CDMKE
1633 int i=0;
1634
1635 timed_out=0;
1636 datarate=0;
1637
1638
1639
1640 DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
1641 sti();
1642
1643 SET_TIMER(mark_timeout,110);
1644 do
1645 {
1646 i=inb(CDi_status);
1647 datarate++;
1648
1649 #if 00000
1650 if (datarate>0x0FFFFFFF) break;
1651 #endif 00000
1652
1653 }
1654 while (!timed_out);
1655 CLEAR_TIMER;
1656 DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
1657 if (datarate<65536) datarate=65536;
1658
1659 maxtim16=datarate*16;
1660 maxtim04=datarate*4;
1661 maxtim02=datarate*2;
1662 maxtim_8=datarate/32;
1663 #if LONG_TIMING
1664 maxtim_data=datarate/100;
1665 #else
1666 maxtim_data=datarate/300;
1667 #endif LONG_TIMING
1668 DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
1669 maxtim_8, maxtim_data));
1670 #endif CDMKE
1671 }
1672
1673 static int check_version(void)
1674 {
1675 int i, j;
1676
1677
1678 clr_cmdbuf();
1679 drvcmd[0]=0x82;
1680 response_count=9;
1681 flags_cmd_out=f_putcmd;
1682 cmd_out();
1683
1684
1685 clr_cmdbuf();
1686 for (i=0;i<12;i++) infobuf[i]=0;
1687 drvcmd[0]=0x83;
1688 response_count=12;
1689 flags_cmd_out=f_putcmd;
1690 i=cmd_out();
1691 if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i));
1692
1693 DPRINTF((DBG_INI,"SBPCD: infobuf = \""));
1694 for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i]));
1695 DPRINTF((DBG_INI,"\"\n"));
1696
1697 for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break;
1698 if (i==4)
1699 {
1700 DS[d].drive_model[0]=infobuf[i++];
1701 DS[d].drive_model[1]=infobuf[i++];
1702 DS[d].drive_model[2]='-';
1703 DS[d].drive_model[3]='x';
1704 DS[d].drv_type=drv_new;
1705 }
1706 else
1707 {
1708 for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
1709 if (i!=8) return (-1);
1710 DS[d].drive_model[0]='2';
1711 DS[d].drive_model[1]='x';
1712 DS[d].drive_model[2]='-';
1713 DS[d].drive_model[3]='x';
1714 DS[d].drv_type=drv_old;
1715 }
1716 for (j=0;j<4;j++) DS[d].firmware_version[j]=infobuf[i+j];
1717 j = (DS[d].firmware_version[0] & 0x0F) * 100 +
1718 (DS[d].firmware_version[2] & 0x0F) *10 +
1719 (DS[d].firmware_version[3] & 0x0F);
1720 if (new_drive)
1721 {
1722 if (j<100) DS[d].drv_type=drv_099;
1723 else DS[d].drv_type=drv_100;
1724 }
1725 else if (j<200) DS[d].drv_type=drv_199;
1726 else if (j<201) DS[d].drv_type=drv_200;
1727 else if (j<210) DS[d].drv_type=drv_201;
1728 else if (j<211) DS[d].drv_type=drv_210;
1729 else if (j<300) DS[d].drv_type=drv_211;
1730 else DS[d].drv_type=drv_300;
1731 return (0);
1732 }
1733
1734 static int switch_drive(int num)
1735 {
1736 int i;
1737
1738 d=num;
1739
1740 i=num;
1741 if (sbpro_type) i=(i&0x01)<<1|(i&0x02)>>1;
1742 OUT(CDo_enable,i);
1743 DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DS[d].drv_minor));
1744 return (0);
1745 }
1746
1747
1748
1749
1750 static int check_drives(void)
1751 {
1752 int i, j;
1753 char *printk_header="";
1754
1755 DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
1756
1757 ndrives=0;
1758 for (j=0;j<NR_SBPCD;j++)
1759 {
1760 DS[j].drv_minor=j;
1761 switch_drive(j);
1762 DPRINTF((DBG_ID,"SBPCD: check_drives: drive %d activated.\n",j));
1763 i=check_version();
1764 DPRINTF((DBG_ID,"SBPCD: check_version returns %d.\n",i));
1765 if (i>=0)
1766 {
1767 ndrives++;
1768 DS[d].drv_options=drv_pattern[j];
1769 if (!new_drive) DS[d].drv_options&=~(speed_auto|speed_300|speed_150);
1770 printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header,
1771 DS[d].drv_minor,
1772 drive_family,
1773 DS[d].drive_model,
1774 DS[d].firmware_version);
1775 printk_header=" - ";
1776 }
1777 else DS[d].drv_minor=-1;
1778 }
1779 if (ndrives==0) return (-1);
1780 return (0);
1781 }
1782
1783 #if 000
1784 static void timewait(void)
1785 {
1786 int i;
1787 for (i=0; i<65500; i++);
1788 }
1789 #endif 000
1790
1791 #if FUTURE
1792
1793
1794
1795 static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
1796 {
1797 switch (audio_state)
1798 {
1799 case aud_11:
1800 case audx11:
1801 switch (func)
1802 {
1803 case cmd_07:
1804 case cmd_0d:
1805 case cmd_0e:
1806 case cmd_0c:
1807 return (1);
1808 case cmd_03:
1809 switch (subfunc)
1810
1811 {
1812 case cxi_00:
1813 case cxi_06:
1814 case cxi_09:
1815 return (1);
1816 default:
1817 return (ERROR15);
1818 }
1819 return (1);
1820 default:
1821 return (ERROR15);
1822 }
1823 return (1);
1824 case aud_12:
1825 case audx12:
1826 return (1);
1827 default:
1828 return (2);
1829 }
1830 }
1831 #endif FUTURE
1832
1833
1834
1835
1836
1837
1838 static int check_allowed1(u_char func1, u_char func2)
1839 {
1840 #if 000
1841 if (func1==ioctl_o) return (0);
1842 if (func1==read_long) return (-1);
1843 if (func1==read_long_prefetch) return (-1);
1844 if (func1==seek) return (-1);
1845 if (func1==audio_play) return (-1);
1846 if (func1==audio_pause) return (-1);
1847 if (func1==audio_resume) return (-1);
1848 if (func1!=ioctl_i) return (0);
1849 if (func2==tell_SubQ_run_tot) return (-1);
1850 if (func2==tell_cdsize) return (-1);
1851 if (func2==tell_TocDescrip) return (-1);
1852 if (func2==tell_TocEntry) return (-1);
1853 if (func2==tell_subQ_info) return (-1);
1854 if (new_drive) if (func2==tell_SubChanInfo) return (-1);
1855 if (func2==tell_UPC) return (-1);
1856 #else
1857 return (0);
1858 #endif 000
1859 }
1860
1861 static int check_allowed2(u_char func1, u_char func2)
1862 {
1863 #if 000
1864 if (func1==read_long) return (-1);
1865 if (func1==read_long_prefetch) return (-1);
1866 if (func1==seek) return (-1);
1867 if (func1==audio_play) return (-1);
1868 if (func1!=ioctl_o) return (0);
1869 if (new_drive)
1870 {
1871 if (func2==EjectDisk) return (-1);
1872 if (func2==CloseTray) return (-1);
1873 }
1874 #else
1875 return (0);
1876 #endif 000
1877 }
1878
1879 static int check_allowed3(u_char func1, u_char func2)
1880 {
1881 #if 000
1882 if (func1==ioctl_i)
1883 {
1884 if (func2==tell_address) return (0);
1885 if (func2==tell_capabiliti) return (0);
1886 if (func2==tell_CD_changed) return (0);
1887 if (!new_drive) if (func2==tell_SubChanInfo) return (0);
1888 return (-1);
1889 }
1890 if (func1==ioctl_o)
1891 {
1892 if (func2==DriveReset) return (0);
1893 if (!new_drive)
1894 {
1895 if (func2==EjectDisk) return (0);
1896 if (func2==LockDoor) return (0);
1897 if (func2==CloseTray) return (0);
1898 }
1899 return (-1);
1900 }
1901 if (func1==flush_input) return (-1);
1902 if (func1==read_long) return (-1);
1903 if (func1==read_long_prefetch) return (-1);
1904 if (func1==seek) return (-1);
1905 if (func1==audio_play) return (-1);
1906 if (func1==audio_pause) return (-1);
1907 if (func1==audio_resume) return (-1);
1908 #else
1909 return (0);
1910 #endif 000
1911 }
1912
1913 static int seek_pos_audio_end(void)
1914 {
1915 int i;
1916
1917 i=msf2blk(DS[d].pos_audio_end)-1;
1918 if (i<0) return (-1);
1919 i=xx_Seek(i,0);
1920 return (i);
1921 }
1922
1923 static int ReadToC(void)
1924 {
1925 int i, j;
1926 DS[d].diskstate_flags &= ~toc_bit;
1927 DS[d].ored_ctl_adr=0;
1928 for (j=DS[d].n_first_track;j<=DS[d].n_last_track;j++)
1929 {
1930 i=xx_ReadTocEntry(j);
1931 if (i<0) return (i);
1932 DS[d].TocBuffer[j].nixbyte=DS[d].TocEnt_nixbyte;
1933 DS[d].TocBuffer[j].ctl_adr=DS[d].TocEnt_ctl_adr;
1934 DS[d].TocBuffer[j].number=DS[d].TocEnt_number;
1935 DS[d].TocBuffer[j].format=DS[d].TocEnt_format;
1936 DS[d].TocBuffer[j].address=DS[d].TocEnt_address;
1937 DS[d].ored_ctl_adr |= DS[d].TocEnt_ctl_adr;
1938 }
1939
1940 DS[d].TocBuffer[j].nixbyte=0;
1941 DS[d].TocBuffer[j].ctl_adr=0;
1942 DS[d].TocBuffer[j].number=0;
1943 DS[d].TocBuffer[j].format=0;
1944 DS[d].TocBuffer[j].address=DS[d].size_msf;
1945
1946 DS[d].diskstate_flags |= toc_bit;
1947 return (0);
1948 }
1949
1950 static int DiskInfo(void)
1951 {
1952 int i;
1953
1954 i=SetSpeed();
1955 if (i<0)
1956 {
1957 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first SetSpeed returns %d\n", i));
1958 i=SetSpeed();
1959 if (i<0)
1960 {
1961 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second SetSpeed returns %d\n", i));
1962 return (i);
1963 }
1964 }
1965 i=xx_ModeSense();
1966 if (i<0)
1967 {
1968 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first xx_ModeSense returns %d\n", i));
1969 i=xx_ModeSense();
1970 if (i<0)
1971 {
1972 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second xx_ModeSense returns %d\n", i));
1973 return (i);
1974 }
1975 return (i);
1976 }
1977 i=xx_ReadCapacity();
1978 if (i<0)
1979 {
1980 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first ReadCapacity returns %d\n", i));
1981 i=xx_ReadCapacity();
1982 if (i<0)
1983 {
1984 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second ReadCapacity returns %d\n", i));
1985 return (i);
1986 }
1987 return (i);
1988 }
1989 i=xx_ReadTocDescr();
1990 if (i<0)
1991 {
1992 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i));
1993 return (i);
1994 }
1995 i=ReadToC();
1996 if (i<0)
1997 {
1998 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i));
1999 return (i);
2000 }
2001 i=yy_CheckMultiSession();
2002 if (i<0)
2003 {
2004 DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i));
2005 return (i);
2006 }
2007 i=xx_ReadTocEntry(DS[d].n_first_track);
2008 if (i<0)
2009 {
2010 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadTocEntry(1) returns %d\n", i));
2011 return (i);
2012 }
2013 i=xx_ReadUPC();
2014 if (i<0)
2015 {
2016 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadUPC returns %d\n", i));
2017 return (i);
2018 }
2019 #ifdef XA_TEST2
2020 if ((!new_drive) && (DS[d].xa_byte==0x20))
2021 {
2022 xx_ModeSelect(CD_FRAMESIZE_XA);
2023 xx_ModeSense();
2024 }
2025 #endif XA_TEST2
2026
2027 return (0);
2028 }
2029
2030
2031
2032
2033
2034 static int prepare(u_char func, u_char subfunc)
2035 {
2036 int i;
2037
2038 if (!new_drive)
2039 {
2040 i=inb(CDi_status);
2041 if (i&s_attention) GetStatus();
2042 }
2043 else GetStatus();
2044 if (DS[d].CD_changed==0xFF)
2045 {
2046 #if MANY_SESSION
2047 #else
2048 DS[d].diskstate_flags=0;
2049 #endif MANY_SESSION
2050 DS[d].audio_state=0;
2051 if (!st_diskok)
2052 {
2053 i=check_allowed1(func,subfunc);
2054 if (i<0) return (-2);
2055 }
2056 else
2057 {
2058 i=check_allowed3(func,subfunc);
2059 if (i<0)
2060 {
2061 DS[d].CD_changed=1;
2062 return (-15);
2063 }
2064 }
2065 }
2066 else
2067 {
2068 if (!st_diskok)
2069 {
2070 #if MANY_SESSION
2071 #else
2072 DS[d].diskstate_flags=0;
2073 #endif MANY_SESSION
2074 DS[d].audio_state=0;
2075 i=check_allowed1(func,subfunc);
2076 if (i<0) return (-2);
2077 }
2078 else
2079 {
2080 if (st_busy)
2081 {
2082 if (DS[d].audio_state!=audio_pausing)
2083 {
2084 i=check_allowed2(func,subfunc);
2085 if (i<0) return (-2);
2086 }
2087 }
2088 else
2089 {
2090 if (DS[d].audio_state==audio_playing) seek_pos_audio_end();
2091 DS[d].audio_state=0;
2092 }
2093 if (!frame_size_valid)
2094 {
2095 i=DiskInfo();
2096 if (i<0)
2097 {
2098 #if MANY_SESSION
2099 #else
2100 DS[d].diskstate_flags=0;
2101 #endif MANY_SESSION
2102 DS[d].audio_state=0;
2103 i=check_allowed1(func,subfunc);
2104 if (i<0) return (-2);
2105 }
2106 }
2107 }
2108 }
2109 return (0);
2110 }
2111
2112 static int xx_PlayAudioMSF(int pos_audio_start,int pos_audio_end)
2113 {
2114 int i;
2115
2116 if (DS[d].audio_state==audio_playing) return (-EINVAL);
2117 clr_cmdbuf();
2118 if (new_drive)
2119 {
2120 drvcmd[0]=0x0E;
2121 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
2122 f_obey_p_check | f_wait_if_busy;
2123 }
2124 else
2125 {
2126 drvcmd[0]=0x0B;
2127 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2128 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2129 }
2130 drvcmd[1]=(pos_audio_start>>16)&0x00FF;
2131 drvcmd[2]=(pos_audio_start>>8)&0x00FF;
2132 drvcmd[3]=pos_audio_start&0x00FF;
2133 drvcmd[4]=(pos_audio_end>>16)&0x00FF;
2134 drvcmd[5]=(pos_audio_end>>8)&0x00FF;
2135 drvcmd[6]=pos_audio_end&0x00FF;
2136 response_count=0;
2137 i=cmd_out();
2138 return (i);
2139 }
2140
2141
2142
2143
2144
2145
2146
2147
2148 static int sbpcd_ioctl(struct inode *inode,struct file *file,
2149 u_int cmd, u_long arg)
2150 {
2151 int i, st;
2152
2153 DPRINTF((DBG_IO2,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
2154 MINOR(inode->i_rdev), cmd, arg));
2155 if (!inode) return (-EINVAL);
2156 i=MINOR(inode->i_rdev);
2157 if ( (i<0) || (i>=NR_SBPCD) )
2158 {
2159 printk("SBPCD: ioctl: bad device: %d\n", i);
2160 return (-ENODEV);
2161 }
2162 switch_drive(i);
2163
2164 st=GetStatus();
2165 if (st<0) return (-EIO);
2166
2167 if (!toc_valid)
2168 {
2169 i=DiskInfo();
2170 if (i<0) return (-EIO);
2171 }
2172
2173 DPRINTF((DBG_IO2,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
2174 switch (cmd)
2175 {
2176 case DDIOCSDBG:
2177 if (! suser()) return (-EPERM);
2178 i = verify_area(VERIFY_READ, (int *) arg, sizeof(int));
2179 if (i>=0) i=sbpcd_dbg_ioctl(arg,1);
2180 return (i);
2181
2182 case CDROMPAUSE:
2183 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPAUSE entered.\n"));
2184
2185
2186
2187
2188 switch (DS[d].audio_state)
2189 {
2190 case audio_playing:
2191 i=xx_Pause_Resume(1);
2192 if (i<0) return (-EIO);
2193 DS[d].audio_state=audio_pausing;
2194 i=xx_ReadSubQ();
2195 if (i<0) return (-EIO);
2196 DS[d].pos_audio_start=DS[d].SubQ_run_tot;
2197 return (0);
2198 case audio_pausing:
2199 i=xx_Seek(DS[d].pos_audio_start,1);
2200 if (i<0) return (-EIO);
2201 return (0);
2202 default:
2203 return (-EINVAL);
2204 }
2205
2206 case CDROMRESUME:
2207 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMRESUME entered.\n"));
2208
2209
2210
2211 if (DS[d].audio_state!=audio_pausing) return -EINVAL;
2212 i=xx_Pause_Resume(3);
2213 if (i<0) return (-EIO);
2214 DS[d].audio_state=audio_playing;
2215 return (0);
2216
2217 case CDROMPLAYMSF:
2218 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYMSF entered.\n"));
2219 if (DS[d].audio_state==audio_playing)
2220 {
2221 i=xx_Pause_Resume(1);
2222 if (i<0) return (-EIO);
2223 i=xx_ReadSubQ();
2224 if (i<0) return (-EIO);
2225 DS[d].pos_audio_start=DS[d].SubQ_run_tot;
2226 i=xx_Seek(DS[d].pos_audio_start,1);
2227 }
2228 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_msf));
2229 if (st) return (st);
2230 memcpy_fromfs(&msf, (void *) arg, sizeof(struct cdrom_msf));
2231
2232 DS[d].pos_audio_start = (msf.cdmsf_min0<<16) |
2233 (msf.cdmsf_sec0<<8) |
2234 msf.cdmsf_frame0;
2235 DS[d].pos_audio_end = (msf.cdmsf_min1<<16) |
2236 (msf.cdmsf_sec1<<8) |
2237 msf.cdmsf_frame1;
2238 DPRINTF((DBG_IOX,"SBPCD: ioctl: CDROMPLAYMSF %08X %08X\n",
2239 DS[d].pos_audio_start,DS[d].pos_audio_end));
2240 i=xx_PlayAudioMSF(DS[d].pos_audio_start,DS[d].pos_audio_end);
2241 DPRINTF((DBG_IOC,"SBPCD: ioctl: xx_PlayAudioMSF returns %d\n",i));
2242 #if 0
2243 if (i<0) return (-EIO);
2244 #endif 0
2245 DS[d].audio_state=audio_playing;
2246 return (0);
2247
2248 case CDROMPLAYTRKIND:
2249 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYTRKIND entered.\n"));
2250 if (DS[d].audio_state==audio_playing)
2251 {
2252 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: already audio_playing.\n"));
2253 return (0);
2254 return (-EINVAL);
2255 }
2256 st=verify_area(VERIFY_READ,(void *) arg,sizeof(struct cdrom_ti));
2257 if (st<0)
2258 {
2259 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: verify_area error.\n"));
2260 return (st);
2261 }
2262 memcpy_fromfs(&ti,(void *) arg,sizeof(struct cdrom_ti));
2263 DPRINTF((DBG_IOX,"SBPCD: ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
2264 ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1));
2265 if (ti.cdti_trk0<DS[d].n_first_track) return (-EINVAL);
2266 if (ti.cdti_trk0>DS[d].n_last_track) return (-EINVAL);
2267 if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
2268 if (ti.cdti_trk1>DS[d].n_last_track) ti.cdti_trk1=DS[d].n_last_track;
2269 DS[d].pos_audio_start=DS[d].TocBuffer[ti.cdti_trk0].address;
2270 DS[d].pos_audio_end=DS[d].TocBuffer[ti.cdti_trk1+1].address;
2271 i=xx_PlayAudioMSF(DS[d].pos_audio_start,DS[d].pos_audio_end);
2272 #if 0
2273 if (i<0) return (-EIO);
2274 #endif 0
2275 DS[d].audio_state=audio_playing;
2276 return (0);
2277
2278 case CDROMREADTOCHDR:
2279 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCHDR entered.\n"));
2280 tochdr.cdth_trk0=DS[d].n_first_track;
2281 tochdr.cdth_trk1=DS[d].n_last_track;
2282 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_tochdr));
2283 if (st) return (st);
2284 memcpy_tofs((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
2285 return (0);
2286
2287 case CDROMREADTOCENTRY:
2288 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCENTRY entered.\n"));
2289 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_tocentry));
2290 if (st) return (st);
2291 memcpy_fromfs(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
2292 i=tocentry.cdte_track;
2293 if (i==CDROM_LEADOUT) i=DS[d].n_last_track+1;
2294 else if (i<DS[d].n_first_track||i>DS[d].n_last_track) return (-EINVAL);
2295 tocentry.cdte_adr=DS[d].TocBuffer[i].ctl_adr&0x0F;
2296 tocentry.cdte_ctrl=(DS[d].TocBuffer[i].ctl_adr>>4)&0x0F;
2297 tocentry.cdte_datamode=DS[d].TocBuffer[i].format;
2298 if (tocentry.cdte_format==CDROM_MSF)
2299 { tocentry.cdte_addr.msf.minute=(DS[d].TocBuffer[i].address>>16)&0x00FF;
2300 tocentry.cdte_addr.msf.second=(DS[d].TocBuffer[i].address>>8)&0x00FF;
2301 tocentry.cdte_addr.msf.frame=DS[d].TocBuffer[i].address&0x00FF;
2302 }
2303 else if (tocentry.cdte_format==CDROM_LBA)
2304 tocentry.cdte_addr.lba=msf2blk(DS[d].TocBuffer[i].address);
2305 else return (-EINVAL);
2306 st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_tocentry));
2307 if (st) return (st);
2308 memcpy_tofs((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
2309 return (0);
2310
2311 case CDROMSTOP:
2312 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTOP entered.\n"));
2313 i=DriveReset();
2314 #if WORKMAN
2315 DS[d].CD_changed=0xFF;
2316 DS[d].diskstate_flags=0;
2317 #endif WORKMAN
2318 DPRINTF((DBG_IOC,"SBPCD: ioctl: DriveReset returns %d\n",i));
2319 DS[d].audio_state=0;
2320 i=DiskInfo();
2321 return (0);
2322
2323 case CDROMSTART:
2324 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTART entered.\n"));
2325 i=xx_SpinUp();
2326 DS[d].audio_state=0;
2327 return (0);
2328
2329 case CDROMEJECT:
2330 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT entered.\n"));
2331 if (!new_drive) return (0);
2332 #if WORKMAN
2333 DS[d].CD_changed=0xFF;
2334 DS[d].diskstate_flags=0;
2335 #endif WORKMAN
2336 i=yy_SpinDown();
2337 if (i<0) return (-EIO);
2338 DS[d].audio_state=0;
2339 return (0);
2340
2341 case CDROMVOLCTRL:
2342 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMVOLCTRL entered.\n"));
2343 st=verify_area(VERIFY_READ,(void *) arg,sizeof(volctrl));
2344 if (st) return (st);
2345 memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
2346 DS[d].vol_chan0=0;
2347 DS[d].vol_ctrl0=volctrl.channel0;
2348 DS[d].vol_chan1=1;
2349 DS[d].vol_ctrl1=volctrl.channel1;
2350 i=xx_SetVolume();
2351 return (0);
2352
2353 case CDROMSUBCHNL:
2354 DPRINTF((DBG_IOS,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
2355 if ((st_spinning)||(!subq_valid)) { i=xx_ReadSubQ();
2356 if (i<0) return (-EIO);
2357 }
2358 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
2359 if (st) return (st);
2360 memcpy_fromfs(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
2361 switch (DS[d].audio_state)
2362 {
2363 case audio_playing:
2364 SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
2365 break;
2366 case audio_pausing:
2367 SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
2368 break;
2369 default:
2370 SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
2371 break;
2372 }
2373 SC.cdsc_adr=DS[d].SubQ_ctl_adr;
2374 SC.cdsc_ctrl=DS[d].SubQ_ctl_adr>>4;
2375 SC.cdsc_trk=bcd2bin(DS[d].SubQ_trk);
2376 SC.cdsc_ind=bcd2bin(DS[d].SubQ_pnt_idx);
2377 if (SC.cdsc_format==CDROM_LBA)
2378 {
2379 SC.cdsc_absaddr.lba=msf2blk(DS[d].SubQ_run_tot);
2380 SC.cdsc_reladdr.lba=msf2blk(DS[d].SubQ_run_trk);
2381 }
2382 else
2383 {
2384 SC.cdsc_absaddr.msf.minute=(DS[d].SubQ_run_tot>>16)&0x00FF;
2385 SC.cdsc_absaddr.msf.second=(DS[d].SubQ_run_tot>>8)&0x00FF;
2386 SC.cdsc_absaddr.msf.frame=DS[d].SubQ_run_tot&0x00FF;
2387 SC.cdsc_reladdr.msf.minute=(DS[d].SubQ_run_trk>>16)&0x00FF;
2388 SC.cdsc_reladdr.msf.second=(DS[d].SubQ_run_trk>>8)&0x00FF;
2389 SC.cdsc_reladdr.msf.frame=DS[d].SubQ_run_trk&0x00FF;
2390 }
2391 memcpy_tofs((void *) arg, &SC, sizeof(struct cdrom_subchnl));
2392 DPRINTF((DBG_IOS,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
2393 SC.cdsc_format,SC.cdsc_audiostatus,
2394 SC.cdsc_adr,SC.cdsc_ctrl,
2395 SC.cdsc_trk,SC.cdsc_ind,
2396 SC.cdsc_absaddr,SC.cdsc_reladdr));
2397 return (0);
2398
2399 case CDROMREADMODE2:
2400 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n"));
2401 return (-EINVAL);
2402
2403 case CDROMREADMODE1:
2404 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE1 requested.\n"));
2405 return (-EINVAL);
2406
2407 default:
2408 DPRINTF((DBG_IOC,"SBPCD: ioctl: unknown function request %04X\n", cmd));
2409 return (-EINVAL);
2410 }
2411 }
2412
2413
2414
2415
2416
2417 static void sbp_transfer(void)
2418 {
2419 long offs;
2420
2421 while ( (CURRENT->nr_sectors > 0) &&
2422 (CURRENT->sector/4 >= DS[d].sbp_first_frame) &&
2423 (CURRENT->sector/4 <= DS[d].sbp_last_frame) )
2424 {
2425 offs = (CURRENT->sector - DS[d].sbp_first_frame * 4) * 512;
2426 memcpy(CURRENT->buffer, DS[d].sbp_buf + offs, 512);
2427 CURRENT->nr_sectors--;
2428 CURRENT->sector++;
2429 CURRENT->buffer += 512;
2430 }
2431 }
2432
2433
2434
2435
2436 #if SBPCD_USE_IRQ
2437 static void sbpcd_interrupt(int unused)
2438 {
2439 int st;
2440
2441 st = inb(CDi_status) & 0xFF;
2442 DPRINTF((DBG_IRQ,"SBPCD: INTERRUPT received - CDi_status=%02X\n", st));
2443 }
2444 #endif SBPCD_USE_IRQ
2445
2446
2447
2448
2449 static int sbp_status(void)
2450 {
2451 int st;
2452
2453 st=ResponseStatus();
2454 if (st<0)
2455 {
2456 DPRINTF((DBG_INF,"SBPCD: sbp_status: timeout.\n"));
2457 return (0);
2458 }
2459
2460 if (!st_spinning) DPRINTF((DBG_SPI,"SBPCD: motor got off - ignoring.\n"));
2461
2462 if (st_check)
2463 {
2464 DPRINTF((DBG_INF,"SBPCD: st_check detected - retrying.\n"));
2465 return (0);
2466 }
2467 if (!st_door_closed)
2468 {
2469 DPRINTF((DBG_INF,"SBPCD: door is open - retrying.\n"));
2470 return (0);
2471 }
2472 if (!st_caddy_in)
2473 {
2474 DPRINTF((DBG_INF,"SBPCD: disk removed - retrying.\n"));
2475 return (0);
2476 }
2477 if (!st_diskok)
2478 {
2479 DPRINTF((DBG_INF,"SBPCD: !st_diskok detected - retrying.\n"));
2480 return (0);
2481 }
2482 if (st_busy)
2483 {
2484 DPRINTF((DBG_INF,"SBPCD: st_busy detected - retrying.\n"));
2485 return (0);
2486 }
2487 return (1);
2488 }
2489
2490
2491
2492
2493 static void do_sbpcd_request(void)
2494 {
2495 u_int block;
2496 int dev;
2497 u_int nsect;
2498 int i, status_tries, data_tries;
2499
2500 request_loop:
2501
2502 sti();
2503
2504 if ((CURRENT==NULL)||(CURRENT->dev<0)) return;
2505 if (CURRENT -> sector == -1) return;
2506
2507 dev = MINOR(CURRENT->dev);
2508 if ( (dev<0) || (dev>=NR_SBPCD) )
2509 {
2510 printk("SBPCD: do_request: bad device: %d\n", dev);
2511 return;
2512 }
2513 switch_drive(dev);
2514
2515 INIT_REQUEST;
2516 block = CURRENT->sector;
2517 nsect = CURRENT->nr_sectors;
2518
2519 if (CURRENT->cmd != READ)
2520 {
2521 printk("SBPCD: bad cmd %d\n", CURRENT->cmd);
2522 end_request(0);
2523 goto request_loop;
2524 }
2525
2526 DPRINTF((DBG_MUL,"SBPCD: read LBA %d\n", block/4));
2527 sbp_transfer();
2528
2529
2530
2531 if (CURRENT->nr_sectors == 0)
2532 {
2533 end_request(1);
2534 goto request_loop;
2535 }
2536
2537 i=prepare(0,0);
2538 if (i!=0) DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i));
2539
2540 if (!st_spinning) xx_SpinUp();
2541
2542 #ifdef XA_TEST1
2543 if ((!new_drive) && (DS[d].xa_byte==0x20))
2544 {
2545 xx_ModeSelect(CD_FRAMESIZE_XA);
2546 xx_ModeSense();
2547 }
2548 #endif XA_TEST1
2549
2550 for (data_tries=3; data_tries > 0; data_tries--)
2551 {
2552 for (status_tries=3; status_tries > 0; status_tries--)
2553 {
2554 flags_cmd_out |= f_respo3;
2555 xx_ReadStatus();
2556 if (sbp_status() != 0) break;
2557 sbp_sleep(1);
2558 }
2559 if (status_tries == 0)
2560 {
2561 DPRINTF((DBG_INF,"SBPCD: sbp_status: failed after 3 tries\n"));
2562 break;
2563 }
2564
2565 sbp_read_cmd();
2566 sbp_sleep(0);
2567 if (sbp_data() != 0)
2568 {
2569 end_request(1);
2570 goto request_loop;
2571 }
2572 }
2573
2574 end_request(0);
2575 sbp_sleep(10);
2576 goto request_loop;
2577 }
2578
2579
2580
2581
2582
2583 static void sbp_read_cmd(void)
2584 {
2585 int i;
2586 int block;
2587
2588 DS[d].sbp_first_frame=DS[d].sbp_last_frame=-1;
2589 block=CURRENT->sector/4;
2590
2591 if (new_drive)
2592 {
2593 #if MANY_SESSION
2594 DPRINTF((DBG_MUL,"SBPCD: read MSF %08X\n", blk2msf(block)));
2595 if ( (DS[d].f_multisession) && (multisession_valid) )
2596 {
2597 DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
2598 blk2msf(DS[d].lba_multi+block),
2599 blk2msf(block)));
2600 block=DS[d].lba_multi+block;
2601 }
2602 #else
2603 if ( (block==166) && (DS[d].f_multisession) && (multisession_valid) )
2604 {
2605 DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
2606 blk2msf(DS[d].lba_multi+16),
2607 blk2msf(block)));
2608 block=DS[d].lba_multi+16;
2609 }
2610 #endif MANY_SESSION
2611 }
2612
2613 if (block+SBP_BUFFER_FRAMES <= DS[d].CDsize_frm)
2614 DS[d].sbp_read_frames = SBP_BUFFER_FRAMES;
2615 else
2616 {
2617 DS[d].sbp_read_frames=DS[d].CDsize_frm-block;
2618
2619 if (DS[d].sbp_read_frames < 1)
2620 {
2621 DPRINTF((DBG_INF,"SBPCD: requested frame %d, CD size %d ???\n",
2622 block, DS[d].CDsize_frm));
2623 DS[d].sbp_read_frames=1;
2624 }
2625 }
2626 DS[d].sbp_current = 0;
2627
2628 flags_cmd_out = f_putcmd |
2629 f_respo2 |
2630 f_ResponseStatus |
2631 f_obey_p_check;
2632
2633 if (!new_drive)
2634 {
2635 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
2636 if (DS[d].xa_byte==0x20)
2637 {
2638 cmd_type=READ_M2;
2639 drvcmd[0]=0x03;
2640 drvcmd[1]=(block>>16)&0x000000ff;
2641 drvcmd[2]=(block>>8)&0x000000ff;
2642 drvcmd[3]=block&0x000000ff;
2643 drvcmd[4]=0;
2644 drvcmd[5]=DS[d].sbp_read_frames;
2645 drvcmd[6]=0;
2646 }
2647 else
2648 {
2649 drvcmd[0]=0x02;
2650
2651 if (DS[d].drv_type>=drv_201)
2652 {
2653 lba2msf(block,&drvcmd[1]);
2654 bin2bcdx(&drvcmd[1]);
2655 bin2bcdx(&drvcmd[2]);
2656 bin2bcdx(&drvcmd[3]);
2657 }
2658 else
2659 {
2660 drvcmd[1]=(block>>16)&0x000000ff;
2661 drvcmd[2]=(block>>8)&0x000000ff;
2662 drvcmd[3]=block&0x000000ff;
2663 }
2664 drvcmd[4]=0;
2665 drvcmd[5]=DS[d].sbp_read_frames;
2666 drvcmd[6]=(DS[d].drv_type<drv_201)?0:2;
2667 }
2668 }
2669 else
2670 {
2671 drvcmd[0]=0x10;
2672 lba2msf(block,&drvcmd[1]);
2673 drvcmd[4]=0;
2674 drvcmd[5]=0;
2675 drvcmd[6]=DS[d].sbp_read_frames;
2676 }
2677 #if SBPCD_DIS_IRQ
2678 cli();
2679 #endif SBPCD_DIS_IRQ
2680 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
2681 #if SBPCD_DIS_IRQ
2682 sti();
2683 #endif SBPCD_DIS_IRQ
2684
2685 return;
2686 }
2687
2688
2689
2690
2691
2692 static int sbp_data(void)
2693 {
2694 int i=0, j=0, frame;
2695 u_int try=0;
2696 u_long timeout;
2697 u_char *p;
2698 u_int data_tries = 0;
2699 u_int data_waits = 0;
2700 u_int data_retrying = 0;
2701 int error_flag;
2702 int xa_count;
2703 error_flag=0;
2704
2705 for (frame=DS[d].sbp_current;frame<DS[d].sbp_read_frames&&!error_flag; frame++)
2706 {
2707 #if SBPCD_DIS_IRQ
2708 cli();
2709 #endif SBPCD_DIS_IRQ
2710 try=maxtim_data;
2711 #if LONG_TIMING
2712 for (timeout=jiffies+900; ; )
2713 #else
2714 for (timeout=jiffies+100; ; )
2715 #endif
2716 {
2717 for ( ; try!=0;try--)
2718 {
2719 j=inb(CDi_status);
2720 if (!(j&s_not_data_ready)) break;
2721 if (!(j&s_not_result_ready)) break;
2722 if (!new_drive) if (j&s_attention) break;
2723 }
2724 if (try != 0 || timeout <= jiffies) break;
2725 if (data_retrying == 0) data_waits++;
2726 data_retrying = 1;
2727 sbp_sleep(1);
2728 try = 1;
2729 }
2730 if (try==0)
2731 {
2732 DPRINTF((DBG_INF,"SBPCD: sbp_data: CDi_status timeout.\n"));
2733 error_flag++;
2734 break;
2735 }
2736
2737 if (j&s_not_data_ready)
2738 {
2739 if ((DS[d].ored_ctl_adr&0x40)==0)
2740 printk("SBPCD: CD contains no data tracks.\n");
2741 else printk("SBPCD: sbp_data: DATA_READY timeout.\n");
2742 error_flag++;
2743 break;
2744 }
2745
2746 #if SBPCD_DIS_IRQ
2747 sti();
2748 #endif SBPCD_DIS_IRQ
2749
2750 CLEAR_TIMER;
2751 error_flag=0;
2752 p = DS[d].sbp_buf + frame * CD_FRAMESIZE;
2753
2754 if (sbpro_type) OUT(CDo_sel_d_i,0x01);
2755 if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_head_buf, CD_XA_HEAD);
2756 READ_DATA(CDi_data, p, CD_FRAMESIZE);
2757 if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_tail_buf, CD_XA_TAIL);
2758 if (sbpro_type) OUT(CDo_sel_d_i,0x00);
2759 DS[d].sbp_current++;
2760 if (cmd_type==READ_M2)
2761 {
2762 DPRINTF((DBG_XA,"SBPCD: xa_head:"));
2763 for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
2764 DPRINTF((DBG_XA," %02X", xa_head_buf[xa_count]));
2765 DPRINTF((DBG_XA,"\n"));
2766 }
2767 data_tries++;
2768 data_retrying = 0;
2769 if (data_tries >= 1000)
2770 {
2771 DPRINTF((DBG_INF,"SBPCD: info: %d waits in %d frames.\n",
2772 data_waits, data_tries));
2773 data_waits = data_tries = 0;
2774 }
2775 }
2776 #if SBPCD_DIS_IRQ
2777 sti();
2778 #endif SBPCD_DIS_IRQ
2779
2780 if (error_flag)
2781 {
2782 DPRINTF((DBG_INF,"SBPCD: read aborted by drive\n"));
2783 i=DriveReset();
2784 return (0);
2785 }
2786
2787 if (!new_drive)
2788 {
2789 #if SBPCD_DIS_IRQ
2790 cli();
2791 #endif SBPCD_DIS_IRQ
2792 i=maxtim_data;
2793 for (timeout=jiffies+100; timeout > jiffies; timeout--)
2794 {
2795 for ( ;i!=0;i--)
2796 {
2797 j=inb(CDi_status);
2798 if (!(j&s_not_data_ready)) break;
2799 if (!(j&s_not_result_ready)) break;
2800 if (j&s_attention) break;
2801 }
2802 if (i != 0 || timeout <= jiffies) break;
2803 sbp_sleep(0);
2804 i = 1;
2805 }
2806 if (i==0) { DPRINTF((DBG_INF,"SBPCD: STATUS TIMEOUT AFTER READ")); }
2807 if (!(j&s_attention))
2808 {
2809 DPRINTF((DBG_INF,"SBPCD: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
2810 i=DriveReset();
2811 #if SBPCD_DIS_IRQ
2812 sti();
2813 #endif SBPCD_DIS_IRQ
2814 return (0);
2815 }
2816 #if SBPCD_DIS_IRQ
2817 sti();
2818 #endif SBPCD_DIS_IRQ
2819 }
2820
2821 do
2822 {
2823 if (!new_drive) xx_ReadStatus();
2824 i=ResponseStatus();
2825 if (i<0) { DPRINTF((DBG_INF,"SBPCD: xx_ReadStatus error after read: %02X\n",
2826 DS[d].status_byte));
2827 return (0);
2828 }
2829 }
2830 while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
2831 if (st_check)
2832 {
2833 i=xx_ReadError();
2834 DPRINTF((DBG_INF,"SBPCD: xx_ReadError was necessary after read: %02X\n",i));
2835 return (0);
2836 }
2837
2838 DS[d].sbp_first_frame = CURRENT -> sector / 4;
2839 DS[d].sbp_last_frame = DS[d].sbp_first_frame + DS[d].sbp_read_frames - 1;
2840 sbp_transfer();
2841 return (1);
2842 }
2843
2844
2845
2846
2847
2848 int sbpcd_open(struct inode *ip, struct file *fp)
2849 {
2850 int i;
2851
2852 if (ndrives==0) return (-ENXIO);
2853
2854 i = MINOR(ip->i_rdev);
2855 if ( (i<0) || (i>=NR_SBPCD) )
2856 {
2857 printk("SBPCD: open: bad device: %d\n", i);
2858 return (-ENODEV);
2859 }
2860 switch_drive(i);
2861
2862 if (!st_spinning) xx_SpinUp();
2863
2864 flags_cmd_out |= f_respo2;
2865 xx_ReadStatus();
2866 i=ResponseStatus();
2867 if (i<0)
2868 {
2869 DPRINTF((DBG_INF,"SBPCD: sbpcd_open: xx_ReadStatus timed out\n"));
2870 return (-EIO);
2871 }
2872 DPRINTF((DBG_STA,"SBPCD: sbpcd_open: status %02X\n", DS[d].status_byte));
2873 if (!st_door_closed||!st_caddy_in)
2874 {
2875 printk("SBPCD: sbpcd_open: no disk in drive\n");
2876 return (-EIO);
2877 }
2878
2879
2880
2881
2882 DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
2883 DS[d].open_count,DS[d].open_count+1));
2884 if (++DS[d].open_count==1) yy_LockDoor(1);
2885
2886 if (!st_spinning) xx_SpinUp();
2887
2888 i=DiskInfo();
2889 if ((DS[d].ored_ctl_adr&0x40)==0)
2890 DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
2891 return (0);
2892 }
2893
2894
2895
2896
2897 static void sbpcd_release(struct inode * ip, struct file * file)
2898 {
2899 int i;
2900
2901 i = MINOR(ip->i_rdev);
2902 if ( (i<0) || (i>=NR_SBPCD) )
2903 {
2904 printk("SBPCD: release: bad device: %d\n", i);
2905 return;
2906 }
2907 switch_drive(i);
2908
2909 DS[d].sbp_first_frame=DS[d].sbp_last_frame=-1;
2910 sync_dev(ip->i_rdev);
2911 invalidate_buffers(ip->i_rdev);
2912 DS[d].diskstate_flags &= ~cd_size_bit;
2913
2914
2915
2916
2917 DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
2918 DS[d].open_count,DS[d].open_count-1));
2919 if (--DS[d].open_count==0) yy_LockDoor(0);
2920 }
2921
2922
2923
2924
2925 static struct file_operations sbpcd_fops =
2926 {
2927 NULL,
2928 block_read,
2929 block_write,
2930 NULL,
2931 NULL,
2932 sbpcd_ioctl,
2933 NULL,
2934 sbpcd_open,
2935 sbpcd_release
2936 };
2937
2938
2939
2940
2941 #if SBPCD_USE_IRQ
2942 static struct sigaction sbpcd_sigaction =
2943 {
2944 sbpcd_interrupt,
2945 0,
2946 SA_INTERRUPT,
2947 NULL
2948 };
2949 #endif SBPCD_USE_IRQ
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966 void sbpcd_setup(char *s, int *p)
2967 {
2968 DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s));
2969 if (!strcmp(s,str_sb)) sbpro_type=1;
2970 else sbpro_type=0;
2971 if (p[0]>0) sbpcd_ioaddr=p[1];
2972
2973 CDo_command=sbpcd_ioaddr;
2974 CDi_info=sbpcd_ioaddr;
2975 CDi_status=sbpcd_ioaddr+1;
2976 CDo_reset=sbpcd_ioaddr+2;
2977 CDo_enable=sbpcd_ioaddr+3;
2978 if (sbpro_type==1)
2979 {
2980 MIXER_addr=sbpcd_ioaddr-0x10+0x04;
2981 MIXER_data=sbpcd_ioaddr-0x10+0x05;
2982 CDo_sel_d_i=sbpcd_ioaddr+1;
2983 CDi_data=sbpcd_ioaddr;
2984 }
2985 else CDi_data=sbpcd_ioaddr+2;
2986 }
2987
2988
2989
2990
2991 u_long sbpcd_init(u_long mem_start, u_long mem_end)
2992 {
2993 int i=0, j=0;
2994 int addr[2]={1, CDROM_PORT};
2995 int port_index;
2996
2997 DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION));
2998
2999 DPRINTF((DBG_INF,"SBPCD: Looking for a SoundBlaster/Matsushita CD-ROM drive\n"));
3000 DPRINTF((DBG_WRN,"SBPCD: \n"));
3001 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = W A R N I N G = = = = = = = = = =\n"));
3002 DPRINTF((DBG_WRN,"SBPCD: Auto-Probing can cause a hang (f.e. touching an ethernet card).\n"));
3003 DPRINTF((DBG_WRN,"SBPCD: If that happens, you have to reboot and use the\n"));
3004 DPRINTF((DBG_WRN,"SBPCD: LILO (kernel) command line feature like:\n"));
3005 DPRINTF((DBG_WRN,"SBPCD: \n"));
3006 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x230,SoundBlaster\n"));
3007 DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
3008 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x300,LaserMate\n"));
3009 DPRINTF((DBG_WRN,"SBPCD: \n"));
3010 DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n"));
3011 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n"));
3012 DPRINTF((DBG_WRN,"SBPCD: \n"));
3013 sti();
3014
3015 autoprobe[0]=sbpcd_ioaddr;
3016 autoprobe[1]=sbpro_type;
3017
3018 for (port_index=0;port_index<NUM_AUTOPROBE;port_index+=2)
3019 {
3020 addr[1]=autoprobe[port_index];
3021 if (check_region(addr[1],4)) continue;
3022 DPRINTF((DBG_INI,"SBPCD: check_region done.\n"));
3023 if (autoprobe[port_index+1]==0) type=str_lm;
3024 else type=str_sb;
3025 sbpcd_setup(type, addr);
3026 DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n",
3027 type, CDo_command));
3028
3029 DPRINTF((DBG_INF,"SBPCD: - "));
3030 sti();
3031 i=check_drives();
3032 DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
3033 sti();
3034 if (i>=0) break;
3035 DPRINTF((DBG_INF,"\n"));
3036 sti();
3037 }
3038
3039 if (ndrives==0)
3040 {
3041 printk("SBPCD: No drive found.\n");
3042 sti();
3043 return (mem_start);
3044 }
3045
3046 if (port_index>0)
3047 {
3048 printk("SBPCD: You should configure sbpcd.h for your hardware.\n");
3049 sti();
3050 }
3051
3052 printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
3053 ndrives, type, CDo_command);
3054 sti();
3055 check_datarate();
3056 DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
3057 sti();
3058
3059 for (j=0;j<NR_SBPCD;j++)
3060 {
3061 if (DS[j].drv_minor==-1) continue;
3062 switch_drive(j);
3063 xy_DriveReset();
3064 if (!st_spinning) xx_SpinUp();
3065 DS[d].sbp_first_frame = -1;
3066 DS[d].sbp_last_frame = -1;
3067 DS[d].sbp_read_frames = 0;
3068 DS[d].sbp_current = 0;
3069 DS[d].CD_changed=1;
3070 DS[d].frame_size=CD_FRAMESIZE;
3071
3072 xx_ReadStatus();
3073 i=ResponseStatus();
3074 if (i<0)
3075 DPRINTF((DBG_INF,"SBPCD: init: ResponseStatus returns %02X\n",i));
3076 else
3077 {
3078 if (st_check)
3079 {
3080 i=xx_ReadError();
3081 DPRINTF((DBG_INI,"SBPCD: init: xx_ReadError returns %d\n",i));
3082 sti();
3083 }
3084 }
3085 DPRINTF((DBG_INI,"SBPCD: init: first GetStatus: %d\n",i));
3086 sti();
3087 if (DS[d].error_byte==aud_12)
3088 {
3089 do { i=GetStatus();
3090 DPRINTF((DBG_INI,"SBPCD: init: second GetStatus: %02X\n",i));
3091 sti();
3092 if (i<0) break;
3093 if (!st_caddy_in) break;
3094 }
3095 while (!st_diskok);
3096 }
3097 i=SetSpeed();
3098 if (i>=0) DS[d].CD_changed=1;
3099 }
3100
3101 if (sbpro_type)
3102 {
3103 OUT(MIXER_addr,MIXER_CD_Volume);
3104 OUT(MIXER_data,0xCC);
3105 }
3106
3107 if (register_blkdev(MATSUSHITA_CDROM_MAJOR, "sbpcd", &sbpcd_fops) != 0)
3108 {
3109 printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n",
3110 MATSUSHITA_CDROM_MAJOR);
3111 sti();
3112 return (mem_start);
3113 }
3114 blk_dev[MATSUSHITA_CDROM_MAJOR].request_fn = DEVICE_REQUEST;
3115 read_ahead[MATSUSHITA_CDROM_MAJOR] = 4;
3116
3117 snarf_region(CDo_command,4);
3118
3119 #if SBPCD_USE_IRQ
3120 if (irqaction(SBPCD_INTR_NR, &sbpcd_sigaction))
3121 {
3122 printk("SBPCD: Can't get IRQ%d for sbpcd driver\n", SBPCD_INTR_NR);
3123 sti();
3124 }
3125 #endif SBPCD_USE_IRQ
3126
3127
3128
3129
3130 for (j=0;j<NR_SBPCD;j++)
3131 {
3132 if (DS[j].drv_minor==-1) continue;
3133 DS[j].sbp_buf=(u_char *)mem_start;
3134 mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE;
3135 }
3136 DPRINTF((DBG_INF,"SBPCD: init done.\n"));
3137 sti();
3138 return (mem_start);
3139 }
3140
3141
3142
3143
3144
3145
3146
3147
3148 int check_sbpcd_media_change(int full_dev, int unused_minor)
3149 {
3150 int st;
3151
3152 if (MAJOR(full_dev) != MATSUSHITA_CDROM_MAJOR)
3153 {
3154 printk("SBPCD: media_check: invalid device.\n");
3155 return (-1);
3156 }
3157
3158 xx_ReadStatus();
3159 st=ResponseStatus();
3160 DPRINTF((DBG_CHK,"SBPCD: media_check: %02X\n",DS[d].status_byte));
3161 if (st<0)
3162 {
3163 DPRINTF((DBG_INF,"SBPCD: media_check: ResponseStatus error.\n"));
3164 return (1);
3165 }
3166 if (DS[d].CD_changed==0xFF) DPRINTF((DBG_CHK,"SBPCD: media_check: \"changed\" assumed.\n"));
3167 if (!st_spinning) DPRINTF((DBG_CHK,"SBPCD: media_check: motor off.\n"));
3168 if (!st_door_closed)
3169 {
3170 DPRINTF((DBG_CHK,"SBPCD: media_check: door open.\n"));
3171 DS[d].CD_changed=0xFF;
3172 }
3173 if (!st_caddy_in)
3174 {
3175 DPRINTF((DBG_CHK,"SBPCD: media_check: no disk in drive.\n"));
3176 DS[d].CD_changed=0xFF;
3177 }
3178 if (!st_diskok) DPRINTF((DBG_CHK,"SBPCD: media_check: !st_diskok.\n"));
3179
3180 #if 0000
3181 if (DS[d].CD_changed==0xFF)
3182 {
3183 DS[d].CD_changed=1;
3184 return (1);
3185 }
3186 #endif 0000
3187
3188 if (!st_diskok) return (1);
3189 if (!st_caddy_in) return (1);
3190 if (!st_door_closed) return (1);
3191 return (0);
3192 }
3193