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