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