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