* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-0.99 / drivers / block / sbpcd.c
blob3312e7f298df31bc7695443418d63e767becebec
1 /*
2 * sbpcd.c CD-ROM device driver for the whole family of IDE-style
3 * Kotobuki/Matsushita/Panasonic CR-5xx drives for
4 * SoundBlaster ("Pro" or "16 ASP" or compatible) cards
5 * and for "no-sound" interfaces like Lasermate and the
6 * Panasonic CI-101P.
8 * NOTE: This is release 1.2.
9 * It works with my SbPro & drive CR-521 V2.11 from 2/92
10 * and with the new CR-562-B V0.75 on a "naked" Panasonic
11 * CI-101P interface. And vice versa.
14 * VERSION HISTORY
16 * 0.1 initial release, April/May 93, after mcd.c
18 * 0.2 the "repeat:"-loop in do_sbpcd_request did not check for
19 * end-of-request_queue (resulting in kernel panic).
20 * Flow control seems stable, but throughput is not better.
22 * 0.3 interrupt locking totally eliminated (maybe "inb" and "outb"
23 * are still locking) - 0.2 made keyboard-type-ahead losses.
24 * check_sbpcd_media_change added (to use by isofs/inode.c)
25 * - but it detects almost nothing.
27 * 0.4 use MAJOR 25 definitely.
28 * Almost total re-design to support double-speed drives and
29 * "naked" (no sound) interface cards.
30 * Flow control should be exact now (tell me if not).
31 * Don't occupy the SbPro IRQ line (not needed either); will
32 * live together with Hannu Savolainen's sndkit now.
33 * Speeded up data transfer to 150 kB/sec, with help from Kai
34 * Makisara, the "provider" of the "mt" tape utility.
35 * Give "SpinUp" command if necessary.
36 * First steps to support up to 4 drives (but currently only one).
37 * Implemented audio capabilities - workman should work, xcdplayer
38 * gives some problems.
39 * This version is still consuming too much CPU time, and
40 * sleeping still has to be worked on.
41 * During "long" implied seeks, it seems possible that a
42 * ReadStatus command gets ignored. That gives the message
43 * "ResponseStatus timed out" (happens about 6 times here during
44 * a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
45 * handled without data error, but it should get done better.
47 * 0.5 Free CPU during waits (again with help from Kai Makisara).
48 * Made it work together with the LILO/kernel setup standard.
49 * Included auto-probing code, as suggested by YGGDRASIL.
50 * Formal redesign to add DDI debugging.
51 * There are still flaws in IOCTL (workman with double speed drive).
53 * 1.0 Added support for all drive ids (0...3, no longer only 0)
54 * and up to 4 drives on one controller.
55 * Added "#define MANY_SESSION" for "old" multi session CDs.
57 * 1.1 Do SpinUp for new drives, too.
58 * Revised for clean compile under "old" kernels (pl9).
60 * 1.2 Found the "workman with double-speed drive" bug: use the driver's
61 * audio_state, not what the drive is reporting with ReadSubQ.
65 * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
66 * elaborated speed-up experiments (and the fabulous results!), for
67 * the "push" towards load-free wait loops, and for the extensive mail
68 * thread which brought additional hints and bug fixes.
71 * Copyright (C) 1993, 1994 Eberhard Moenkeberg <emoenke@gwdg.de>
72 * or <eberhard_moenkeberg@rollo.central.de>
74 * The FTP-home of this driver is
75 * ftp.gwdg.de:/pub/linux/cdrom/drivers/sbpcd/.
77 * If you change this software, you should mail a .diff
78 * file with some description lines to emoenke@gwdg.de.
79 * I want to know about it.
81 * If you are the editor of a Linux CD, you should
82 * enable sbpcd.c within your boot floppy kernel and
83 * send me one of your CDs for free.
85 * This program is free software; you can redistribute it and/or modify
86 * it under the terms of the GNU General Public License as published by
87 * the Free Software Foundation; either version 2, or (at your option)
88 * any later version.
90 * You should have received a copy of the GNU General Public License
91 * (for example /usr/src/linux/COPYING); if not, write to the Free
92 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
95 #ifndef PATCHLEVEL
96 #define PATCHLEVEL 9
97 #endif
99 #include <linux/config.h>
100 #include <linux/errno.h>
102 #if SBPCD_USE_IRQ
103 #include <linux/signal.h>
104 #endif SBPCD_USE_IRQ
106 #include <linux/sched.h>
107 #include <linux/timer.h>
108 #include <linux/fs.h>
109 #include <linux/kernel.h>
110 #include <linux/cdrom.h>
111 #include <linux/ioport.h>
112 #include <linux/sbpcd.h>
114 #if PATCHLEVEL>13
115 #include <linux/ddi.h>
116 #include <linux/major.h>
117 #else
118 #define DDIOCSDBG 0x9000
119 #define MATSUSHITA_CDROM_MAJOR 25
120 #endif
122 #include <asm/system.h>
123 #include <asm/io.h>
124 #include <asm/segment.h>
125 #include <stdarg.h>
127 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
128 #include "blk.h"
130 #define VERSION "1.2"
132 #define SBPCD_DEBUG
134 #ifndef CONFIG_SBPCD
135 #error "SBPCD: \"make config\" again. Enable Matsushita/Panasonic CDROM support"
136 #endif
138 #ifndef CONFIG_ISO9660_FS
139 #error "SBPCD: \"make config\" again. File system iso9660 is necessary."
140 #endif
143 * still testing around...
145 #define MANY_SESSION 0
146 #define CDMKE
147 #undef FUTURE
148 #define WORKMAN 0 /* some testing stuff to make it better */
150 /*==========================================================================*/
151 /*==========================================================================*/
153 * auto-probing address list
154 * inspired by Adam J. Richter from Yggdrasil
156 * still not good enough - can cause a hang.
157 * example: a NE 2000 ehernet card at 300 will cause a hang probing 310.
158 * if that happens, reboot and use the LILO (kernel) command line.
159 * the conflicting possible ethernet card addresses get probed last - to
160 * minimize the hang possibilities.
162 * The SB Pro addresses get "mirrored" at 0x6xx - to avoid a type error,
163 * the 0x2xx-addresses must get checked before 0x6xx.
165 * what are other cards' default and range ???
166 * what about ESCOM PowerSound???
167 * what about HighScreen???
169 static int autoprobe[] =
171 CDROM_PORT, SBPRO, /* probe with user's setup first */
172 0x230, 1, /* Soundblaster Pro and 16 (default) */
173 0x300, 0, /* CI-101P (default), Galaxy (default), Reveal (one default) */
174 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
175 0x260, 1, /* OmniCD */
176 0x320, 0, /* Lasermate, CI-101P, Galaxy, Reveal (other default) */
177 0x340, 0, /* Lasermate, CI-101P */
178 0x360, 0, /* Lasermate, CI-101P */
179 0x270, 1, /* Soundblaster 16 */
180 0x630, 0, /* "sound card #9" (default) */
181 0x650, 0, /* "sound card #9" */
182 0x670, 0, /* "sound card #9" */
183 0x690, 0, /* "sound card #9" */
184 0x330, 0, /* Lasermate, CI-101P */
185 0x350, 0, /* Lasermate, CI-101P */
186 0x370, 0, /* Lasermate, CI-101P */
187 0x290, 1, /* Soundblaster 16 */
188 0x310, 0, /* Lasermate, CI-101P */
191 #define NUM_AUTOPROBE (sizeof(autoprobe) / sizeof(int))
194 /*==========================================================================*/
196 * the forward references:
198 static void sbp_read_cmd(void);
199 static int sbp_data(void);
201 /*==========================================================================*/
204 * pattern for printk selection:
206 * (1<<DBG_INF) necessary information
207 * (1<<DBG_IRQ) interrupt trace
208 * (1<<DBG_REA) "read" status trace
209 * (1<<DBG_CHK) "media check" trace
210 * (1<<DBG_TIM) datarate timer test
211 * (1<<DBG_INI) initialization trace
212 * (1<<DBG_TOC) tell TocEntry values
213 * (1<<DBG_IOC) ioctl trace
214 * (1<<DBG_STA) "ResponseStatus" trace
215 * (1<<DBG_ERR) "xx_ReadError" trace
216 * (1<<DBG_CMD) "cmd_out" trace
217 * (1<<DBG_WRN) give explanation before auto-probing
218 * (1<<DBG_MUL) multi session code test
219 * (1<<DBG_ID) "drive_id != 0" test code
220 * (1<<DBG_IOX) some special information
221 * (1<<DBG_DID) drive ID test
222 * (1<<DBG_RES) drive reset info
223 * (1<<DBG_SPI) SpinUp test info
224 * (1<<DBG_000) unnecessary information
226 #if 1
227 static int sbpcd_debug = (1<<DBG_INF) | (1<<DBG_WRN);
228 #else
229 static int sbpcd_debug = (1<<DBG_INF) |
230 (1<<DBG_TOC) |
231 (1<<DBG_IOX);
232 #endif
233 static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
234 static int sbpro_type = SBPRO;
235 static int CDo_command, CDo_reset;
236 static int CDo_sel_d_i, CDo_enable;
237 static int CDi_info, CDi_status, CDi_data;
238 static int MIXER_addr, MIXER_data;
239 static struct cdrom_msf msf;
240 static struct cdrom_ti ti;
241 static struct cdrom_tochdr tochdr;
242 static struct cdrom_tocentry tocentry;
243 static struct cdrom_subchnl SC;
244 static struct cdrom_volctrl volctrl;
245 char *str_sb = "SoundBlaster";
246 char *str_lm = "LaserMate";
247 char *type;
249 /*==========================================================================*/
251 #if FUTURE
252 static struct wait_queue *sbp_waitq = NULL;
253 #endif FUTURE
255 /*==========================================================================*/
257 #define SBP_BUFFER_FRAMES 4 /* driver's own read_ahead */
259 /*==========================================================================*/
261 static u_char drive_family[]="CR-5";
262 static u_char drive_vendor[]="MATSHITA";
264 static u_int response_count=0;
265 static u_int flags_cmd_out;
266 static u_char cmd_type=0;
267 static u_char drvcmd[7];
268 static u_char infobuf[20];
270 static u_char timed_out=0;
271 static u_int datarate= 1000000;
272 static u_int maxtim16=16000000;
273 static u_int maxtim04= 4000000;
274 static u_int maxtim02= 2000000;
275 static u_int maxtim_8= 30000;
276 #if MANY_SESSION
277 static u_int maxtim_data= 9000;
278 #else
279 static u_int maxtim_data= 3000;
280 #endif MANY_SESSION
282 /*==========================================================================*/
284 static int ndrives=0;
285 static u_char drv_pattern[4]={ 0x80, 0x80, 0x80, 0x80 }; /* auto speed */
286 /* /X:... drv_pattern[0] |= (sax_n1|sax_n2); */
287 /* /A:... for (i=0;i<4;i++) drv_pattern[i] |= sax_a; */
288 /* /N:... ndrives=i-'0'; */
290 /*==========================================================================*/
292 * drive space begins here (needed separate for each unit)
294 static int d=0; /* DS index: drive number */
296 static struct {
297 char drv_minor; /* minor number or -1 */
299 char drive_model[4];
300 char firmware_version[4];
301 u_char *sbp_buf; /* Pointer to internal data buffer,
302 space allocated during sbpcd_init() */
303 int sbp_first_frame; /* First frame in buffer */
304 int sbp_last_frame; /* Last frame in buffer */
305 int sbp_read_frames; /* Number of frames being read to buffer */
306 int sbp_current; /* Frame being currently read */
308 u_char drv_type;
309 u_char drv_options;
310 u_char status_byte;
311 u_char diskstate_flags;
312 u_char sense_byte;
314 u_char CD_changed;
316 u_char error_byte;
318 u_char f_multisession;
319 u_int lba_multi;
321 u_char audio_state;
322 u_int pos_audio_start;
323 u_int pos_audio_end;
324 char vol_chan0;
325 u_char vol_ctrl0;
326 char vol_chan1;
327 u_char vol_ctrl1;
328 #if 000
329 char vol_chan2;
330 u_char vol_ctrl2;
331 char vol_chan3;
332 u_char vol_ctrl3;
333 #endif 000
335 u_char SubQ_audio;
336 u_char SubQ_ctl_adr;
337 u_char SubQ_trk;
338 u_char SubQ_pnt_idx;
339 u_int SubQ_run_tot;
340 u_int SubQ_run_trk;
341 u_char SubQ_whatisthis;
343 u_char UPC_ctl_adr;
344 u_char UPC_buf[7];
346 int CDsize_blk;
347 int frame_size;
348 int CDsize_frm;
350 u_char xa_byte; /* 0x20: XA capabilities */
351 u_char n_first_track; /* binary */
352 u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
353 u_int size_msf; /* time of whole CD, position of LeadOut track */
354 u_int size_blk;
356 u_char TocEnt_nixbyte; /* em */
357 u_char TocEnt_ctl_adr;
358 u_char TocEnt_number;
359 u_char TocEnt_format; /* em */
360 u_int TocEnt_address;
361 u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
363 struct {
364 u_char nixbyte; /* em */
365 u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
366 u_char number;
367 u_char format; /* em */ /* 0x00: lba, 0x01: msf */
368 u_int address;
369 } TocBuffer[MAX_TRACKS+1]; /* last entry faked */
371 int in_SpinUp;
373 } DS[4];
376 * drive space ends here (needed separate for each unit)
379 /*==========================================================================*/
380 /*==========================================================================*/
382 * DDI interface definitions
384 #ifdef SBPCD_DEBUG
385 # define DPRINTF(x) sbpcd_dprintf x
387 void sbpcd_dprintf(int level, char *fmt, ...)
389 char buff[256];
390 va_list args;
391 extern int vsprintf(char *buf, const char *fmt, va_list args);
393 if (! (sbpcd_debug & (1 << level))) return;
395 va_start(args, fmt);
396 vsprintf(buff, fmt, args);
397 va_end(args);
398 printk(buff);
401 #else
402 # define DPRINTF(x) /* nothing */
404 #endif SBPCD_DEBUG
407 * maintain trace bit pattern
409 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
411 int val;
413 val = get_fs_long((int *) arg);
414 switch(val)
416 case 0: /* OFF */
417 sbpcd_debug = 0;
418 break;
420 default:
421 if (val >= 128) sbpcd_debug &= ~(1 << (val - 128));
422 else sbpcd_debug |= (1 << val);
424 return(0);
428 /*==========================================================================*/
429 /*==========================================================================*/
431 * Wait a little while (used for polling the drive). If in initialization,
432 * setting a timeout doesn't work, so just loop for a while.
434 static inline void sbp_sleep(u_int jifs)
436 current->state = TASK_INTERRUPTIBLE;
437 current->timeout = jiffies + jifs;
438 schedule();
441 /*==========================================================================*/
442 /*==========================================================================*/
444 * convert logical_block_address to m-s-f_number (3 bytes only)
446 static void lba2msf(int lba, u_char *msf)
448 lba += CD_BLOCK_OFFSET;
449 msf[0] = lba / (CD_SECS*CD_FRAMES);
450 lba %= CD_SECS*CD_FRAMES;
451 msf[1] = lba / CD_FRAMES;
452 msf[2] = lba % CD_FRAMES;
454 /*==========================================================================*/
455 /*==========================================================================*/
457 * convert msf-bin to msf-bcd
459 static void bin2bcdx(u_char *p) /* must work only up to 75 or 99 */
461 *p=((*p/10)<<4)|(*p%10);
463 /*==========================================================================*/
464 static u_int blk2msf(u_int blk)
466 MSF msf;
467 u_int mm;
469 msf.c[3] = 0;
470 msf.c[2] = (blk + CD_BLOCK_OFFSET) / (CD_SECS * CD_FRAMES);
471 mm = (blk + CD_BLOCK_OFFSET) % (CD_SECS * CD_FRAMES);
472 msf.c[1] = mm / CD_FRAMES;
473 msf.c[0] = mm % CD_FRAMES;
474 return (msf.n);
476 /*==========================================================================*/
477 static u_int make16(u_char rh, u_char rl)
479 return ((rh<<8)|rl);
481 /*==========================================================================*/
482 static u_int make32(u_int rh, u_int rl)
484 return ((rh<<16)|rl);
486 /*==========================================================================*/
487 static u_char swap_nibbles(u_char i)
489 return ((i<<4)|(i>>4));
491 /*==========================================================================*/
492 static u_char byt2bcd(u_char i)
494 return (((i/10)<<4)+i%10);
496 /*==========================================================================*/
497 static u_char bcd2bin(u_char bcd)
499 return ((bcd>>4)*10+(bcd&0x0F));
501 /*==========================================================================*/
502 static int msf2blk(int msfx)
504 MSF msf;
505 int i;
507 msf.n=msfx;
508 i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_BLOCK_OFFSET;
509 if (i<0) return (0);
510 return (i);
512 /*==========================================================================*/
513 /* evaluate xx_ReadError code (still mysterious) */
514 static int sta2err(int sta)
516 if (sta<=2) return (sta);
517 if (sta==0x05) return (-4);
518 if (sta==0x06) return (-6);
519 if (sta==0x0d) return (-6);
520 if (sta==0x0e) return (-3);
521 if (sta==0x14) return (-3);
522 if (sta==0x0c) return (-11);
523 if (sta==0x0f) return (-11);
524 if (sta==0x10) return (-11);
525 if (sta>=0x16) return (-12);
526 DS[d].CD_changed=0xFF;
527 if (sta==0x11) return (-15);
528 return (-2);
530 /*==========================================================================*/
531 static void clr_cmdbuf(void)
533 int i;
535 for (i=0;i<7;i++) drvcmd[i]=0;
536 cmd_type=0;
538 /*==========================================================================*/
539 static void mark_timeout(void)
541 timed_out=1;
542 DPRINTF((DBG_TIM,"SBPCD: timer stopped.\n"));
544 /*==========================================================================*/
545 static void flush_status(void)
547 #ifdef CDMKE
548 int i;
550 if (current == task[0])
551 for (i=maxtim02;i!=0;i--) inb(CDi_status);
552 else
554 sbp_sleep(150);
555 for (i=maxtim_data;i!=0;i--) inb(CDi_status);
557 #else
558 timed_out=0;
559 SET_TIMER(mark_timeout,150);
560 do { }
561 while (!timed_out);
562 CLEAR_TIMER;
563 inb(CDi_status);
564 #endif CDMKE
566 /*==========================================================================*/
567 static int CDi_stat_loop(void)
569 int i,j;
570 u_long timeout;
572 if (current == task[0])
573 for(i=maxtim16;i!=0;i--)
575 j=inb(CDi_status);
576 if (!(j&s_not_data_ready)) return (j);
577 if (!(j&s_not_result_ready)) return (j);
578 if (!new_drive) if (j&s_attention) return (j);
580 else
581 for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; )
583 for ( ;i!=0;i--)
585 j=inb(CDi_status);
586 if (!(j&s_not_data_ready)) return (j);
587 if (!(j&s_not_result_ready)) return (j);
588 if (!new_drive) if (j&s_attention) return (j);
590 sbp_sleep(1);
591 i = 1;
593 return (-1);
595 /*==========================================================================*/
596 static int ResponseInfo(void)
598 int i,j, st=0;
599 u_long timeout;
601 if (current == task[0])
602 for (i=0;i<response_count;i++)
604 for (j=maxtim_8;j!=0;j--)
606 st=inb(CDi_status);
607 if (!(st&s_not_result_ready)) break;
609 if (j==0) return (-1);
610 infobuf[i]=inb(CDi_info);
612 else
614 for (i=0, timeout = jiffies + 100; i < response_count; i++)
616 for (j=maxtim_data; ; )
618 for ( ;j!=0;j-- )
620 st=inb(CDi_status);
621 if (!(st&s_not_result_ready)) break;
623 if (j != 0 || timeout <= jiffies) break;
624 sbp_sleep(0);
625 j = 1;
627 if (timeout <= jiffies) return (-1);
628 infobuf[i]=inb(CDi_info);
631 return (0);
633 /*==========================================================================*/
634 static int EvaluateStatus(int st)
636 if (!new_drive)
638 DS[d].status_byte=0;
639 if (st&p_caddin_old) DS[d].status_byte |= p_door_closed|p_caddy_in;
640 if (st&p_spinning) DS[d].status_byte |= p_spinning;
641 if (st&p_check) DS[d].status_byte |= p_check;
642 if (st&p_busy_old) DS[d].status_byte |= p_busy_new;
643 if (st&p_disk_ok) DS[d].status_byte |= p_disk_ok;
645 else { DS[d].status_byte=st;
646 st=p_success_old; /* for new drives: fake "successful" bit of old drives */
648 return (st);
650 /*==========================================================================*/
651 static int ResponseStatus(void)
653 int i,j;
654 u_long timeout;
656 DPRINTF((DBG_STA,"SBPCD: doing ResponseStatus...\n"));
658 if (current == task[0])
660 if (flags_cmd_out & f_respo3) j = maxtim_8;
661 else if (flags_cmd_out&f_respo2) j=maxtim16;
662 else j=maxtim04;
663 for (;j!=0;j--)
665 i=inb(CDi_status);
666 if (!(i&s_not_result_ready)) break;
669 else
671 if (flags_cmd_out & f_respo3) timeout = jiffies;
672 else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600;
673 else timeout = jiffies + 400;
674 j=maxtim_8;
677 for ( ;j!=0;j--)
679 i=inb(CDi_status);
680 if (!(i&s_not_result_ready)) break;
682 if (j != 0 || timeout <= jiffies) break;
683 sbp_sleep(0);
684 j = 1;
686 while (1);
688 if (j==0)
689 { if ((flags_cmd_out & f_respo3) == 0)
690 DPRINTF((DBG_STA,"SBPCD: ResponseStatus: timeout.\n"));
691 EvaluateStatus(0);
692 return (-1);
694 i=inb(CDi_info);
695 i=EvaluateStatus(i);
696 return (i);
698 /*==========================================================================*/
699 static void xx_ReadStatus(void)
701 int i;
703 DPRINTF((DBG_STA,"SBPCD: giving xx_ReadStatus command\n"));
705 if (!new_drive) OUT(CDo_command,0x81);
706 else
708 #if SBPCD_DIS_IRQ
709 cli();
710 #endif SBPCD_DIS_IRQ
711 OUT(CDo_command,0x05);
712 for (i=0;i<6;i++) OUT(CDo_command,0);
713 #if SBPCD_DIS_IRQ
714 sti();
715 #endif SBPCD_DIS_IRQ
718 /*==========================================================================*/
719 int xx_ReadError(void)
721 int cmd_out(void);
722 int i;
724 clr_cmdbuf();
725 DPRINTF((DBG_ERR,"SBPCD: giving xx_ReadError command.\n"));
726 if (new_drive)
728 drvcmd[0]=0x82;
729 response_count=8;
730 flags_cmd_out=f_putcmd|f_ResponseStatus;
732 else
734 drvcmd[0]=0x82;
735 response_count=6;
736 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
738 i=cmd_out();
739 DS[d].error_byte=0;
740 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
741 if (i<0) return (i);
742 if (new_drive) i=2;
743 else i=1;
744 DS[d].error_byte=infobuf[i];
745 DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DS[d].error_byte,DS[d].error_byte));
746 i=sta2err(infobuf[i]);
747 return (i);
749 /*==========================================================================*/
750 int cmd_out(void)
752 int i=0;
754 if (flags_cmd_out&f_putcmd)
756 DPRINTF((DBG_CMD,"SBPCD: cmd_out: put"));
757 for (i=0;i<7;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i]));
758 DPRINTF((DBG_CMD,"\n"));
760 #if SBPCD_DIS_IRQ
761 cli();
762 #endif SBPCD_DIS_IRQ
763 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
764 #if SBPCD_DIS_IRQ
765 sti();
766 #endif SBPCD_DIS_IRQ
768 if (response_count!=0)
770 if (cmd_type!=0)
772 if (sbpro_type) OUT(CDo_sel_d_i,0x01);
773 DPRINTF((DBG_INF,"SBPCD: misleaded to try ResponseData.\n"));
774 if (sbpro_type) OUT(CDo_sel_d_i,0x00);
776 else i=ResponseInfo();
777 if (i<0) return (-9);
779 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to CDi_stat_loop.\n"));
780 if (flags_cmd_out&f_lopsta)
782 i=CDi_stat_loop();
783 if ((i<0)||!(i&s_attention)) return (-9);
785 if (!(flags_cmd_out&f_getsta)) goto LOC_229;
787 LOC_228:
788 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadStatus.\n"));
789 xx_ReadStatus();
791 LOC_229:
792 if (flags_cmd_out&f_ResponseStatus)
794 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to ResponseStatus.\n"));
795 i=ResponseStatus();
796 /* builds status_byte, returns orig. status or p_busy_new */
797 if (i<0) return (-9);
798 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
800 if (!st_check)
802 if (flags_cmd_out&f_bit1) if (i&p_success_old) goto LOC_232;
803 if (!(flags_cmd_out&f_wait_if_busy)) goto LOC_228;
804 if (!st_busy) goto LOC_228;
808 LOC_232:
809 if (!(flags_cmd_out&f_obey_p_check)) return (0);
810 if (!st_check) return (0);
811 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadError.\n"));
812 i=xx_ReadError();
813 if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to cmd_out OK.\n"));
814 return (i);
816 /*==========================================================================*/
817 static int xx_Seek(u_int pos, char f_blk_msf)
819 int i;
821 clr_cmdbuf();
822 if (f_blk_msf>1) return (-3);
823 if (!new_drive)
825 if (f_blk_msf==1) pos=msf2blk(pos);
826 drvcmd[2]=(pos>>16)&0x00FF;
827 drvcmd[3]=(pos>>8)&0x00FF;
828 drvcmd[4]=pos&0x00FF;
829 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
830 f_ResponseStatus | f_obey_p_check | f_bit1;
832 else
834 if (f_blk_msf==0) pos=blk2msf(pos);
835 drvcmd[1]=(pos>>16)&0x00FF;
836 drvcmd[2]=(pos>>8)&0x00FF;
837 drvcmd[3]=pos&0x00FF;
838 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
840 drvcmd[0]=0x01;
841 response_count=0;
842 i=cmd_out();
843 return (i);
845 /*==========================================================================*/
846 static int xx_SpinUp(void)
848 int i;
850 DPRINTF((DBG_SPI,"SBPCD: SpinUp.\n"));
851 DS[d].in_SpinUp = 1;
852 clr_cmdbuf();
853 if (!new_drive)
855 drvcmd[0]=0x05;
856 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
858 else
860 drvcmd[0]=0x02;
861 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
863 response_count=0;
864 i=cmd_out();
865 DS[d].in_SpinUp = 0;
866 return (i);
868 /*==========================================================================*/
869 static int yy_SpinDown(void)
871 int i;
873 if (!new_drive) return (-3);
874 clr_cmdbuf();
875 drvcmd[0]=0x06;
876 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
877 response_count=0;
878 i=cmd_out();
879 return (i);
881 /*==========================================================================*/
882 static int yy_SetSpeed(u_char speed, u_char x1, u_char x2)
884 int i;
886 if (!new_drive) return (-3);
887 clr_cmdbuf();
888 drvcmd[0]=0x09;
889 drvcmd[1]=0x03;
890 drvcmd[2]=speed;
891 drvcmd[3]=x1;
892 drvcmd[4]=x2;
893 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
894 response_count=0;
895 i=cmd_out();
896 return (i);
898 /*==========================================================================*/
899 static int xx_SetVolume(void)
901 int i;
902 u_char channel0,channel1,volume0,volume1;
903 u_char control0,value0,control1,value1;
905 DS[d].diskstate_flags &= ~volume_bit;
906 clr_cmdbuf();
907 channel0=DS[d].vol_chan0;
908 volume0=DS[d].vol_ctrl0;
909 channel1=control1=DS[d].vol_chan1;
910 volume1=value1=DS[d].vol_ctrl1;
911 control0=value0=0;
913 if (((DS[d].drv_options&sax_a)!=0)&&(DS[d].drv_type>=drv_211))
915 if ((volume0!=0)&&(volume1==0))
917 volume1=volume0;
918 channel1=channel0;
920 else if ((volume0==0)&&(volume1!=0))
922 volume0=volume1;
923 channel0=channel1;
926 if (channel0>1)
928 channel0=0;
929 volume0=0;
931 if (channel1>1)
933 channel1=1;
934 volume1=0;
937 if (new_drive)
939 control0=channel0+1;
940 control1=channel1+1;
941 value0=(volume0>volume1)?volume0:volume1;
942 value1=value0;
943 if (volume0==0) control0=0;
944 if (volume1==0) control1=0;
945 drvcmd[0]=0x09;
946 drvcmd[1]=0x05;
947 drvcmd[3]=control0;
948 drvcmd[4]=value0;
949 drvcmd[5]=control1;
950 drvcmd[6]=value1;
951 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
953 else
955 if (DS[d].drv_type>=drv_300)
957 control0=volume0&0xFC;
958 value0=volume1&0xFC;
959 if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
960 if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
961 if (channel0!=0) control0 |= 0x01;
962 if (channel1==1) value0 |= 0x01;
964 else
966 value0=(volume0>volume1)?volume0:volume1;
967 if (DS[d].drv_type<drv_211)
969 if (channel0!=0)
971 i=channel1;
972 channel1=channel0;
973 channel0=i;
974 i=volume1;
975 volume1=volume0;
976 volume0=i;
978 if (channel0==channel1)
980 if (channel0==0)
982 channel1=1;
983 volume1=0;
984 volume0=value0;
986 else
988 channel0=0;
989 volume0=0;
990 volume1=value0;
995 if ((volume0!=0)&&(volume1!=0))
997 if (volume0==0xFF) volume1=0xFF;
998 else if (volume1==0xFF) volume0=0xFF;
1000 else if (DS[d].drv_type<drv_201) volume0=volume1=value0;
1002 if (DS[d].drv_type>=drv_201)
1004 if (volume0==0) control0 |= 0x80;
1005 if (volume1==0) control0 |= 0x40;
1007 if (DS[d].drv_type>=drv_211)
1009 if (channel0!=0) control0 |= 0x20;
1010 if (channel1!=1) control0 |= 0x10;
1013 drvcmd[0]=0x84;
1014 drvcmd[1]=0x83;
1015 drvcmd[4]=control0;
1016 drvcmd[5]=value0;
1017 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1020 response_count=0;
1021 i=cmd_out();
1022 if (i>0) return (i);
1023 DS[d].diskstate_flags |= volume_bit;
1024 return (0);
1026 /*==========================================================================*/
1027 static int GetStatus(void)
1029 int i;
1031 flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1032 response_count=0;
1033 cmd_type=0;
1034 i=cmd_out();
1035 return (i);
1037 /*==========================================================================*/
1038 static int xy_DriveReset(void)
1040 int i;
1042 DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
1043 if (!new_drive) OUT(CDo_reset,0x00);
1044 else
1046 clr_cmdbuf();
1047 drvcmd[0]=0x0A;
1048 flags_cmd_out=f_putcmd;
1049 response_count=0;
1050 i=cmd_out();
1052 flush_status();
1053 i=GetStatus();
1054 if (i>=0) return -1;
1055 if (DS[d].error_byte!=aud_12) return -1;
1056 return (0);
1058 /*==========================================================================*/
1059 static int SetSpeed(void)
1061 int i, speed;
1063 if (!(DS[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
1064 speed=0x80;
1065 if (!(DS[d].drv_options&speed_auto))
1067 speed |= 0x40;
1068 if (!(DS[d].drv_options&speed_300)) speed=0;
1070 i=yy_SetSpeed(speed,0,0);
1071 return (i);
1073 /*==========================================================================*/
1074 static int DriveReset(void)
1076 int i;
1078 i=xy_DriveReset();
1079 if (i<0) return (-2);
1082 i=GetStatus();
1083 if ((i<0)&&(i!=-15)) return (-2); /* i!=-15 is from sta2err */
1084 if (!st_caddy_in) break;
1086 while (!st_diskok);
1087 DS[d].CD_changed=1;
1088 i=SetSpeed();
1089 if (i<0) return (-2);
1090 return (0);
1092 /*==========================================================================*/
1093 static int xx_Pause_Resume(int pau_res)
1095 int i;
1097 clr_cmdbuf();
1098 if (new_drive)
1100 drvcmd[0]=0x0D;
1101 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1103 else
1105 drvcmd[0]=0x8D;
1106 flags_cmd_out=f_putcmd|f_respo2|f_getsta|f_ResponseStatus|f_obey_p_check;
1108 if (pau_res!=1) drvcmd[1]=0x80;
1109 response_count=0;
1110 i=cmd_out();
1111 return (i);
1113 /*==========================================================================*/
1114 #if 000
1115 static int yy_LockDoor(char lock)
1117 int i;
1119 if (!new_drive) return (-3);
1120 clr_cmdbuf();
1121 drvcmd[0]=0x0C;
1122 if (lock==1) drvcmd[1]=0x01;
1123 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1124 response_count=0;
1125 i=cmd_out();
1126 return (i);
1128 #endif 000
1129 /*==========================================================================*/
1130 static int xx_ReadSubQ(void)
1132 int i,j;
1134 DS[d].diskstate_flags &= ~subq_bit;
1135 clr_cmdbuf();
1136 if (new_drive)
1138 drvcmd[0]=0x87;
1139 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1140 response_count=11;
1142 else
1144 drvcmd[0]=0x89;
1145 drvcmd[1]=0x02;
1146 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1147 response_count=13;
1149 for (j=0;j<255;j++)
1151 i=cmd_out();
1152 if (i<0) return (i);
1153 if (infobuf[0]!=0) break;
1154 if (!st_spinning)
1156 DS[d].SubQ_ctl_adr=DS[d].SubQ_trk=DS[d].SubQ_pnt_idx=DS[d].SubQ_whatisthis=0;
1157 DS[d].SubQ_run_tot=DS[d].SubQ_run_trk=0;
1158 return (0);
1161 DS[d].SubQ_audio=infobuf[0];
1162 DS[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
1163 DS[d].SubQ_trk=byt2bcd(infobuf[2]);
1164 DS[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
1165 i=4;
1166 if (!new_drive) i=5;
1167 DS[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
1168 i=7;
1169 if (!new_drive) i=9;
1170 DS[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
1171 DS[d].SubQ_whatisthis=infobuf[i+3];
1172 DS[d].diskstate_flags |= subq_bit;
1173 return (0);
1175 /*==========================================================================*/
1176 static int xx_ModeSense(void)
1178 int i;
1180 DS[d].diskstate_flags &= ~frame_size_bit;
1181 clr_cmdbuf();
1182 if (new_drive)
1184 drvcmd[0]=0x84;
1185 drvcmd[1]=0x00;
1186 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1187 response_count=5;
1189 else
1191 drvcmd[0]=0x85;
1192 drvcmd[1]=0x00;
1193 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1194 response_count=2;
1196 i=cmd_out();
1197 if (i<0) return (i);
1198 i=0;
1199 if (new_drive) DS[d].sense_byte=infobuf[i++];
1200 DS[d].frame_size=make16(infobuf[i],infobuf[i+1]);
1201 DS[d].diskstate_flags |= frame_size_bit;
1202 return (0);
1204 /*==========================================================================*/
1205 #if 0000
1206 static int xx_TellVolume(void)
1208 int i;
1209 u_char switches;
1210 u_char chan0,vol0,chan1,vol1;
1212 DS[d].diskstate_flags &= ~volume_bit;
1213 clr_cmdbuf();
1214 if (new_drive)
1216 drvcmd[0]=0x84;
1217 drvcmd[1]=0x05;
1218 response_count=5;
1219 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1221 else
1223 drvcmd[0]=0x85;
1224 drvcmd[1]=0x03;
1225 response_count=2;
1226 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1228 i=cmd_out();
1229 if (i<0) return (i);
1230 if (new_drive)
1232 chan0=infobuf[1]&0x0F;
1233 vol0=infobuf[2];
1234 chan1=infobuf[3]&0x0F;
1235 vol1=infobuf[4];
1236 if (chan0==0)
1238 chan0=1;
1239 vol0=0;
1241 if (chan1==0)
1243 chan1=2;
1244 vol1=0;
1246 chan0 >>= 1;
1247 chan1 >>= 1;
1249 else
1251 chan0=0;
1252 chan1=1;
1253 vol0=vol1=infobuf[1];
1254 if (DS[d].drv_type>=drv_201)
1256 if (DS[d].drv_type<drv_300)
1258 switches=infobuf[0];
1259 if ((switches&0x80)!=0) vol0=0;
1260 if ((switches&0x40)!=0) vol1=0;
1261 if (DS[d].drv_type>=drv_211)
1263 if ((switches&0x20)!=0) chan0=1;
1264 if ((switches&0x10)!=0) chan1=0;
1267 else
1269 vol0=infobuf[0];
1270 if ((vol0&0x01)!=0) chan0=1;
1271 if ((vol1&0x01)==0) chan1=0;
1272 vol0 &= 0xFC;
1273 vol1 &= 0xFC;
1274 if (vol0!=0) vol0 += 3;
1275 if (vol1!=0) vol1 += 3;
1279 DS[d].vol_chan0=chan0;
1280 DS[d].vol_ctrl0=vol0;
1281 DS[d].vol_chan1=chan1;
1282 DS[d].vol_ctrl1=vol1;
1283 DS[d].vol_chan2=2;
1284 DS[d].vol_ctrl2=0xFF;
1285 DS[d].vol_chan3=3;
1286 DS[d].vol_ctrl3=0xFF;
1287 DS[d].diskstate_flags |= volume_bit;
1288 return (0);
1290 #endif
1291 /*==========================================================================*/
1292 static int xx_ReadCapacity(void)
1294 int i;
1296 DS[d].diskstate_flags &= ~cd_size_bit;
1297 clr_cmdbuf();
1298 if (new_drive)
1300 drvcmd[0]=0x85;
1301 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1303 else
1305 drvcmd[0]=0x88;
1306 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1308 response_count=5;
1309 i=cmd_out();
1310 if (i<0) return (i);
1311 DS[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
1312 if (new_drive) DS[d].CDsize_blk=msf2blk(DS[d].CDsize_blk);
1313 DS[d].CDsize_frm = (DS[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
1314 DS[d].CDsize_blk += 151;
1315 DS[d].diskstate_flags |= cd_size_bit;
1316 return (0);
1318 /*==========================================================================*/
1319 static int xx_ReadTocDescr(void)
1321 int i;
1323 DS[d].diskstate_flags &= ~toc_bit;
1324 clr_cmdbuf();
1325 if (new_drive)
1327 drvcmd[0]=0x8B;
1328 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1330 else
1332 drvcmd[0]=0x8B;
1333 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1335 response_count=6;
1336 i=cmd_out();
1337 if (i<0) return (i);
1338 DS[d].xa_byte=infobuf[0];
1339 DS[d].n_first_track=infobuf[1];
1340 DS[d].n_last_track=infobuf[2];
1341 DS[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
1342 DS[d].size_blk=msf2blk(DS[d].size_msf);
1343 DS[d].diskstate_flags |= toc_bit;
1344 DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
1345 DS[d].xa_byte,DS[d].n_first_track,DS[d].n_last_track,DS[d].size_msf));
1346 return (0);
1348 /*==========================================================================*/
1349 static int xx_ReadTocEntry(int num)
1351 int i;
1353 clr_cmdbuf();
1354 if (new_drive)
1356 drvcmd[0]=0x8C;
1357 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1359 else
1361 drvcmd[0]=0x8C;
1362 drvcmd[1]=0x02;
1363 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1365 drvcmd[2]=num;
1366 response_count=8;
1367 i=cmd_out();
1368 if (i<0) return (i);
1369 DS[d].TocEnt_nixbyte=infobuf[0];
1370 DS[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
1371 DS[d].TocEnt_number=infobuf[2];
1372 DS[d].TocEnt_format=infobuf[3];
1373 if (new_drive) i=4;
1374 else i=5;
1375 DS[d].TocEnt_address=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1376 DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
1377 DS[d].TocEnt_nixbyte,DS[d].TocEnt_ctl_adr,DS[d].TocEnt_number,
1378 DS[d].TocEnt_format,DS[d].TocEnt_address));
1379 return (0);
1381 /*==========================================================================*/
1382 static int xx_ReadPacket(void)
1384 int i;
1386 clr_cmdbuf();
1387 drvcmd[0]=0x8E;
1388 drvcmd[1]=response_count;
1389 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1390 i=cmd_out();
1391 return (i);
1393 /*==========================================================================*/
1394 static int convert_UPC(u_char *p)
1396 int i;
1398 p++;
1399 if (!new_drive) p[13]=0;
1400 for (i=0;i<7;i++)
1402 if (new_drive) DS[d].UPC_buf[i]=swap_nibbles(*p++);
1403 else
1405 DS[d].UPC_buf[i]=((*p++)<<4)&0xFF;
1406 DS[d].UPC_buf[i] |= *p++;
1409 DS[d].UPC_buf[6] &= 0xF0;
1410 return (0);
1412 /*==========================================================================*/
1413 static int xx_ReadUPC(void)
1415 int i;
1417 DS[d].diskstate_flags &= ~upc_bit;
1418 clr_cmdbuf();
1419 if (new_drive)
1421 drvcmd[0]=0x88;
1422 response_count=8;
1423 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1425 else
1427 drvcmd[0]=0x08;
1428 response_count=0;
1429 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1431 i=cmd_out();
1432 if (i<0) return (i);
1433 if (!new_drive)
1435 response_count=16;
1436 i=xx_ReadPacket();
1437 if (i<0) return (i);
1439 DS[d].UPC_ctl_adr=0;
1440 if (new_drive) i=0;
1441 else i=2;
1442 if ((infobuf[i]&0x80)!=0)
1444 convert_UPC(&infobuf[i]);
1445 DS[d].UPC_ctl_adr &= 0xF0;
1446 DS[d].UPC_ctl_adr |= 0x02;
1448 DS[d].diskstate_flags |= upc_bit;
1449 return (0);
1451 /*==========================================================================*/
1452 static int yy_CheckMultiSession(void)
1454 int i;
1456 DS[d].diskstate_flags &= ~multisession_bit;
1457 DS[d].f_multisession=0;
1458 clr_cmdbuf();
1459 if (new_drive)
1461 drvcmd[0]=0x8D;
1462 response_count=6;
1463 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1464 i=cmd_out();
1465 if (i<0) return (i);
1466 if ((infobuf[0]&0x80)!=0)
1468 DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X\n",
1469 infobuf[0], infobuf[1], infobuf[2],
1470 infobuf[3], infobuf[4], infobuf[5]));
1471 DS[d].f_multisession=1;
1472 DS[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
1473 make16(infobuf[2],infobuf[3])));
1476 DS[d].diskstate_flags |= multisession_bit;
1477 return (0);
1479 /*==========================================================================*/
1480 static void check_datarate(void)
1482 #ifdef CDMKE
1483 int i=0;
1485 timed_out=0;
1486 datarate=0;
1488 /* set a timer to make (timed_out!=0) after 1.1 seconds */
1490 DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
1491 sti(); /* to avoid possible "printf" bug */
1493 SET_TIMER(mark_timeout,110);
1496 i=inb(CDi_status);
1497 datarate++;
1499 #if 00000
1500 if (datarate>0x0FFFFFFF) break;
1501 #endif 00000
1504 while (!timed_out); /* originally looping for 1.1 seconds */
1505 CLEAR_TIMER;
1506 DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
1507 if (datarate<65536) datarate=65536;
1509 maxtim16=datarate*16;
1510 maxtim04=datarate*4;
1511 maxtim02=datarate*2;
1512 maxtim_8=datarate/32;
1513 #if MANY_SESSION
1514 maxtim_data=datarate/100;
1515 #else
1516 maxtim_data=datarate/300;
1517 #endif MANY_SESSION
1518 DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
1519 maxtim_8, maxtim_data));
1520 #endif CDMKE
1522 /*==========================================================================*/
1523 static int check_version(void)
1525 int i, j;
1527 /* clear any pending error state */
1528 clr_cmdbuf();
1529 drvcmd[0]=0x82;
1530 response_count=9;
1531 flags_cmd_out=f_putcmd;
1532 cmd_out();
1534 /* read drive version */
1535 clr_cmdbuf();
1536 for (i=0;i<12;i++) infobuf[i]=0;
1537 drvcmd[0]=0x83;
1538 response_count=12;
1539 flags_cmd_out=f_putcmd;
1540 i=cmd_out();
1541 if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i));
1543 DPRINTF((DBG_INI,"SBPCD: infobuf = \""));
1544 for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i]));
1545 DPRINTF((DBG_INI,"\"\n"));
1547 for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break;
1548 if (i==4)
1550 DS[d].drive_model[0]=infobuf[i++];
1551 DS[d].drive_model[1]=infobuf[i++];
1552 DS[d].drive_model[2]='-';
1553 DS[d].drive_model[3]='x';
1554 DS[d].drv_type=drv_new;
1556 else
1558 for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
1559 if (i!=8) return (-1);
1560 DS[d].drive_model[0]='2';
1561 DS[d].drive_model[1]='x';
1562 DS[d].drive_model[2]='-';
1563 DS[d].drive_model[3]='x';
1564 DS[d].drv_type=drv_old;
1566 for (j=0;j<4;j++) DS[d].firmware_version[j]=infobuf[i+j];
1567 j = (DS[d].firmware_version[0] & 0x0F) * 100 +
1568 (DS[d].firmware_version[2] & 0x0F) *10 +
1569 (DS[d].firmware_version[3] & 0x0F);
1570 if (new_drive)
1572 if (j<100) DS[d].drv_type=drv_099;
1573 else DS[d].drv_type=drv_100;
1575 else if (j<200) DS[d].drv_type=drv_199;
1576 else if (j<201) DS[d].drv_type=drv_200;
1577 else if (j<210) DS[d].drv_type=drv_201;
1578 else if (j<211) DS[d].drv_type=drv_210;
1579 else if (j<300) DS[d].drv_type=drv_211;
1580 else DS[d].drv_type=drv_300;
1581 return (0);
1583 /*==========================================================================*/
1584 static int switch_drive(int num)
1586 int i;
1588 d=num;
1590 i=num;
1591 if (sbpro_type) i=(i&0x01)<<1|(i&0x02)>>1;
1592 OUT(CDo_enable,i);
1593 DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DS[d].drv_minor));
1594 return (0);
1596 /*==========================================================================*/
1598 * probe for the presence of drives on the selected controller
1600 static int check_drives(void)
1602 int i, j;
1603 char *printk_header="";
1605 DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
1607 ndrives=0;
1608 for (j=0;j<NR_SBPCD;j++)
1610 DS[j].drv_minor=j;
1611 switch_drive(j);
1612 DPRINTF((DBG_ID,"SBPCD: check_drives: drive %d activated.\n",j));
1613 i=check_version();
1614 DPRINTF((DBG_ID,"SBPCD: check_version returns %d.\n",i));
1615 if (i>=0)
1617 ndrives++;
1618 DS[d].drv_options=drv_pattern[j];
1619 if (!new_drive) DS[d].drv_options&=~(speed_auto|speed_300|speed_150);
1620 printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header,
1621 DS[d].drv_minor,
1622 drive_family,
1623 DS[d].drive_model,
1624 DS[d].firmware_version);
1625 printk_header=" - ";
1627 else DS[d].drv_minor=-1;
1629 if (ndrives==0) return (-1);
1630 return (0);
1632 /*==========================================================================*/
1633 #if 000
1634 static void timewait(void)
1636 int i;
1637 for (i=0; i<65500; i++);
1639 #endif 000
1640 /*==========================================================================*/
1641 #if FUTURE
1643 * obtain if requested service disturbs current audio state
1645 static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
1647 switch (audio_state) /* audio status from controller */
1649 case aud_11: /* "audio play in progress" */
1650 case audx11:
1651 switch (func) /* DOS command code */
1653 case cmd_07: /* input flush */
1654 case cmd_0d: /* open device */
1655 case cmd_0e: /* close device */
1656 case cmd_0c: /* ioctl output */
1657 return (1);
1658 case cmd_03: /* ioctl input */
1659 switch (subfunc)
1660 /* DOS ioctl input subfunction */
1662 case cxi_00:
1663 case cxi_06:
1664 case cxi_09:
1665 return (1);
1666 default:
1667 return (ERROR15);
1669 return (1);
1670 default:
1671 return (ERROR15);
1673 return (1);
1674 case aud_12: /* "audio play paused" */
1675 case audx12:
1676 return (1);
1677 default:
1678 return (2);
1681 #endif FUTURE
1682 /*==========================================================================*/
1683 /* allowed is only
1684 * ioctl_o, flush_input, open_device, close_device,
1685 * tell_address, tell_volume, tell_capabiliti,
1686 * tell_framesize, tell_CD_changed, tell_audio_posi
1688 static int check_allowed1(u_char func1, u_char func2)
1690 #if 000
1691 if (func1==ioctl_o) return (0);
1692 if (func1==read_long) return (-1);
1693 if (func1==read_long_prefetch) return (-1);
1694 if (func1==seek) return (-1);
1695 if (func1==audio_play) return (-1);
1696 if (func1==audio_pause) return (-1);
1697 if (func1==audio_resume) return (-1);
1698 if (func1!=ioctl_i) return (0);
1699 if (func2==tell_SubQ_run_tot) return (-1);
1700 if (func2==tell_cdsize) return (-1);
1701 if (func2==tell_TocDescrip) return (-1);
1702 if (func2==tell_TocEntry) return (-1);
1703 if (func2==tell_subQ_info) return (-1);
1704 if (new_drive) if (func2==tell_SubChanInfo) return (-1);
1705 if (func2==tell_UPC) return (-1);
1706 #else
1707 return (0);
1708 #endif 000
1710 /*==========================================================================*/
1711 static int check_allowed2(u_char func1, u_char func2)
1713 #if 000
1714 if (func1==read_long) return (-1);
1715 if (func1==read_long_prefetch) return (-1);
1716 if (func1==seek) return (-1);
1717 if (func1==audio_play) return (-1);
1718 if (func1!=ioctl_o) return (0);
1719 if (new_drive)
1721 if (func2==EjectDisk) return (-1);
1722 if (func2==CloseTray) return (-1);
1724 #else
1725 return (0);
1726 #endif 000
1728 /*==========================================================================*/
1729 static int check_allowed3(u_char func1, u_char func2)
1731 #if 000
1732 if (func1==ioctl_i)
1734 if (func2==tell_address) return (0);
1735 if (func2==tell_capabiliti) return (0);
1736 if (func2==tell_CD_changed) return (0);
1737 if (!new_drive) if (func2==tell_SubChanInfo) return (0);
1738 return (-1);
1740 if (func1==ioctl_o)
1742 if (func2==DriveReset) return (0);
1743 if (!new_drive)
1745 if (func2==EjectDisk) return (0);
1746 if (func2==LockDoor) return (0);
1747 if (func2==CloseTray) return (0);
1749 return (-1);
1751 if (func1==flush_input) return (-1);
1752 if (func1==read_long) return (-1);
1753 if (func1==read_long_prefetch) return (-1);
1754 if (func1==seek) return (-1);
1755 if (func1==audio_play) return (-1);
1756 if (func1==audio_pause) return (-1);
1757 if (func1==audio_resume) return (-1);
1758 #else
1759 return (0);
1760 #endif 000
1762 /*==========================================================================*/
1763 static int seek_pos_audio_end(void)
1765 int i;
1767 i=msf2blk(DS[d].pos_audio_end)-1;
1768 if (i<0) return (-1);
1769 i=xx_Seek(i,0);
1770 return (i);
1772 /*==========================================================================*/
1773 static int ReadToC(void)
1775 int i, j;
1776 DS[d].diskstate_flags &= ~toc_bit;
1777 DS[d].ored_ctl_adr=0;
1778 for (j=DS[d].n_first_track;j<=DS[d].n_last_track;j++)
1780 i=xx_ReadTocEntry(j);
1781 if (i<0) return (i);
1782 DS[d].TocBuffer[j].nixbyte=DS[d].TocEnt_nixbyte;
1783 DS[d].TocBuffer[j].ctl_adr=DS[d].TocEnt_ctl_adr;
1784 DS[d].TocBuffer[j].number=DS[d].TocEnt_number;
1785 DS[d].TocBuffer[j].format=DS[d].TocEnt_format;
1786 DS[d].TocBuffer[j].address=DS[d].TocEnt_address;
1787 DS[d].ored_ctl_adr |= DS[d].TocEnt_ctl_adr;
1789 /* fake entry for LeadOut Track */
1790 DS[d].TocBuffer[j].nixbyte=0;
1791 DS[d].TocBuffer[j].ctl_adr=0;
1792 DS[d].TocBuffer[j].number=0;
1793 DS[d].TocBuffer[j].format=0;
1794 DS[d].TocBuffer[j].address=DS[d].size_msf;
1796 DS[d].diskstate_flags |= toc_bit;
1797 return (0);
1799 /*==========================================================================*/
1800 static int DiskInfo(void)
1802 int i;
1804 i=SetSpeed();
1805 if (i<0)
1807 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first SetSpeed returns %d\n", i));
1808 i=SetSpeed();
1809 if (i<0)
1811 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second SetSpeed returns %d\n", i));
1812 return (i);
1815 i=xx_ModeSense();
1816 if (i<0)
1818 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first xx_ModeSense returns %d\n", i));
1819 i=xx_ModeSense();
1820 if (i<0)
1822 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second xx_ModeSense returns %d\n", i));
1823 return (i);
1825 return (i);
1827 i=xx_ReadCapacity();
1828 if (i<0)
1830 DPRINTF((DBG_INF,"SBPCD: DiskInfo: first ReadCapacity returns %d\n", i));
1831 i=xx_ReadCapacity();
1832 if (i<0)
1834 DPRINTF((DBG_INF,"SBPCD: DiskInfo: second ReadCapacity returns %d\n", i));
1835 return (i);
1837 return (i);
1839 i=xx_ReadTocDescr();
1840 if (i<0)
1842 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i));
1843 return (i);
1845 i=ReadToC();
1846 if (i<0)
1848 DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i));
1849 return (i);
1851 i=yy_CheckMultiSession();
1852 if (i<0)
1854 DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i));
1855 return (i);
1857 i=xx_ReadTocEntry(DS[d].n_first_track);
1858 if (i<0)
1860 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadTocEntry(1) returns %d\n", i));
1861 return (i);
1863 i=xx_ReadUPC();
1864 if (i<0)
1866 DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadUPC returns %d\n", i));
1867 return (i);
1869 return (0);
1871 /*==========================================================================*/
1873 * called always if driver gets entered
1874 * returns 0 or ERROR2 or ERROR15
1876 static int prepare(u_char func, u_char subfunc)
1878 int i;
1880 if (!new_drive)
1882 i=inb(CDi_status);
1883 if (i&s_attention) GetStatus();
1885 else GetStatus();
1886 if (DS[d].CD_changed==0xFF)
1888 #if MANY_SESSION
1889 #else
1890 DS[d].diskstate_flags=0;
1891 #endif MANY_SESSION
1892 DS[d].audio_state=0;
1893 if (!st_diskok)
1895 i=check_allowed1(func,subfunc);
1896 if (i<0) return (-2);
1898 else
1900 i=check_allowed3(func,subfunc);
1901 if (i<0)
1903 DS[d].CD_changed=1;
1904 return (-15);
1908 else
1910 if (!st_diskok)
1912 #if MANY_SESSION
1913 #else
1914 DS[d].diskstate_flags=0;
1915 #endif MANY_SESSION
1916 DS[d].audio_state=0;
1917 i=check_allowed1(func,subfunc);
1918 if (i<0) return (-2);
1920 else
1922 if (st_busy)
1924 if (DS[d].audio_state!=audio_pausing)
1926 i=check_allowed2(func,subfunc);
1927 if (i<0) return (-2);
1930 else
1932 if (DS[d].audio_state==audio_playing) seek_pos_audio_end();
1933 DS[d].audio_state=0;
1935 if (!frame_size_valid)
1937 i=DiskInfo();
1938 if (i<0)
1940 #if MANY_SESSION
1941 #else
1942 DS[d].diskstate_flags=0;
1943 #endif MANY_SESSION
1944 DS[d].audio_state=0;
1945 i=check_allowed1(func,subfunc);
1946 if (i<0) return (-2);
1951 return (0);
1953 /*==========================================================================*/
1954 static int xx_PlayAudioMSF(int pos_audio_start,int pos_audio_end)
1956 int i;
1958 if (DS[d].audio_state==audio_playing) return (-EINVAL);
1959 clr_cmdbuf();
1960 if (new_drive)
1962 drvcmd[0]=0x0E;
1963 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
1964 f_obey_p_check | f_wait_if_busy;
1966 else
1968 drvcmd[0]=0x0B;
1969 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1970 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
1972 drvcmd[1]=(pos_audio_start>>16)&0x00FF;
1973 drvcmd[2]=(pos_audio_start>>8)&0x00FF;
1974 drvcmd[3]=pos_audio_start&0x00FF;
1975 drvcmd[4]=(pos_audio_end>>16)&0x00FF;
1976 drvcmd[5]=(pos_audio_end>>8)&0x00FF;
1977 drvcmd[6]=pos_audio_end&0x00FF;
1978 response_count=0;
1979 i=cmd_out();
1980 return (i);
1982 /*==========================================================================*/
1983 /*==========================================================================*/
1985 /*==========================================================================*/
1986 /*==========================================================================*/
1988 * ioctl support, adopted from scsi/sr_ioctl.c and mcd.c
1990 static int sbpcd_ioctl(struct inode *inode,struct file *file,
1991 u_int cmd, u_long arg)
1993 int i, st;
1995 DPRINTF((DBG_IOC,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
1996 MINOR(inode->i_rdev), cmd, arg));
1997 if (!inode) return (-EINVAL);
1998 st=GetStatus();
1999 if (st<0) return (-EIO);
2001 if (!toc_valid)
2003 i=DiskInfo();
2004 if (i<0) return (-EIO); /* error reading TOC */
2007 i=MINOR(inode->i_rdev);
2008 if ( (i<0) || (i>=NR_SBPCD) )
2010 DPRINTF((DBG_INF,"SBPCD: ioctl: bad device: %d\n", i));
2011 return (-ENODEV); /* no such drive */
2013 switch_drive(i);
2016 DPRINTF((DBG_IOC,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
2017 switch (cmd) /* Sun-compatible */
2019 case DDIOCSDBG: /* DDI Debug */
2020 if (! suser()) return (-EPERM);
2021 i = verify_area(VERIFY_READ, (int *) arg, sizeof(int));
2022 if (i>=0) i=sbpcd_dbg_ioctl(arg,1);
2023 return (i);
2025 case CDROMPAUSE: /* Pause the drive */
2026 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPAUSE entered.\n"));
2027 /* pause the drive unit when it is currently in PLAY mode, */
2028 /* or reset the starting and ending locations when in PAUSED mode. */
2029 /* If applicable, at the next stopping point it reaches */
2030 /* the drive will discontinue playing. */
2031 switch (DS[d].audio_state)
2033 case audio_playing:
2034 i=xx_Pause_Resume(1);
2035 if (i<0) return (-EIO);
2036 DS[d].audio_state=audio_pausing;
2037 i=xx_ReadSubQ();
2038 if (i<0) return (-EIO);
2039 DS[d].pos_audio_start=DS[d].SubQ_run_tot;
2040 return (0);
2041 case audio_pausing:
2042 i=xx_Seek(DS[d].pos_audio_start,1);
2043 if (i<0) return (-EIO);
2044 return (0);
2045 default:
2046 return (-EINVAL);
2049 case CDROMRESUME: /* resume paused audio play */
2050 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMRESUME entered.\n"));
2051 /* resume playing audio tracks when a previous PLAY AUDIO call has */
2052 /* been paused with a PAUSE command. */
2053 /* It will resume playing from the location saved in SubQ_run_tot. */
2054 if (DS[d].audio_state!=audio_pausing) return -EINVAL;
2055 i=xx_Pause_Resume(3);
2056 if (i<0) return (-EIO);
2057 DS[d].audio_state=audio_playing;
2058 return (0);
2060 case CDROMPLAYMSF:
2061 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYMSF entered.\n"));
2062 if (DS[d].audio_state==audio_playing)
2064 i=xx_Pause_Resume(1);
2065 if (i<0) return (-EIO);
2066 i=xx_ReadSubQ();
2067 if (i<0) return (-EIO);
2068 DS[d].pos_audio_start=DS[d].SubQ_run_tot;
2069 i=xx_Seek(DS[d].pos_audio_start,1);
2071 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_msf));
2072 if (st) return (st);
2073 memcpy_fromfs(&msf, (void *) arg, sizeof(struct cdrom_msf));
2074 /* values come as msf-bin */
2075 DS[d].pos_audio_start = (msf.cdmsf_min0<<16) |
2076 (msf.cdmsf_sec0<<8) |
2077 msf.cdmsf_frame0;
2078 DS[d].pos_audio_end = (msf.cdmsf_min1<<16) |
2079 (msf.cdmsf_sec1<<8) |
2080 msf.cdmsf_frame1;
2081 DPRINTF((DBG_IOX,"SBPCD: ioctl: CDROMPLAYMSF %08X %08X\n",
2082 DS[d].pos_audio_start,DS[d].pos_audio_end));
2083 i=xx_PlayAudioMSF(DS[d].pos_audio_start,DS[d].pos_audio_end);
2084 DPRINTF((DBG_IOC,"SBPCD: ioctl: xx_PlayAudioMSF returns %d\n",i));
2085 #if 0
2086 if (i<0) return (-EIO);
2087 #endif 0
2088 DS[d].audio_state=audio_playing;
2089 return (0);
2091 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
2092 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYTRKIND entered.\n"));
2093 if (DS[d].audio_state==audio_playing)
2095 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: already audio_playing.\n"));
2096 return (0);
2097 return (-EINVAL);
2099 st=verify_area(VERIFY_READ,(void *) arg,sizeof(struct cdrom_ti));
2100 if (st<0)
2102 DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: verify_area error.\n"));
2103 return (st);
2105 memcpy_fromfs(&ti,(void *) arg,sizeof(struct cdrom_ti));
2106 DPRINTF((DBG_IOX,"SBPCD: ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
2107 ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1));
2108 if (ti.cdti_trk0<DS[d].n_first_track) return (-EINVAL);
2109 if (ti.cdti_trk0>DS[d].n_last_track) return (-EINVAL);
2110 if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
2111 if (ti.cdti_trk1>DS[d].n_last_track) ti.cdti_trk1=DS[d].n_last_track;
2112 DS[d].pos_audio_start=DS[d].TocBuffer[ti.cdti_trk0].address;
2113 DS[d].pos_audio_end=DS[d].TocBuffer[ti.cdti_trk1+1].address;
2114 i=xx_PlayAudioMSF(DS[d].pos_audio_start,DS[d].pos_audio_end);
2115 #if 0
2116 if (i<0) return (-EIO);
2117 #endif 0
2118 DS[d].audio_state=audio_playing;
2119 return (0);
2121 case CDROMREADTOCHDR: /* Read the table of contents header */
2122 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCHDR entered.\n"));
2123 tochdr.cdth_trk0=DS[d].n_first_track;
2124 tochdr.cdth_trk1=DS[d].n_last_track;
2125 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_tochdr));
2126 if (st) return (st);
2127 memcpy_tofs((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
2128 return (0);
2130 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
2131 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCENTRY entered.\n"));
2132 st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_tocentry));
2133 if (st) return (st);
2134 memcpy_fromfs(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
2135 i=tocentry.cdte_track;
2136 if (i==CDROM_LEADOUT) i=DS[d].n_last_track+1;
2137 else if (i<DS[d].n_first_track||i>DS[d].n_last_track) return (-EINVAL);
2138 tocentry.cdte_adr=DS[d].TocBuffer[i].ctl_adr&0x0F;
2139 tocentry.cdte_ctrl=(DS[d].TocBuffer[i].ctl_adr>>4)&0x0F;
2140 tocentry.cdte_datamode=DS[d].TocBuffer[i].format;
2141 if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
2142 { tocentry.cdte_addr.msf.minute=(DS[d].TocBuffer[i].address>>16)&0x00FF;
2143 tocentry.cdte_addr.msf.second=(DS[d].TocBuffer[i].address>>8)&0x00FF;
2144 tocentry.cdte_addr.msf.frame=DS[d].TocBuffer[i].address&0x00FF;
2146 else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
2147 tocentry.cdte_addr.lba=msf2blk(DS[d].TocBuffer[i].address);
2148 else return (-EINVAL);
2149 st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_tocentry));
2150 if (st) return (st);
2151 memcpy_tofs((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
2152 return (0);
2154 case CDROMSTOP: /* Spin down the drive */
2155 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTOP entered.\n"));
2156 i=DriveReset();
2157 #if WORKMAN
2158 DS[d].CD_changed=0xFF;
2159 DS[d].diskstate_flags=0;
2160 #endif WORKMAN
2161 DPRINTF((DBG_IOC,"SBPCD: ioctl: DriveReset returns %d\n",i));
2162 DS[d].audio_state=0;
2163 i=DiskInfo();
2164 return (0);
2166 case CDROMSTART: /* Spin up the drive */
2167 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTART entered.\n"));
2168 i=xx_SpinUp();
2169 DS[d].audio_state=0;
2170 return (0);
2172 case CDROMEJECT:
2173 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT entered.\n"));
2174 if (!new_drive) return (0);
2175 #if WORKMAN
2176 DS[d].CD_changed=0xFF;
2177 DS[d].diskstate_flags=0;
2178 #endif WORKMAN
2179 i=yy_SpinDown();
2180 if (i<0) return (-EIO);
2181 DS[d].audio_state=0;
2182 return (0);
2184 case CDROMVOLCTRL: /* Volume control */
2185 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMVOLCTRL entered.\n"));
2186 st=verify_area(VERIFY_READ,(void *) arg,sizeof(volctrl));
2187 if (st) return (st);
2188 memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
2189 DS[d].vol_chan0=0;
2190 DS[d].vol_ctrl0=volctrl.channel0;
2191 DS[d].vol_chan1=1;
2192 DS[d].vol_ctrl1=volctrl.channel1;
2193 i=xx_SetVolume();
2194 return (0);
2196 case CDROMSUBCHNL: /* Get subchannel info */
2197 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
2198 if ((st_spinning)||(!subq_valid)) { i=xx_ReadSubQ();
2199 if (i<0) return (-EIO);
2201 st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
2202 if (st) return (st);
2203 memcpy_fromfs(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
2204 #if 0
2205 if (DS[d].SubQ_audio==0x80) DS[d].SubQ_audio=CDROM_AUDIO_NO_STATUS;
2206 #endif
2207 switch (DS[d].audio_state)
2209 case audio_playing:
2210 SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
2211 break;
2212 case audio_pausing:
2213 SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
2214 break;
2215 default:
2216 SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
2217 break;
2219 SC.cdsc_adr=DS[d].SubQ_ctl_adr;
2220 SC.cdsc_ctrl=DS[d].SubQ_ctl_adr>>4;
2221 SC.cdsc_trk=bcd2bin(DS[d].SubQ_trk);
2222 SC.cdsc_ind=bcd2bin(DS[d].SubQ_pnt_idx);
2223 if (SC.cdsc_format==CDROM_LBA)
2225 SC.cdsc_absaddr.lba=msf2blk(DS[d].SubQ_run_tot);
2226 SC.cdsc_reladdr.lba=msf2blk(DS[d].SubQ_run_trk);
2228 else /* not only if (SC.cdsc_format==CDROM_MSF) */
2230 SC.cdsc_absaddr.msf.minute=(DS[d].SubQ_run_tot>>16)&0x00FF;
2231 SC.cdsc_absaddr.msf.second=(DS[d].SubQ_run_tot>>8)&0x00FF;
2232 SC.cdsc_absaddr.msf.frame=DS[d].SubQ_run_tot&0x00FF;
2233 SC.cdsc_reladdr.msf.minute=(DS[d].SubQ_run_trk>>16)&0x00FF;
2234 SC.cdsc_reladdr.msf.second=(DS[d].SubQ_run_trk>>8)&0x00FF;
2235 SC.cdsc_reladdr.msf.frame=DS[d].SubQ_run_trk&0x00FF;
2237 memcpy_tofs((void *) arg, &SC, sizeof(struct cdrom_subchnl));
2238 DPRINTF((DBG_IOC,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
2239 SC.cdsc_format,SC.cdsc_audiostatus,
2240 SC.cdsc_adr,SC.cdsc_ctrl,
2241 SC.cdsc_trk,SC.cdsc_ind,
2242 SC.cdsc_absaddr,SC.cdsc_reladdr));
2243 return (0);
2245 case CDROMREADMODE2:
2246 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n"));
2247 return (-EINVAL);
2249 case CDROMREADMODE1:
2250 DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE1 requested.\n"));
2251 return (-EINVAL);
2253 default:
2254 DPRINTF((DBG_IOX,"SBPCD: ioctl: unknown function request %04X\n", cmd));
2255 return (-EINVAL);
2256 } /* end switch(cmd) */
2258 /*==========================================================================*/
2260 * Take care of the different block sizes between cdrom and Linux.
2261 * When Linux gets variable block sizes this will probably go away.
2263 static void sbp_transfer(void)
2265 long offs;
2267 while ( (CURRENT->nr_sectors > 0) &&
2268 (CURRENT->sector/4 >= DS[d].sbp_first_frame) &&
2269 (CURRENT->sector/4 <= DS[d].sbp_last_frame) )
2271 offs = (CURRENT->sector - DS[d].sbp_first_frame * 4) * 512;
2272 memcpy(CURRENT->buffer, DS[d].sbp_buf + offs, 512);
2273 CURRENT->nr_sectors--;
2274 CURRENT->sector++;
2275 CURRENT->buffer += 512;
2278 /*==========================================================================*/
2280 * We seem to get never an interrupt.
2282 #if SBPCD_USE_IRQ
2283 static void sbpcd_interrupt(int unused)
2285 int st;
2287 st = inb(CDi_status) & 0xFF;
2288 DPRINTF((DBG_IRQ,"SBPCD: INTERRUPT received - CDi_status=%02X\n", st));
2290 #endif SBPCD_USE_IRQ
2291 /*==========================================================================*/
2293 * Called from the timer to check the results of the get-status cmd.
2295 static int sbp_status(void)
2297 int st;
2299 st=ResponseStatus();
2300 if (st<0)
2302 DPRINTF((DBG_INF,"SBPCD: sbp_status: timeout.\n"));
2303 return (0);
2306 if (!st_spinning) DPRINTF((DBG_SPI,"SBPCD: motor got off - ignoring.\n"));
2308 if (st_check)
2310 DPRINTF((DBG_INF,"SBPCD: st_check detected - retrying.\n"));
2311 return (0);
2313 if (!st_door_closed)
2315 DPRINTF((DBG_INF,"SBPCD: door is open - retrying.\n"));
2316 return (0);
2318 if (!st_caddy_in)
2320 DPRINTF((DBG_INF,"SBPCD: disk removed - retrying.\n"));
2321 return (0);
2323 if (!st_diskok)
2325 DPRINTF((DBG_INF,"SBPCD: !st_diskok detected - retrying.\n"));
2326 return (0);
2328 if (st_busy)
2330 DPRINTF((DBG_INF,"SBPCD: st_busy detected - retrying.\n"));
2331 return (0);
2333 return (1);
2335 /*==========================================================================*/
2337 * I/O request routine, called from Linux kernel.
2339 static void do_sbpcd_request(void)
2341 u_int block;
2342 int dev;
2343 u_int nsect;
2344 int i, status_tries, data_tries;
2346 request_loop:
2348 sti();
2350 if ((CURRENT==NULL)||(CURRENT->dev<0)) return;
2351 if (CURRENT -> sector == -1) return;
2353 dev = MINOR(CURRENT->dev);
2354 if ( (dev<0) || (dev>=NR_SBPCD) )
2356 DPRINTF((DBG_INF,"SBPCD: do_request: bad device: %d\n", dev));
2357 return;
2359 switch_drive(dev);
2361 INIT_REQUEST;
2362 block = CURRENT->sector;
2363 nsect = CURRENT->nr_sectors;
2365 if (CURRENT->cmd != READ)
2367 DPRINTF((DBG_INF,"SBPCD: bad cmd %d\n", CURRENT->cmd));
2368 end_request(0);
2369 goto request_loop;
2372 DPRINTF((DBG_MUL,"SBPCD: read LBA %d\n", block/4));
2373 sbp_transfer();
2375 /* if we satisfied the request from the buffer, we're done. */
2377 if (CURRENT->nr_sectors == 0)
2379 end_request(1);
2380 goto request_loop;
2383 i=prepare(0,0); /* at moment not really a hassle check, but ... */
2384 if (i!=0) DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i));
2386 if (!st_spinning) xx_SpinUp();
2388 for (data_tries=3; data_tries > 0; data_tries--)
2390 for (status_tries=3; status_tries > 0; status_tries--)
2392 flags_cmd_out |= f_respo3;
2393 xx_ReadStatus();
2394 if (sbp_status() != 0) break;
2395 sbp_sleep(1); /* wait a bit, try again */
2397 if (status_tries == 0)
2399 DPRINTF((DBG_INF,"SBPCD: sbp_status: failed after 3 tries\n"));
2400 break;
2403 sbp_read_cmd();
2404 sbp_sleep(0);
2405 if (sbp_data() != 0)
2407 end_request(1);
2408 goto request_loop;
2412 end_request(0);
2413 sbp_sleep(10); /* wait a bit, try again */
2414 goto request_loop;
2416 /*==========================================================================*/
2418 * build and send the READ command.
2419 * Maybe it would be better to "set mode1" before ...
2421 static void sbp_read_cmd(void)
2423 int i;
2424 int block;
2426 DS[d].sbp_first_frame=DS[d].sbp_last_frame=-1; /* purge buffer */
2427 block=CURRENT->sector/4;
2429 if (new_drive)
2431 #if MANY_SESSION
2432 DPRINTF((DBG_MUL,"SBPCD: read MSF %08X\n", blk2msf(block)));
2433 if ( (DS[d].f_multisession) && (multisession_valid) )
2435 DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
2436 blk2msf(DS[d].lba_multi+block),
2437 blk2msf(block)));
2438 block=DS[d].lba_multi+block;
2440 #else
2441 if ( (block==166) && (DS[d].f_multisession) && (multisession_valid) )
2443 DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
2444 blk2msf(DS[d].lba_multi+16),
2445 blk2msf(block)));
2446 block=DS[d].lba_multi+16;
2448 #endif MANY_SESSION
2451 if (block+SBP_BUFFER_FRAMES <= DS[d].CDsize_frm)
2452 DS[d].sbp_read_frames = SBP_BUFFER_FRAMES;
2453 else
2455 DS[d].sbp_read_frames=DS[d].CDsize_frm-block;
2456 /* avoid reading past end of data */
2457 if (DS[d].sbp_read_frames < 1)
2459 DPRINTF((DBG_INF,"SBPCD: requested frame %d, CD size %d ???\n",
2460 block, DS[d].CDsize_frm));
2461 DS[d].sbp_read_frames=1;
2464 DS[d].sbp_current = 0;
2466 flags_cmd_out = f_putcmd |
2467 f_respo2 |
2468 f_ResponseStatus |
2469 f_obey_p_check;
2471 if (!new_drive)
2473 if (DS[d].drv_type>=drv_201)
2475 lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
2476 bin2bcdx(&drvcmd[1]);
2477 bin2bcdx(&drvcmd[2]);
2478 bin2bcdx(&drvcmd[3]);
2480 else
2482 drvcmd[1]=(block>>16)&0x000000ff;
2483 drvcmd[2]=(block>>8)&0x000000ff;
2484 drvcmd[3]=block&0x000000ff;
2486 drvcmd[4]=0;
2487 drvcmd[5]=DS[d].sbp_read_frames;
2488 drvcmd[6]=(DS[d].drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
2489 drvcmd[0]=0x02; /* "read frames" command for old drives */
2490 flags_cmd_out |= f_lopsta|f_getsta|f_bit1;
2492 else /* if new_drive */
2494 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
2495 drvcmd[4]=0;
2496 drvcmd[5]=0;
2497 drvcmd[6]=DS[d].sbp_read_frames;
2498 drvcmd[0]=0x10; /* "read frames" command for new drives */
2500 #if SBPCD_DIS_IRQ
2501 cli();
2502 #endif SBPCD_DIS_IRQ
2503 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
2504 #if SBPCD_DIS_IRQ
2505 sti();
2506 #endif SBPCD_DIS_IRQ
2508 return;
2510 /*==========================================================================*/
2512 * Check the completion of the read-data command. On success, read
2513 * the SBP_BUFFER_FRAMES * 2048 bytes of data from the disk into buffer.
2515 static int sbp_data(void)
2517 int i=0, j=0, frame;
2518 u_int try=0;
2519 u_long timeout;
2520 u_char *p;
2521 u_int data_tries = 0;
2522 u_int data_waits = 0;
2523 u_int data_retrying = 0;
2524 int error_flag;
2526 error_flag=0;
2528 for (frame=DS[d].sbp_current;frame<DS[d].sbp_read_frames&&!error_flag; frame++)
2530 #if SBPCD_DIS_IRQ
2531 cli();
2532 #endif SBPCD_DIS_IRQ
2533 try=maxtim_data;
2534 for (timeout=jiffies+100; ; )
2536 for ( ; try!=0;try--)
2538 j=inb(CDi_status);
2539 if (!(j&s_not_data_ready)) break;
2540 if (!(j&s_not_result_ready)) break;
2541 if (!new_drive) if (j&s_attention) break;
2543 if (try != 0 || timeout <= jiffies) break;
2544 if (data_retrying == 0) data_waits++;
2545 data_retrying = 1;
2546 sbp_sleep(1);
2547 try = 1;
2549 if (try==0)
2551 DPRINTF((DBG_INF,"SBPCD: sbp_data: CDi_status timeout.\n"));
2552 error_flag++;
2553 break;
2556 if (j&s_not_data_ready)
2558 if ((DS[d].ored_ctl_adr&0x40)==0)
2559 DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
2560 else DPRINTF((DBG_INF,"SBPCD: sbp_data: DATA_READY timeout.\n"));
2561 error_flag++;
2562 break;
2565 #if SBPCD_DIS_IRQ
2566 sti();
2567 #endif SBPCD_DIS_IRQ
2569 CLEAR_TIMER;
2570 error_flag=0;
2571 p = DS[d].sbp_buf + frame * CD_FRAMESIZE;
2573 if (sbpro_type) OUT(CDo_sel_d_i,0x01);
2574 READ_DATA(CDi_data, p, CD_FRAMESIZE);
2575 if (sbpro_type) OUT(CDo_sel_d_i,0x00);
2576 DS[d].sbp_current++;
2578 data_tries++;
2579 data_retrying = 0;
2580 if (data_tries >= 1000)
2582 DPRINTF((DBG_INF,"SBPCD: info: %d waits in %d frames.\n",
2583 data_waits, data_tries));
2584 data_waits = data_tries = 0;
2587 #if SBPCD_DIS_IRQ
2588 sti();
2589 #endif SBPCD_DIS_IRQ
2591 if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
2593 DPRINTF((DBG_INF,"SBPCD: read aborted by drive\n"));
2594 i=DriveReset(); /* ugly fix to prevent a hang */
2595 return (0);
2598 if (!new_drive)
2600 #if SBPCD_DIS_IRQ
2601 cli();
2602 #endif SBPCD_DIS_IRQ
2603 i=maxtim_data;
2604 for (timeout=jiffies+100; timeout > jiffies; timeout--)
2606 for ( ;i!=0;i--)
2608 j=inb(CDi_status);
2609 if (!(j&s_not_data_ready)) break;
2610 if (!(j&s_not_result_ready)) break;
2611 if (j&s_attention) break;
2613 if (i != 0 || timeout <= jiffies) break;
2614 sbp_sleep(0);
2615 i = 1;
2617 if (i==0) { DPRINTF((DBG_INF,"SBPCD: STATUS TIMEOUT AFTER READ")); }
2618 if (!(j&s_attention))
2620 DPRINTF((DBG_INF,"SBPCD: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
2621 i=DriveReset(); /* ugly fix to prevent a hang */
2622 #if SBPCD_DIS_IRQ
2623 sti();
2624 #endif SBPCD_DIS_IRQ
2625 return (0);
2627 #if SBPCD_DIS_IRQ
2628 sti();
2629 #endif SBPCD_DIS_IRQ
2634 if (!new_drive) xx_ReadStatus();
2635 i=ResponseStatus(); /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */
2636 if (i<0) { DPRINTF((DBG_INF,"SBPCD: xx_ReadStatus error after read: %02X\n",
2637 DS[d].status_byte));
2638 return (0);
2641 while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
2642 if (st_check)
2644 i=xx_ReadError();
2645 DPRINTF((DBG_INF,"SBPCD: xx_ReadError was necessary after read: %02X\n",i));
2646 return (0);
2649 DS[d].sbp_first_frame = CURRENT -> sector / 4;
2650 DS[d].sbp_last_frame = DS[d].sbp_first_frame + DS[d].sbp_read_frames - 1;
2651 sbp_transfer();
2652 return (1);
2654 /*==========================================================================*/
2655 /*==========================================================================*/
2657 * Open the device special file. Check that a disk is in. Read TOC.
2659 int sbpcd_open(struct inode *ip, struct file *fp)
2661 int i;
2663 if (ndrives==0) return (-ENXIO); /* no hardware */
2665 i = MINOR(ip->i_rdev);
2666 if ( (i<0) || (i>=NR_SBPCD) )
2668 DPRINTF((DBG_INF,"SBPCD: open: bad device: %d\n", i));
2669 return (-ENODEV); /* no such drive */
2671 switch_drive(i);
2673 if (!st_spinning) xx_SpinUp();
2675 flags_cmd_out |= f_respo2;
2676 xx_ReadStatus(); /* command: give 1-byte status */
2677 i=ResponseStatus();
2678 if (i<0)
2680 DPRINTF((DBG_INF,"SBPCD: sbpcd_open: xx_ReadStatus timed out\n"));
2681 return (-EIO); /* drive doesn't respond */
2683 DPRINTF((DBG_STA,"SBPCD: sbpcd_open: status %02X\n", DS[d].status_byte));
2684 if (!st_door_closed||!st_caddy_in)
2686 DPRINTF((DBG_INF,"SBPCD: sbpcd_open: no disk in drive\n"));
2687 return (-EIO);
2691 * we could try to keep an "open" counter here and lock the door if 0->1.
2692 * not done yet.
2696 if (!st_spinning) xx_SpinUp();
2698 i=DiskInfo();
2699 if ((DS[d].ored_ctl_adr&0x40)==0)
2700 DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
2701 return (0);
2703 /*==========================================================================*/
2705 * On close, we flush all sbp blocks from the buffer cache.
2707 static void sbpcd_release(struct inode * ip, struct file * file)
2709 int i;
2711 * we could try to count down an "open" counter here
2712 * and unlock the door if zero.
2713 * not done yet.
2716 i = MINOR(ip->i_rdev);
2717 if ( (i<0) || (i>=NR_SBPCD) )
2719 DPRINTF((DBG_INF,"SBPCD: release: bad device: %d\n", i));
2720 return;
2722 switch_drive(i);
2724 DS[d].sbp_first_frame=DS[d].sbp_last_frame=-1;
2725 sync_dev(ip->i_rdev); /* nonsense if read only device? */
2726 invalidate_buffers(ip->i_rdev);
2727 DS[d].diskstate_flags &= ~cd_size_bit;
2729 /*==========================================================================*/
2733 static struct file_operations sbpcd_fops =
2735 NULL, /* lseek - default */
2736 block_read, /* read - general block-dev read */
2737 block_write, /* write - general block-dev write */
2738 NULL, /* readdir - bad */
2739 NULL, /* select */
2740 sbpcd_ioctl, /* ioctl */
2741 NULL, /* mmap */
2742 sbpcd_open, /* open */
2743 sbpcd_release /* release */
2745 /*==========================================================================*/
2747 * SBP interrupt descriptor
2749 #if SBPCD_USE_IRQ
2750 static struct sigaction sbpcd_sigaction =
2752 sbpcd_interrupt,
2754 SA_INTERRUPT,
2755 NULL
2757 #endif SBPCD_USE_IRQ
2758 /*==========================================================================*/
2760 * accept "kernel command line" parameters
2761 * (suggested by Peter MacDonald with SLS 1.03)
2763 * use: tell LILO:
2764 * sbpcd=0x230,SoundBlaster
2765 * or
2766 * sbpcd=0x300,LaserMate
2768 * (upper/lower case sensitive here!!!).
2770 * the address value has to be the TRUE CDROM PORT ADDRESS -
2771 * not the soundcard base address.
2774 void sbpcd_setup(char *s, int *p)
2776 DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s));
2777 if (!strcmp(s,str_sb)) sbpro_type=1;
2778 else sbpro_type=0;
2779 if (p[0]>0) sbpcd_ioaddr=p[1];
2781 CDo_command=sbpcd_ioaddr;
2782 CDi_info=sbpcd_ioaddr;
2783 CDi_status=sbpcd_ioaddr+1;
2784 CDo_reset=sbpcd_ioaddr+2;
2785 CDo_enable=sbpcd_ioaddr+3;
2786 if (sbpro_type==1)
2788 MIXER_addr=sbpcd_ioaddr-0x10+0x04;
2789 MIXER_data=sbpcd_ioaddr-0x10+0x05;
2790 CDo_sel_d_i=sbpcd_ioaddr+1;
2791 CDi_data=sbpcd_ioaddr;
2793 else CDi_data=sbpcd_ioaddr+2;
2795 /*==========================================================================*/
2797 * Test for presence of drive and initialize it. Called at boot time.
2799 u_long sbpcd_init(u_long mem_start, u_long mem_end)
2801 int i=0, j=0;
2802 int addr[2]={1, CDROM_PORT};
2803 int port_index;
2805 DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION));
2807 DPRINTF((DBG_INF,"SBPCD: Looking for a SoundBlaster/Matsushita CD-ROM drive\n"));
2808 DPRINTF((DBG_WRN,"SBPCD: \n"));
2809 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = W A R N I N G = = = = = = = = = =\n"));
2810 DPRINTF((DBG_WRN,"SBPCD: Auto-Probing can cause a hang (f.e. touching an ethernet card).\n"));
2811 DPRINTF((DBG_WRN,"SBPCD: If that happens, you have to reboot and use the\n"));
2812 DPRINTF((DBG_WRN,"SBPCD: LILO (kernel) command line feature like:\n"));
2813 DPRINTF((DBG_WRN,"SBPCD: \n"));
2814 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x230,SoundBlaster\n"));
2815 DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
2816 DPRINTF((DBG_WRN,"SBPCD: LILO boot: linux sbpcd=0x300,LaserMate\n"));
2817 DPRINTF((DBG_WRN,"SBPCD: \n"));
2818 DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n"));
2819 DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n"));
2820 DPRINTF((DBG_WRN,"SBPCD: \n"));
2821 sti(); /* to avoid possible "printk" bug */
2823 autoprobe[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
2824 autoprobe[1]=sbpro_type; /* possibly changed by kernel command line */
2826 for (port_index=0;port_index<NUM_AUTOPROBE;port_index+=2)
2828 addr[1]=autoprobe[port_index];
2829 if (check_region(addr[1],4)) continue;
2830 DPRINTF((DBG_INI,"SBPCD: check_region done.\n"));
2831 if (autoprobe[port_index+1]==0) type=str_lm;
2832 else type=str_sb;
2833 sbpcd_setup(type, addr);
2834 DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n",
2835 type, CDo_command));
2837 DPRINTF((DBG_INF,"SBPCD: - "));
2838 sti(); /* to avoid possible "printk" bug */
2839 i=check_drives();
2840 DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
2841 sti(); /* to avoid possible "printk" bug */
2842 if (i>=0) break; /* drive found */
2843 printk ("\n");
2844 sti(); /* to avoid possible "printk" bug */
2845 } /* end of cycling through the set of possible I/O port addresses */
2847 if (ndrives==0)
2849 DPRINTF((DBG_INF,"SBPCD: No drive found.\n"));
2850 sti();
2851 return (mem_start);
2854 DPRINTF((DBG_INF,"SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
2855 ndrives, type, CDo_command));
2856 sti(); /* to avoid possible "printk" bug */
2857 check_datarate();
2858 DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
2859 sti(); /* to avoid possible "printk" bug */
2861 for (j=0;j<NR_SBPCD;j++)
2863 if (DS[j].drv_minor==-1) continue;
2864 switch_drive(j);
2865 xy_DriveReset();
2866 if (!st_spinning) xx_SpinUp();
2867 DS[d].sbp_first_frame = -1; /* First frame in buffer */
2868 DS[d].sbp_last_frame = -1; /* Last frame in buffer */
2869 DS[d].sbp_read_frames = 0; /* Number of frames being read to buffer */
2870 DS[d].sbp_current = 0; /* Frame being currently read */
2871 DS[d].CD_changed=1;
2872 DS[d].frame_size=CD_FRAMESIZE;
2874 xx_ReadStatus();
2875 i=ResponseStatus(); /* returns orig. status or p_busy_new */
2876 if (i<0)
2877 DPRINTF((DBG_INF,"SBPCD: init: ResponseStatus returns %02X\n",i));
2878 else
2880 if (st_check)
2882 i=xx_ReadError();
2883 DPRINTF((DBG_INI,"SBPCD: init: xx_ReadError returns %d\n",i));
2884 sti(); /* to avoid possible "printk" bug */
2887 DPRINTF((DBG_INI,"SBPCD: init: first GetStatus: %d\n",i));
2888 sti(); /* to avoid possible "printk" bug */
2889 if (DS[d].error_byte==aud_12)
2891 do { i=GetStatus();
2892 DPRINTF((DBG_INI,"SBPCD: init: second GetStatus: %02X\n",i));
2893 sti(); /* to avoid possible "printk" bug */
2894 if (i<0) break;
2895 if (!st_caddy_in) break;
2897 while (!st_diskok);
2899 i=SetSpeed();
2900 if (i>=0) DS[d].CD_changed=1;
2903 if (sbpro_type)
2905 OUT(MIXER_addr,MIXER_CD_Volume);
2906 OUT(MIXER_data,0xCC); /* one nibble per channel */
2909 if (register_blkdev(MATSUSHITA_CDROM_MAJOR, "sbpcd", &sbpcd_fops) != 0)
2911 DPRINTF((DBG_INF,"SBPCD: Can't get MAJOR %d for Matsushita CDROM\n",
2912 MATSUSHITA_CDROM_MAJOR));
2913 sti(); /* to avoid possible "printk" bug */
2914 return (mem_start);
2916 blk_dev[MATSUSHITA_CDROM_MAJOR].request_fn = DEVICE_REQUEST;
2917 read_ahead[MATSUSHITA_CDROM_MAJOR] = 4; /* just one frame */
2919 snarf_region(CDo_command,4);
2921 #if SBPCD_USE_IRQ
2922 if (irqaction(SBPCD_INTR_NR, &sbpcd_sigaction))
2924 DPRINTF((DBG_INF,"SBPCD: Can't get IRQ%d for sbpcd driver\n",
2925 SBPCD_INTR_NR));
2926 sti(); /* to avoid possible "printk" bug */
2928 #endif SBPCD_USE_IRQ
2931 * allocate memory for the frame buffers
2933 for (j=0;j<NR_SBPCD;j++)
2935 if (DS[j].drv_minor==-1) continue;
2936 DS[j].sbp_buf=(u_char *)mem_start;
2937 mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE;
2939 DPRINTF((DBG_INF,"SBPCD: init done.\n"));
2940 sti(); /* to avoid possible "printk" bug */
2941 return (mem_start);
2943 /*==========================================================================*/
2945 * adopted from sr.c
2947 * Check if the media has changed in the CD-ROM drive.
2948 * used externally (isofs/inode.c) - but still does not work.
2951 int check_sbpcd_media_change(int full_dev, int unused_minor)
2953 int st;
2955 if (MAJOR(full_dev) != MATSUSHITA_CDROM_MAJOR)
2957 DPRINTF((DBG_INF,"SBPCD: media_check: invalid device.\n"));
2958 return (-1);
2961 xx_ReadStatus(); /* command: give 1-byte status */
2962 st=ResponseStatus();
2963 DPRINTF((DBG_CHK,"SBPCD: media_check: %02X\n",DS[d].status_byte));
2964 if (st<0)
2966 DPRINTF((DBG_INF,"SBPCD: media_check: ResponseStatus error.\n"));
2967 return (1); /* status not obtainable */
2969 if (DS[d].CD_changed==0xFF) DPRINTF((DBG_CHK,"SBPCD: media_check: \"changed\" assumed.\n"));
2970 if (!st_spinning) DPRINTF((DBG_CHK,"SBPCD: media_check: motor off.\n"));
2971 if (!st_door_closed)
2973 DPRINTF((DBG_CHK,"SBPCD: media_check: door open.\n"));
2974 DS[d].CD_changed=0xFF;
2976 if (!st_caddy_in)
2978 DPRINTF((DBG_CHK,"SBPCD: media_check: no disk in drive.\n"));
2979 DS[d].CD_changed=0xFF;
2981 if (!st_diskok) DPRINTF((DBG_CHK,"SBPCD: media_check: !st_diskok.\n"));
2983 #if 0000
2984 if (DS[d].CD_changed==0xFF)
2986 DS[d].CD_changed=1;
2987 return (1); /* driver had a change detected before */
2989 #endif 0000 /* seems to give additional errors at the moment */
2991 if (!st_diskok) return (1); /* disk not o.k. */
2992 if (!st_caddy_in) return (1); /* disk removed */
2993 if (!st_door_closed) return (1); /* door open */
2994 return (0);
2996 /*==========================================================================*/