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