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