File: /usr/src/linux/drivers/cdrom/optcd.c

1     /*	linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver
2     	$Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $
3     
4     	Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
5     
6     
7     	Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks
8     	by Eberhard Moenkeberg (emoenke@gwdg.de). 
9     
10     	This program is free software; you can redistribute it and/or modify
11     	it under the terms of the GNU General Public License as published by
12     	the Free Software Foundation; either version 2, or (at your option)
13     	any later version.
14     
15     	This program is distributed in the hope that it will be useful,
16     	but WITHOUT ANY WARRANTY; without even the implied warranty of
17     	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     	GNU General Public License for more details.
19     
20     	You should have received a copy of the GNU General Public License
21     	along with this program; if not, write to the Free Software
22     	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23     */
24     
25     /*	Revision history
26     
27     
28     	14-5-95		v0.0	Plays sound tracks. No reading of data CDs yet.
29     				Detection of disk change doesn't work.
30     	21-5-95		v0.1	First ALPHA version. CD can be mounted. The
31     				device major nr is borrowed from the Aztech
32     				driver. Speed is around 240 kb/s, as measured
33     				with "time dd if=/dev/cdrom of=/dev/null \
34     				bs=2048 count=4096".
35     	24-6-95		v0.2	Reworked the #defines for the command codes
36     				and the like, as well as the structure of
37     				the hardware communication protocol, to
38     				reflect the "official" documentation, kindly
39     				supplied by C.K. Tan, Optics Storage Pte. Ltd.
40     				Also tidied up the state machine somewhat.
41     	28-6-95		v0.3	Removed the ISP-16 interface code, as this
42     				should go into its own driver. The driver now
43     				has its own major nr.
44     				Disk change detection now seems to work, too.
45     				This version became part of the standard
46     				kernel as of version 1.3.7
47     	24-9-95		v0.4	Re-inserted ISP-16 interface code which I
48     				copied from sjcd.c, with a few changes.
49     				Updated README.optcd. Submitted for
50     				inclusion in 1.3.21
51     	29-9-95		v0.4a	Fixed bug that prevented compilation as module
52     	25-10-95	v0.5	Started multisession code. Implementation
53     				copied from Werner Zimmermann, who copied it
54     				from Heiko Schlittermann's mcdx.
55     	17-1-96		v0.6	Multisession works; some cleanup too.
56     	18-4-96		v0.7	Increased some timing constants;
57     				thanks to Luke McFarlane. Also tidied up some
58     				printk behaviour. ISP16 initialization
59     				is now handled by a separate driver.
60     				
61     	09-11-99 	  	Make kernel-parameter implementation work with 2.3.x 
62     	                 	Removed init_module & cleanup_module in favor of 
63     			 	module_init & module_exit.
64     			 	Torben Mathiasen <tmm@image.dk>
65     */
66     
67     /* Includes */
68     
69     
70     #include <linux/module.h>
71     #include <linux/mm.h>
72     #include <linux/ioport.h>
73     #include <linux/init.h>
74     #include <linux/devfs_fs_kernel.h>
75     
76     #include <asm/io.h>
77     
78     #define MAJOR_NR OPTICS_CDROM_MAJOR
79     #include <linux/blk.h>
80     
81     #include <linux/cdrom.h>
82     #include "optcd.h"
83     
84     #include <asm/uaccess.h>
85     
86     
87     /* Debug support */
88     
89     
90     /* Don't forget to add new debug flags here. */
91     #if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \
92         DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS
93     #define DEBUG(x) debug x
94     static void debug(int debug_this, const char* fmt, ...)
95     {
96     	char s[1024];
97     	va_list args;
98     
99     	if (!debug_this)
100     		return;
101     
102     	va_start(args, fmt);
103     	vsprintf(s, fmt, args);
104     	printk(KERN_DEBUG "optcd: %s\n", s);
105     	va_end(args);
106     }
107     #else
108     #define DEBUG(x)
109     #endif
110     
111     static int blksize = 2048;
112     static int hsecsize = 2048;
113     
114     
115     /* Drive hardware/firmware characteristics
116        Identifiers in accordance with Optics Storage documentation */
117     
118     
119     #define optcd_port optcd			/* Needed for the modutils. */
120     static short optcd_port = OPTCD_PORTBASE;	/* I/O base of drive. */
121     MODULE_PARM(optcd_port, "h");
122     /* Drive registers, read */
123     #define DATA_PORT	optcd_port	/* Read data/status */
124     #define STATUS_PORT	optcd_port+1	/* Indicate data/status availability */
125     
126     /* Drive registers, write */
127     #define COMIN_PORT	optcd_port	/* For passing command/parameter */
128     #define RESET_PORT	optcd_port+1	/* Write anything and wait 0.5 sec */
129     #define HCON_PORT	optcd_port+2	/* Host Xfer Configuration */
130     
131     
132     /* Command completion/status read from DATA register */
133     #define ST_DRVERR		0x80
134     #define ST_DOOR_OPEN		0x40
135     #define ST_MIXEDMODE_DISK	0x20
136     #define ST_MODE_BITS		0x1c
137     #define ST_M_STOP		0x00
138     #define ST_M_READ		0x04
139     #define ST_M_AUDIO		0x04
140     #define ST_M_PAUSE		0x08
141     #define ST_M_INITIAL		0x0c
142     #define ST_M_ERROR		0x10
143     #define ST_M_OTHERS		0x14
144     #define	ST_MODE2TRACK		0x02
145     #define	ST_DSK_CHG		0x01
146     #define ST_L_LOCK		0x01
147     #define ST_CMD_OK		0x00
148     #define ST_OP_OK		0x01
149     #define ST_PA_OK		0x02
150     #define ST_OP_ERROR		0x05
151     #define ST_PA_ERROR		0x06
152     
153     
154     /* Error codes (appear as command completion code from DATA register) */
155     /* Player related errors */
156     #define ERR_ILLCMD	0x11	/* Illegal command to player module */
157     #define ERR_ILLPARM	0x12	/* Illegal parameter to player module */
158     #define ERR_SLEDGE	0x13
159     #define ERR_FOCUS	0x14
160     #define ERR_MOTOR	0x15
161     #define ERR_RADIAL	0x16
162     #define ERR_PLL		0x17	/* PLL lock error */
163     #define ERR_SUB_TIM	0x18	/* Subcode timeout error */
164     #define ERR_SUB_NF	0x19	/* Subcode not found error */
165     #define ERR_TRAY	0x1a
166     #define ERR_TOC		0x1b	/* Table of Contents read error */
167     #define ERR_JUMP	0x1c
168     /* Data errors */
169     #define ERR_MODE	0x21
170     #define ERR_FORM	0x22
171     #define ERR_HEADADDR	0x23	/* Header Address not found */
172     #define ERR_CRC		0x24
173     #define ERR_ECC		0x25	/* Uncorrectable ECC error */
174     #define ERR_CRC_UNC	0x26	/* CRC error and uncorrectable error */
175     #define ERR_ILLBSYNC	0x27	/* Illegal block sync error */
176     #define ERR_VDST	0x28	/* VDST not found */
177     /* Timeout errors */
178     #define ERR_READ_TIM	0x31	/* Read timeout error */
179     #define ERR_DEC_STP	0x32	/* Decoder stopped */
180     #define ERR_DEC_TIM	0x33	/* Decoder interrupt timeout error */
181     /* Function abort codes */
182     #define ERR_KEY		0x41	/* Key -Detected abort */
183     #define ERR_READ_FINISH	0x42	/* Read Finish */
184     /* Second Byte diagnostic codes */
185     #define ERR_NOBSYNC	0x01	/* No block sync */
186     #define ERR_SHORTB	0x02	/* Short block */
187     #define ERR_LONGB	0x03	/* Long block */
188     #define ERR_SHORTDSP	0x04	/* Short DSP word */
189     #define ERR_LONGDSP	0x05	/* Long DSP word */
190     
191     
192     /* Status availability flags read from STATUS register */
193     #define FL_EJECT	0x20
194     #define FL_WAIT		0x10	/* active low */
195     #define FL_EOP		0x08	/* active low */
196     #define FL_STEN		0x04	/* Status available when low */
197     #define FL_DTEN		0x02	/* Data available when low */
198     #define FL_DRQ		0x01	/* active low */
199     #define FL_RESET	0xde	/* These bits are high after a reset */
200     #define FL_STDT		(FL_STEN|FL_DTEN)
201     
202     
203     /* Transfer mode, written to HCON register */
204     #define HCON_DTS	0x08
205     #define HCON_SDRQB	0x04
206     #define HCON_LOHI	0x02
207     #define HCON_DMA16	0x01
208     
209     
210     /* Drive command set, written to COMIN register */
211     /* Quick response commands */
212     #define COMDRVST	0x20	/* Drive Status Read */
213     #define COMERRST	0x21	/* Error Status Read */
214     #define COMIOCTLISTAT	0x22	/* Status Read; reset disk changed bit */
215     #define COMINITSINGLE	0x28	/* Initialize Single Speed */
216     #define COMINITDOUBLE	0x29	/* Initialize Double Speed */
217     #define COMUNLOCK	0x30	/* Unlock */
218     #define COMLOCK		0x31	/* Lock */
219     #define COMLOCKST	0x32	/* Lock/Unlock Status */
220     #define COMVERSION	0x40	/* Get Firmware Revision */
221     #define COMVOIDREADMODE	0x50	/* Void Data Read Mode */
222     /* Read commands */
223     #define COMFETCH	0x60	/* Prefetch Data */
224     #define COMREAD		0x61	/* Read */
225     #define COMREADRAW	0x62	/* Read Raw Data */
226     #define COMREADALL	0x63	/* Read All 2646 Bytes */
227     /* Player control commands */
228     #define COMLEADIN	0x70	/* Seek To Lead-in */
229     #define COMSEEK		0x71	/* Seek */
230     #define COMPAUSEON	0x80	/* Pause On */
231     #define COMPAUSEOFF	0x81	/* Pause Off */
232     #define COMSTOP		0x82	/* Stop */
233     #define COMOPEN		0x90	/* Open Tray Door */
234     #define COMCLOSE	0x91	/* Close Tray Door */
235     #define COMPLAY		0xa0	/* Audio Play */
236     #define COMPLAY_TNO	0xa2	/* Audio Play By Track Number */
237     #define COMSUBQ		0xb0	/* Read Sub-q Code */
238     #define COMLOCATION	0xb1	/* Read Head Position */
239     /* Audio control commands */
240     #define COMCHCTRL	0xc0	/* Audio Channel Control */
241     /* Miscellaneous (test) commands */
242     #define COMDRVTEST	0xd0	/* Write Test Bytes */
243     #define COMTEST		0xd1	/* Diagnostic Test */
244     
245     /* Low level drive interface. Only here we do actual I/O
246        Waiting for status / data available */
247     
248     
249     /* Busy wait until FLAG goes low. Return 0 on timeout. */
250     inline static int flag_low(int flag, unsigned long timeout)
251     {
252     	int flag_high;
253     	unsigned long count = 0;
254     
255     	while ((flag_high = (inb(STATUS_PORT) & flag)))
256     		if (++count >= timeout)
257     			break;
258     
259     	DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s",
260     		flag, count, flag_high ? " timeout" : ""));
261     	return !flag_high;
262     }
263     
264     
265     /* Timed waiting for status or data */
266     static int sleep_timeout;	/* max # of ticks to sleep */
267     static DECLARE_WAIT_QUEUE_HEAD(waitq);
268     static void sleep_timer(unsigned long data);
269     static struct timer_list delay_timer = {function: sleep_timer};
270     
271     
272     /* Timer routine: wake up when desired flag goes low,
273        or when timeout expires. */
274     static void sleep_timer(unsigned long data)
275     {
276     	int flags = inb(STATUS_PORT) & FL_STDT;
277     
278     	if (flags == FL_STDT && --sleep_timeout > 0) {
279     		mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
280     	} else
281     		wake_up(&waitq);
282     }
283     
284     
285     /* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */
286     static int sleep_flag_low(int flag, unsigned long timeout)
287     {
288     	int flag_high;
289     
290     	DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low"));
291     
292     	sleep_timeout = timeout;
293     	flag_high = inb(STATUS_PORT) & flag;
294     	if (flag_high && sleep_timeout > 0) {
295     		mod_timer(&delay_timer, jiffies + HZ/100);
296     		sleep_on(&waitq);
297     		flag_high = inb(STATUS_PORT) & flag;
298     	}
299     
300     	DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s",
301     		flag, timeout, flag_high ? " timeout" : ""));
302     	return !flag_high;
303     }
304     
305     /* Low level drive interface. Only here we do actual I/O
306        Sending commands and parameters */
307     
308     
309     /* Errors in the command protocol */
310     #define ERR_IF_CMD_TIMEOUT	0x100
311     #define ERR_IF_ERR_TIMEOUT	0x101
312     #define ERR_IF_RESP_TIMEOUT	0x102
313     #define ERR_IF_DATA_TIMEOUT	0x103
314     #define ERR_IF_NOSTAT		0x104
315     
316     
317     /* Send command code. Return <0 indicates error */
318     static int send_cmd(int cmd)
319     {
320     	unsigned char ack;
321     
322     	DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd));
323     
324     	outb(HCON_DTS, HCON_PORT);	/* Enable Suspend Data Transfer */
325     	outb(cmd, COMIN_PORT);		/* Send command code */
326     	if (!flag_low(FL_STEN, BUSY_TIMEOUT))	/* Wait for status */
327     		return -ERR_IF_CMD_TIMEOUT;
328     	ack = inb(DATA_PORT);		/* read command acknowledge */
329     	outb(HCON_SDRQB, HCON_PORT);	/* Disable Suspend Data Transfer */
330     	return ack==ST_OP_OK ? 0 : -ack;
331     }
332     
333     
334     /* Send command parameters. Return <0 indicates error */
335     static int send_params(struct cdrom_msf *params)
336     {
337     	unsigned char ack;
338     
339     	DEBUG((DEBUG_DRIVE_IF, "sending parameters"
340     		" %02x:%02x:%02x"
341     		" %02x:%02x:%02x",
342     		params->cdmsf_min0,
343     		params->cdmsf_sec0,
344     		params->cdmsf_frame0,
345     		params->cdmsf_min1,
346     		params->cdmsf_sec1,
347     		params->cdmsf_frame1));
348     
349     	outb(params->cdmsf_min0, COMIN_PORT);
350     	outb(params->cdmsf_sec0, COMIN_PORT);
351     	outb(params->cdmsf_frame0, COMIN_PORT);
352     	outb(params->cdmsf_min1, COMIN_PORT);
353     	outb(params->cdmsf_sec1, COMIN_PORT);
354     	outb(params->cdmsf_frame1, COMIN_PORT);
355     	if (!flag_low(FL_STEN, BUSY_TIMEOUT))	/* Wait for status */
356     		return -ERR_IF_CMD_TIMEOUT;
357     	ack = inb(DATA_PORT);		/* read command acknowledge */
358     	return ack==ST_PA_OK ? 0 : -ack;
359     }
360     
361     
362     /* Send parameters for SEEK command. Return <0 indicates error */
363     static int send_seek_params(struct cdrom_msf *params)
364     {
365     	unsigned char ack;
366     
367     	DEBUG((DEBUG_DRIVE_IF, "sending seek parameters"
368     		" %02x:%02x:%02x",
369     		params->cdmsf_min0,
370     		params->cdmsf_sec0,
371     		params->cdmsf_frame0));
372     
373     	outb(params->cdmsf_min0, COMIN_PORT);
374     	outb(params->cdmsf_sec0, COMIN_PORT);
375     	outb(params->cdmsf_frame0, COMIN_PORT);
376     	if (!flag_low(FL_STEN, BUSY_TIMEOUT))	/* Wait for status */
377     		return -ERR_IF_CMD_TIMEOUT;
378     	ack = inb(DATA_PORT);		/* read command acknowledge */
379     	return ack==ST_PA_OK ? 0 : -ack;
380     }
381     
382     
383     /* Wait for command execution status. Choice between busy waiting
384        and sleeping. Return value <0 indicates timeout. */
385     inline static int get_exec_status(int busy_waiting)
386     {
387     	unsigned char exec_status;
388     
389     	if (busy_waiting
390     	    ? !flag_low(FL_STEN, BUSY_TIMEOUT)
391     	    : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT))
392     		return -ERR_IF_CMD_TIMEOUT;
393     
394     	exec_status = inb(DATA_PORT);
395     	DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status));
396     	return exec_status;
397     }
398     
399     
400     /* Wait busy for extra byte of data that a command returns.
401        Return value <0 indicates timeout. */
402     inline static int get_data(int short_timeout)
403     {
404     	unsigned char data;
405     
406     	if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT))
407     		return -ERR_IF_DATA_TIMEOUT;
408     
409     	data = inb(DATA_PORT);
410     	DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data));
411     	return data;
412     }
413     
414     
415     /* Returns 0 if failed */
416     static int reset_drive(void)
417     {
418     	unsigned long count = 0;
419     	int flags;
420     
421     	DEBUG((DEBUG_DRIVE_IF, "reset drive"));
422     
423     	outb(0, RESET_PORT);
424     	while (++count < RESET_WAIT)
425     		inb(DATA_PORT);
426     
427     	count = 0;
428     	while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET)
429     		if (++count >= BUSY_TIMEOUT)
430     			break;
431     
432     	DEBUG((DEBUG_DRIVE_IF, "reset %s",
433     		flags == FL_RESET ? "succeeded" : "failed"));
434     
435     	if (flags != FL_RESET)
436     		return 0;		/* Reset failed */
437     	outb(HCON_SDRQB, HCON_PORT);	/* Disable Suspend Data Transfer */
438     	return 1;			/* Reset succeeded */
439     }
440     
441     
442     /* Facilities for asynchronous operation */
443     
444     /* Read status/data availability flags FL_STEN and FL_DTEN */
445     inline static int stdt_flags(void)
446     {
447     	return inb(STATUS_PORT) & FL_STDT;
448     }
449     
450     
451     /* Fetch status that has previously been waited for. <0 means not available */
452     inline static int fetch_status(void)
453     {
454     	unsigned char status;
455     
456     	if (inb(STATUS_PORT) & FL_STEN)
457     		return -ERR_IF_NOSTAT;
458     
459     	status = inb(DATA_PORT);
460     	DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status));
461     	return status;
462     }
463     
464     
465     /* Fetch data that has previously been waited for. */
466     inline static void fetch_data(char *buf, int n)
467     {
468     	insb(DATA_PORT, buf, n);
469     	DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
470     }
471     
472     
473     /* Flush status and data fifos */
474     inline static void flush_data(void)
475     {
476     	while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
477     		inb(DATA_PORT);
478     	DEBUG((DEBUG_DRIVE_IF, "flushed fifos"));
479     }
480     
481     /* Command protocol */
482     
483     
484     /* Send a simple command and wait for response. Command codes < COMFETCH
485        are quick response commands */
486     inline static int exec_cmd(int cmd)
487     {
488     	int ack = send_cmd(cmd);
489     	if (ack < 0)
490     		return ack;
491     	return get_exec_status(cmd < COMFETCH);
492     }
493     
494     
495     /* Send a command with parameters. Don't wait for the response,
496      * which consists of data blocks read from the CD. */
497     inline static int exec_read_cmd(int cmd, struct cdrom_msf *params)
498     {
499     	int ack = send_cmd(cmd);
500     	if (ack < 0)
501     		return ack;
502     	return send_params(params);
503     }
504     
505     
506     /* Send a seek command with parameters and wait for response */
507     inline static int exec_seek_cmd(int cmd, struct cdrom_msf *params)
508     {
509     	int ack = send_cmd(cmd);
510     	if (ack < 0)
511     		return ack;
512     	ack = send_seek_params(params);
513     	if (ack < 0)
514     		return ack;
515     	return 0;
516     }
517     
518     
519     /* Send a command with parameters and wait for response */
520     inline static int exec_long_cmd(int cmd, struct cdrom_msf *params)
521     {
522     	int ack = exec_read_cmd(cmd, params);
523     	if (ack < 0)
524     		return ack;
525     	return get_exec_status(0);
526     }
527     
528     /* Address conversion routines */
529     
530     
531     /* Binary to BCD (2 digits) */
532     inline static void single_bin2bcd(u_char *p)
533     {
534     	DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
535     	*p = (*p % 10) | ((*p / 10) << 4);
536     }
537     
538     
539     /* Convert entire msf struct */
540     static void bin2bcd(struct cdrom_msf *msf)
541     {
542     	single_bin2bcd(&msf->cdmsf_min0);
543     	single_bin2bcd(&msf->cdmsf_sec0);
544     	single_bin2bcd(&msf->cdmsf_frame0);
545     	single_bin2bcd(&msf->cdmsf_min1);
546     	single_bin2bcd(&msf->cdmsf_sec1);
547     	single_bin2bcd(&msf->cdmsf_frame1);
548     }
549     
550     
551     /* Linear block address to minute, second, frame form */
552     #define CD_FPM	(CD_SECS * CD_FRAMES)	/* frames per minute */
553     
554     static void lba2msf(int lba, struct cdrom_msf *msf)
555     {
556     	DEBUG((DEBUG_CONV, "lba2msf %d", lba));
557     	lba += CD_MSF_OFFSET;
558     	msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM;
559     	msf->cdmsf_sec0 = lba / CD_FRAMES;
560     	msf->cdmsf_frame0 = lba % CD_FRAMES;
561     	msf->cdmsf_min1 = 0;
562     	msf->cdmsf_sec1 = 0;
563     	msf->cdmsf_frame1 = 0;
564     	bin2bcd(msf);
565     }
566     
567     
568     /* Two BCD digits to binary */
569     inline static u_char bcd2bin(u_char bcd)
570     {
571     	DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
572     	return (bcd >> 4) * 10 + (bcd & 0x0f);
573     }
574     
575     
576     static void msf2lba(union cdrom_addr *addr)
577     {
578     	addr->lba = addr->msf.minute * CD_FPM
579     	            + addr->msf.second * CD_FRAMES
580     	            + addr->msf.frame - CD_MSF_OFFSET;
581     }
582     
583     
584     /* Minute, second, frame address BCD to binary or to linear address,
585        depending on MODE */
586     static void msf_bcd2bin(union cdrom_addr *addr)
587     {
588     	addr->msf.minute = bcd2bin(addr->msf.minute);
589     	addr->msf.second = bcd2bin(addr->msf.second);
590     	addr->msf.frame = bcd2bin(addr->msf.frame);
591     }
592     
593     /* High level drive commands */
594     
595     
596     static int audio_status = CDROM_AUDIO_NO_STATUS;
597     static char toc_uptodate = 0;
598     static char disk_changed = 1;
599     
600     /* Get drive status, flagging completion of audio play and disk changes. */
601     static int drive_status(void)
602     {
603     	int status;
604     
605     	status = exec_cmd(COMIOCTLISTAT);
606     	DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status));
607     	if (status < 0)
608     		return status;
609     	if (status == 0xff)	/* No status available */
610     		return -ERR_IF_NOSTAT;
611     
612     	if (((status & ST_MODE_BITS) != ST_M_AUDIO) &&
613     		(audio_status == CDROM_AUDIO_PLAY)) {
614     		audio_status = CDROM_AUDIO_COMPLETED;
615     	}
616     
617     	if (status & ST_DSK_CHG) {
618     		toc_uptodate = 0;
619     		disk_changed = 1;
620     		audio_status = CDROM_AUDIO_NO_STATUS;
621     	}
622     
623     	return status;
624     }
625     
626     
627     /* Read the current Q-channel info. Also used for reading the
628        table of contents. qp->cdsc_format must be set on entry to
629        indicate the desired address format */
630     static int get_q_channel(struct cdrom_subchnl *qp)
631     {
632     	int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
633     
634     	status = drive_status();
635     	if (status < 0)
636     		return status;
637     	qp->cdsc_audiostatus = audio_status;
638     
639     	status = exec_cmd(COMSUBQ);
640     	if (status < 0)
641     		return status;
642     
643     	d1 = get_data(0);
644     	if (d1 < 0)
645     		return d1;
646     	qp->cdsc_adr = d1;
647     	qp->cdsc_ctrl = d1 >> 4;
648     
649     	d2 = get_data(0);
650     	if (d2 < 0)
651     		return d2;
652     	qp->cdsc_trk = bcd2bin(d2);
653     
654     	d3 = get_data(0);
655     	if (d3 < 0)
656     		return d3;
657     	qp->cdsc_ind = bcd2bin(d3);
658     
659     	d4 = get_data(0);
660     	if (d4 < 0)
661     		return d4;
662     	qp->cdsc_reladdr.msf.minute = d4;
663     
664     	d5 = get_data(0);
665     	if (d5 < 0)
666     		return d5;
667     	qp->cdsc_reladdr.msf.second = d5;
668     
669     	d6 = get_data(0);
670     	if (d6 < 0)
671     		return d6;
672     	qp->cdsc_reladdr.msf.frame = d6;
673     
674     	d7 = get_data(0);
675     	if (d7 < 0)
676     		return d7;
677     	/* byte not used */
678     
679     	d8 = get_data(0);
680     	if (d8 < 0)
681     		return d8;
682     	qp->cdsc_absaddr.msf.minute = d8;
683     
684     	d9 = get_data(0);
685     	if (d9 < 0)
686     		return d9;
687     	qp->cdsc_absaddr.msf.second = d9;
688     
689     	d10 = get_data(0);
690     	if (d10 < 0)
691     		return d10;
692     	qp->cdsc_absaddr.msf.frame = d10;
693     
694     	DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
695     		d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
696     
697     	msf_bcd2bin(&qp->cdsc_absaddr);
698     	msf_bcd2bin(&qp->cdsc_reladdr);
699     	if (qp->cdsc_format == CDROM_LBA) {
700     		msf2lba(&qp->cdsc_absaddr);
701     		msf2lba(&qp->cdsc_reladdr);
702     	}
703     
704     	return 0;
705     }
706     
707     /* Table of contents handling */
708     
709     
710     /* Errors in table of contents */
711     #define ERR_TOC_MISSINGINFO	0x120
712     #define ERR_TOC_MISSINGENTRY	0x121
713     
714     
715     struct cdrom_disk_info {
716     	unsigned char		first;
717     	unsigned char		last;
718     	struct cdrom_msf0	disk_length;
719     	struct cdrom_msf0	first_track;
720     	/* Multisession info: */
721     	unsigned char		next;
722     	struct cdrom_msf0	next_session;
723     	struct cdrom_msf0	last_session;
724     	unsigned char		multi;
725     	unsigned char		xa;
726     	unsigned char		audio;
727     };
728     static struct cdrom_disk_info disk_info;
729     
730     #define MAX_TRACKS		111
731     static struct cdrom_subchnl toc[MAX_TRACKS];
732     
733     #define QINFO_FIRSTTRACK	100 /* bcd2bin(0xa0) */
734     #define QINFO_LASTTRACK		101 /* bcd2bin(0xa1) */
735     #define QINFO_DISKLENGTH	102 /* bcd2bin(0xa2) */
736     #define QINFO_NEXTSESSION	110 /* bcd2bin(0xb0) */
737     
738     #define I_FIRSTTRACK	0x01
739     #define I_LASTTRACK	0x02
740     #define I_DISKLENGTH	0x04
741     #define I_NEXTSESSION	0x08
742     #define I_ALL	(I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH)
743     
744     
745     #if DEBUG_TOC
746     void toc_debug_info(int i)
747     {
748     	printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d"
749     		"  %2d:%02d.%02d %2d:%02d.%02d\n",
750     		i, toc[i].cdsc_ctrl, toc[i].cdsc_adr,
751     		toc[i].cdsc_trk, toc[i].cdsc_ind,
752     		toc[i].cdsc_reladdr.msf.minute,
753     		toc[i].cdsc_reladdr.msf.second,
754     		toc[i].cdsc_reladdr.msf.frame,
755     		toc[i].cdsc_absaddr.msf.minute,
756     		toc[i].cdsc_absaddr.msf.second,
757     		toc[i].cdsc_absaddr.msf.frame);
758     }
759     #endif
760     
761     
762     static int read_toc(void)
763     {
764     	int status, limit, count;
765     	unsigned char got_info = 0;
766     	struct cdrom_subchnl q_info;
767     #if DEBUG_TOC
768     	int i;
769     #endif
770     
771     	DEBUG((DEBUG_TOC, "starting read_toc"));
772     
773     	count = 0;
774     	for (limit = 60; limit > 0; limit--) {
775     		int index;
776     
777     		q_info.cdsc_format = CDROM_MSF;
778     		status = get_q_channel(&q_info);
779     		if (status < 0)
780     			return status;
781     
782     		index = q_info.cdsc_ind;
783     		if (index > 0 && index < MAX_TRACKS
784     		    && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) {
785     			toc[index] = q_info;
786     			DEBUG((DEBUG_TOC, "got %d", index));
787     			if (index < 100)
788     				count++;
789     
790     			switch (q_info.cdsc_ind) {
791     			case QINFO_FIRSTTRACK:
792     				got_info |= I_FIRSTTRACK;
793     				break;
794     			case QINFO_LASTTRACK:
795     				got_info |= I_LASTTRACK;
796     				break;
797     			case QINFO_DISKLENGTH:
798     				got_info |= I_DISKLENGTH;
799     				break;
800     			case QINFO_NEXTSESSION:
801     				got_info |= I_NEXTSESSION;
802     				break;
803     			}
804     		}
805     
806     		if ((got_info & I_ALL) == I_ALL
807     		    && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
808     		       >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
809     			break;
810     	}
811     
812     	/* Construct disk_info from TOC */
813     	if (disk_info.first == 0) {
814     		disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
815     		disk_info.first_track.minute =
816     			toc[disk_info.first].cdsc_absaddr.msf.minute;
817     		disk_info.first_track.second =
818     			toc[disk_info.first].cdsc_absaddr.msf.second;
819     		disk_info.first_track.frame =
820     			toc[disk_info.first].cdsc_absaddr.msf.frame;
821     	}
822     	disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute;
823     	disk_info.disk_length.minute =
824     			toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute;
825     	disk_info.disk_length.second =
826     			toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2;
827     	disk_info.disk_length.frame =
828     			toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame;
829     	disk_info.next_session.minute =
830     			toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute;
831     	disk_info.next_session.second =
832     			toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second;
833     	disk_info.next_session.frame =
834     			toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame;
835     	disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
836     	disk_info.last_session.minute =
837     			toc[disk_info.next].cdsc_absaddr.msf.minute;
838     	disk_info.last_session.second =
839     			toc[disk_info.next].cdsc_absaddr.msf.second;
840     	disk_info.last_session.frame =
841     			toc[disk_info.next].cdsc_absaddr.msf.frame;
842     	toc[disk_info.last + 1].cdsc_absaddr.msf.minute =
843     			disk_info.disk_length.minute;
844     	toc[disk_info.last + 1].cdsc_absaddr.msf.second =
845     			disk_info.disk_length.second;
846     	toc[disk_info.last + 1].cdsc_absaddr.msf.frame =
847     			disk_info.disk_length.frame;
848     #if DEBUG_TOC
849     	for (i = 1; i <= disk_info.last + 1; i++)
850     		toc_debug_info(i);
851     	toc_debug_info(QINFO_FIRSTTRACK);
852     	toc_debug_info(QINFO_LASTTRACK);
853     	toc_debug_info(QINFO_DISKLENGTH);
854     	toc_debug_info(QINFO_NEXTSESSION);
855     #endif
856     
857     	DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d",
858     		got_info, count));
859     	if ((got_info & I_ALL) != I_ALL
860     	    || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
861     	       < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
862     		return -ERR_TOC_MISSINGINFO;
863     	return 0;
864     }
865     
866     
867     #ifdef MULTISESSION
868     static int get_multi_disk_info(void)
869     {
870     	int sessions, status;
871     	struct cdrom_msf multi_index;
872     
873     
874     	for (sessions = 2; sessions < 10 /* %%for now */; sessions++) {
875     		int count;
876     
877     		for (count = 100; count < MAX_TRACKS; count++) 
878     			toc[count].cdsc_ind = 0;
879     
880     		multi_index.cdmsf_min0 = disk_info.next_session.minute;
881     		multi_index.cdmsf_sec0 = disk_info.next_session.second;
882     		multi_index.cdmsf_frame0 = disk_info.next_session.frame;
883     		if (multi_index.cdmsf_sec0 >= 20)
884     			multi_index.cdmsf_sec0 -= 20;
885     		else {
886     			multi_index.cdmsf_sec0 += 40;
887     			multi_index.cdmsf_min0--;
888     		}
889     		DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions,
890     			multi_index.cdmsf_min0,
891     			multi_index.cdmsf_sec0,
892     			multi_index.cdmsf_frame0));
893     		bin2bcd(&multi_index);
894     		multi_index.cdmsf_min1 = 0;
895     		multi_index.cdmsf_sec1 = 0;
896     		multi_index.cdmsf_frame1 = 1;
897     
898     		status = exec_read_cmd(COMREAD, &multi_index);
899     		if (status < 0) {
900     			DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x",
901     				-status));
902     			break;
903     		}
904     		status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ?
905     				0 : -ERR_TOC_MISSINGINFO;
906     		flush_data();
907     		if (status < 0) {
908     			DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status));
909     			break;
910     		}
911     
912     		status = read_toc();
913     		if (status < 0) {
914     			DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
915     			break;
916     		}
917     
918     		disk_info.multi = 1;
919     	}
920     
921     	exec_cmd(COMSTOP);
922     
923     	if (status < 0)
924     		return -EIO;
925     	return 0;
926     }
927     #endif /* MULTISESSION */
928     
929     
930     static int update_toc(void)
931     {
932     	int status, count;
933     
934     	if (toc_uptodate)
935     		return 0;
936     
937     	DEBUG((DEBUG_TOC, "starting update_toc"));
938     
939     	disk_info.first = 0;
940     	for (count = 0; count < MAX_TRACKS; count++) 
941     		toc[count].cdsc_ind = 0;
942     
943     	status = exec_cmd(COMLEADIN);
944     	if (status < 0)
945     		return -EIO;
946     
947     	status = read_toc();
948     	if (status < 0) {
949     		DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
950     		return -EIO;
951     	}
952     
953             /* Audio disk detection. Look at first track. */
954     	disk_info.audio =
955     		(toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1;
956     
957     	/* XA detection */
958     	disk_info.xa = drive_status() & ST_MODE2TRACK;
959     
960     	/* Multisession detection: if we want this, define MULTISESSION */
961     	disk_info.multi = 0;
962     #ifdef MULTISESSION
963      	if (disk_info.xa)
964     		get_multi_disk_info();	/* Here disk_info.multi is set */
965     #endif /* MULTISESSION */
966     	if (disk_info.multi)
967     		printk(KERN_WARNING "optcd: Multisession support experimental, "
968     			"see linux/Documentation/cdrom/optcd\n");
969     
970     	DEBUG((DEBUG_TOC, "exiting update_toc"));
971     
972     	toc_uptodate = 1;
973     	return 0;
974     }
975     
976     /* Request handling */
977     
978     
979     #define CURRENT_VALID \
980     	(!QUEUE_EMPTY && MAJOR(CURRENT -> rq_dev) == MAJOR_NR \
981     	 && CURRENT -> cmd == READ && CURRENT -> sector != -1)
982     
983     
984     /* Buffers for block size conversion. */
985     #define NOBUF		-1
986     
987     static char buf[CD_FRAMESIZE * N_BUFS];
988     static volatile int buf_bn[N_BUFS], next_bn;
989     static volatile int buf_in = 0, buf_out = NOBUF;
990     
991     inline static void opt_invalidate_buffers(void)
992     {
993     	int i;
994     
995     	DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers"));
996     
997     	for (i = 0; i < N_BUFS; i++)
998     		buf_bn[i] = NOBUF;
999     	buf_out = NOBUF;
1000     }
1001     
1002     
1003     /* Take care of the different block sizes between cdrom and Linux.
1004        When Linux gets variable block sizes this will probably go away. */
1005     static void transfer(void)
1006     {
1007     #if DEBUG_BUFFERS | DEBUG_REQUEST
1008     	printk(KERN_DEBUG "optcd: executing transfer\n");
1009     #endif
1010     
1011     	if (!CURRENT_VALID)
1012     		return;
1013     	while (CURRENT -> nr_sectors) {
1014     		int bn = CURRENT -> sector / 4;
1015     		int i, offs, nr_sectors;
1016     		for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i);
1017     
1018     		DEBUG((DEBUG_REQUEST, "found %d", i));
1019     
1020     		if (i >= N_BUFS) {
1021     			buf_out = NOBUF;
1022     			break;
1023     		}
1024     
1025     		offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
1026     		nr_sectors = 4 - (CURRENT -> sector & 3);
1027     
1028     		if (buf_out != i) {
1029     			buf_out = i;
1030     			if (buf_bn[i] != bn) {
1031     				buf_out = NOBUF;
1032     				continue;
1033     			}
1034     		}
1035     
1036     		if (nr_sectors > CURRENT -> nr_sectors)
1037     			nr_sectors = CURRENT -> nr_sectors;
1038     		memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512);
1039     		CURRENT -> nr_sectors -= nr_sectors;
1040     		CURRENT -> sector += nr_sectors;
1041     		CURRENT -> buffer += nr_sectors * 512;
1042     	}
1043     }
1044     
1045     
1046     /* State machine for reading disk blocks */
1047     
1048     enum state_e {
1049     	S_IDLE,		/* 0 */
1050     	S_START,	/* 1 */
1051     	S_READ,		/* 2 */
1052     	S_DATA,		/* 3 */
1053     	S_STOP,		/* 4 */
1054     	S_STOPPING	/* 5 */
1055     };
1056     
1057     static volatile enum state_e state = S_IDLE;
1058     #if DEBUG_STATE
1059     static volatile enum state_e state_old = S_STOP;
1060     static volatile int flags_old = 0;
1061     static volatile long state_n = 0;
1062     #endif
1063     
1064     
1065     /* Used as mutex to keep do_optcd_request (and other processes calling
1066        ioctl) out while some process is inside a VFS call.
1067        Reverse is accomplished by checking if state = S_IDLE upon entry
1068        of opt_ioctl and opt_media_change. */
1069     static int in_vfs = 0;
1070     
1071     
1072     static volatile int transfer_is_active = 0;
1073     static volatile int error = 0;	/* %% do something with this?? */
1074     static int tries;		/* ibid?? */
1075     static int timeout = 0;
1076     
1077     static void poll(unsigned long data);
1078     static struct timer_list req_timer = {function: poll};
1079     
1080     
1081     static void poll(unsigned long data)
1082     {
1083     	static volatile int read_count = 1;
1084     	int flags;
1085     	int loop_again = 1;
1086     	int status = 0;
1087     	int skip = 0;
1088     
1089     	if (error) {
1090     		printk(KERN_ERR "optcd: I/O error 0x%02x\n", error);
1091     		opt_invalidate_buffers();
1092     		if (!tries--) {
1093     			printk(KERN_ERR "optcd: read block %d failed;"
1094     				" Giving up\n", next_bn);
1095     			if (transfer_is_active)
1096     				loop_again = 0;
1097     			if (CURRENT_VALID)
1098     				end_request(0);
1099     			tries = 5;
1100     		}
1101     		error = 0;
1102     		state = S_STOP;
1103     	}
1104     
1105     	while (loop_again)
1106     	{
1107     		loop_again = 0; /* each case must flip this back to 1 if we want
1108     		                 to come back up here */
1109     
1110     #if DEBUG_STATE
1111     		if (state == state_old)
1112     			state_n++;
1113     		else {
1114     			state_old = state;
1115     			if (++state_n > 1)
1116     				printk(KERN_DEBUG "optcd: %ld times "
1117     					"in previous state\n", state_n);
1118     			printk(KERN_DEBUG "optcd: state %d\n", state);
1119     			state_n = 0;
1120     		}
1121     #endif
1122     
1123     		switch (state) {
1124     		case S_IDLE:
1125     			return;
1126     		case S_START:
1127     			if (in_vfs)
1128     				break;
1129     			if (send_cmd(COMDRVST)) {
1130     				state = S_IDLE;
1131     				while (CURRENT_VALID)
1132     					end_request(0);
1133     				return;
1134     			}
1135     			state = S_READ;
1136     			timeout = READ_TIMEOUT;
1137     			break;
1138     		case S_READ: {
1139     			struct cdrom_msf msf;
1140     			if (!skip) {
1141     				status = fetch_status();
1142     				if (status < 0)
1143     					break;
1144     				if (status & ST_DSK_CHG) {
1145     					toc_uptodate = 0;
1146     					opt_invalidate_buffers();
1147     				}
1148     			}
1149     			skip = 0;
1150     			if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1151     				toc_uptodate = 0;
1152     				opt_invalidate_buffers();
1153     				printk(KERN_WARNING "optcd: %s\n",
1154     					(status & ST_DOOR_OPEN)
1155     					? "door open"
1156     					: "disk removed");
1157     				state = S_IDLE;
1158     				while (CURRENT_VALID)
1159     					end_request(0);
1160     				return;
1161     			}
1162     			if (!CURRENT_VALID) {
1163     				state = S_STOP;
1164     				loop_again = 1;
1165     				break;
1166     			}
1167     			next_bn = CURRENT -> sector / 4;
1168     			lba2msf(next_bn, &msf);
1169     			read_count = N_BUFS;
1170     			msf.cdmsf_frame1 = read_count; /* Not BCD! */
1171     
1172     			DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x",
1173     				msf.cdmsf_min0,
1174     				msf.cdmsf_sec0,
1175     				msf.cdmsf_frame0,
1176     				msf.cdmsf_min1,
1177     				msf.cdmsf_sec1,
1178     				msf.cdmsf_frame1));
1179     			DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d"
1180     				" buf_out:%d buf_bn:%d",
1181     				next_bn,
1182     				buf_in,
1183     				buf_out,
1184     				buf_bn[buf_in]));
1185     
1186     			exec_read_cmd(COMREAD, &msf);
1187     			state = S_DATA;
1188     			timeout = READ_TIMEOUT;
1189     			break;
1190     		}
1191     		case S_DATA:
1192     			flags = stdt_flags() & (FL_STEN|FL_DTEN);
1193     
1194     #if DEBUG_STATE
1195     			if (flags != flags_old) {
1196     				flags_old = flags;
1197     				printk(KERN_DEBUG "optcd: flags:%x\n", flags);
1198     			}
1199     			if (flags == FL_STEN)
1200     				printk(KERN_DEBUG "timeout cnt: %d\n", timeout);
1201     #endif
1202     
1203     			switch (flags) {
1204     			case FL_DTEN:		/* only STEN low */
1205     				if (!tries--) {
1206     					printk(KERN_ERR
1207     						"optcd: read block %d failed; "
1208     						"Giving up\n", next_bn);
1209     					if (transfer_is_active) {
1210     						tries = 0;
1211     						break;
1212     					}
1213     					if (CURRENT_VALID)
1214     						end_request(0);
1215     					tries = 5;
1216     				}
1217     				state = S_START;
1218     				timeout = READ_TIMEOUT;
1219     				loop_again = 1;
1220     			case (FL_STEN|FL_DTEN):	 /* both high */
1221     				break;
1222     			default:	/* DTEN low */
1223     				tries = 5;
1224     				if (!CURRENT_VALID && buf_in == buf_out) {
1225     					state = S_STOP;
1226     					loop_again = 1;
1227     					break;
1228     				}
1229     				if (read_count<=0)
1230     					printk(KERN_WARNING
1231     						"optcd: warning - try to read"
1232     						" 0 frames\n");
1233     				while (read_count) {
1234     					buf_bn[buf_in] = NOBUF;
1235     					if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) {
1236     					/* should be no waiting here!?? */
1237     						printk(KERN_ERR
1238     						   "read_count:%d "
1239     						   "CURRENT->nr_sectors:%ld "
1240     						   "buf_in:%d\n",
1241     							read_count,
1242     							CURRENT->nr_sectors,
1243     							buf_in);
1244     						printk(KERN_ERR
1245     							"transfer active: %x\n",
1246     							transfer_is_active);
1247     						read_count = 0;
1248     						state = S_STOP;
1249     						loop_again = 1;
1250     						end_request(0);
1251     						break;
1252     					}
1253     					fetch_data(buf+
1254     					    CD_FRAMESIZE*buf_in,
1255     					    CD_FRAMESIZE);
1256     					read_count--;
1257     
1258     					DEBUG((DEBUG_REQUEST,
1259     						"S_DATA; ---I've read data- "
1260     						"read_count: %d",
1261     						read_count));
1262     					DEBUG((DEBUG_REQUEST,
1263     						"next_bn:%d  buf_in:%d "
1264     						"buf_out:%d  buf_bn:%d",
1265     						next_bn,
1266     						buf_in,
1267     						buf_out,
1268     						buf_bn[buf_in]));
1269     
1270     					buf_bn[buf_in] = next_bn++;
1271     					if (buf_out == NOBUF)
1272     						buf_out = buf_in;
1273     					buf_in = buf_in + 1 ==
1274     						N_BUFS ? 0 : buf_in + 1;
1275     				}
1276     				if (!transfer_is_active) {
1277     					while (CURRENT_VALID) {
1278     						transfer();
1279     						if (CURRENT -> nr_sectors == 0)
1280     							end_request(1);
1281     						else
1282     							break;
1283     					}
1284     				}
1285     
1286     				if (CURRENT_VALID
1287     				    && (CURRENT -> sector / 4 < next_bn ||
1288     				    CURRENT -> sector / 4 >
1289     				     next_bn + N_BUFS)) {
1290     					state = S_STOP;
1291     					loop_again = 1;
1292     					break;
1293     				}
1294     				timeout = READ_TIMEOUT;
1295     				if (read_count == 0) {
1296     					state = S_STOP;
1297     					loop_again = 1;
1298     					break;
1299     				}
1300     			}
1301     			break;
1302     		case S_STOP:
1303     			if (read_count != 0)
1304     				printk(KERN_ERR
1305     					"optcd: discard data=%x frames\n",
1306     					read_count);
1307     			flush_data();
1308     			if (send_cmd(COMDRVST)) {
1309     				state = S_IDLE;
1310     				while (CURRENT_VALID)
1311     					end_request(0);
1312     				return;
1313     			}
1314     			state = S_STOPPING;
1315     			timeout = STOP_TIMEOUT;
1316     			break;
1317     		case S_STOPPING:
1318     			status = fetch_status();
1319     			if (status < 0 && timeout)
1320     					break;
1321     			if ((status >= 0) && (status & ST_DSK_CHG)) {
1322     				toc_uptodate = 0;
1323     				opt_invalidate_buffers();
1324     			}
1325     			if (CURRENT_VALID) {
1326     				if (status >= 0) {
1327     					state = S_READ;
1328     					loop_again = 1;
1329     					skip = 1;
1330     					break;
1331     				} else {
1332     					state = S_START;
1333     					timeout = 1;
1334     				}
1335     			} else {
1336     				state = S_IDLE;
1337     				return;
1338     			}
1339     			break;
1340     		default:
1341     			printk(KERN_ERR "optcd: invalid state %d\n", state);
1342     			return;
1343     		} /* case */
1344     	} /* while */
1345     
1346     	if (!timeout--) {
1347     		printk(KERN_ERR "optcd: timeout in state %d\n", state);
1348     		state = S_STOP;
1349     		if (exec_cmd(COMSTOP) < 0) {
1350     			state = S_IDLE;
1351     			while (CURRENT_VALID)
1352     				end_request(0);
1353     			return;
1354     		}
1355     	}
1356     
1357     	mod_timer(&req_timer, jiffies + HZ/100);
1358     }
1359     
1360     
1361     static void do_optcd_request(request_queue_t * q)
1362     {
1363     	DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)",
1364     	       CURRENT -> sector, CURRENT -> nr_sectors));
1365     
1366     	if (disk_info.audio) {
1367     		printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
1368     		end_request(0);
1369     		return;
1370     	}
1371     
1372     	transfer_is_active = 1;
1373     	while (CURRENT_VALID) {
1374     		if (CURRENT->bh) {
1375     			if (!buffer_locked(CURRENT->bh))
1376     				panic(DEVICE_NAME ": block not locked");
1377     		}
1378     		transfer();	/* First try to transfer block from buffers */
1379     		if (CURRENT -> nr_sectors == 0) {
1380     			end_request(1);
1381     		} else {	/* Want to read a block not in buffer */
1382     			buf_out = NOBUF;
1383     			if (state == S_IDLE) {
1384     				/* %% Should this block the request queue?? */
1385     				if (update_toc() < 0) {
1386     					while (CURRENT_VALID)
1387     						end_request(0);
1388     					break;
1389     				}
1390     				/* Start state machine */
1391     				state = S_START;
1392     				timeout = READ_TIMEOUT;
1393     				tries = 5;
1394     				/* %% why not start right away?? */
1395     				mod_timer(&req_timer, jiffies + HZ/100);
1396     			}
1397     			break;
1398     		}
1399     	}
1400     	transfer_is_active = 0;
1401     
1402     	DEBUG((DEBUG_REQUEST, "next_bn:%d  buf_in:%d buf_out:%d  buf_bn:%d",
1403     	       next_bn, buf_in, buf_out, buf_bn[buf_in]));
1404     	DEBUG((DEBUG_REQUEST, "do_optcd_request ends"));
1405     }
1406     
1407     /* IOCTLs */
1408     
1409     
1410     static char auto_eject = 0;
1411     
1412     static int cdrompause(void)
1413     {
1414     	int status;
1415     
1416     	if (audio_status != CDROM_AUDIO_PLAY)
1417     		return -EINVAL;
1418     
1419     	status = exec_cmd(COMPAUSEON);
1420     	if (status < 0) {
1421     		DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status));
1422     		return -EIO;
1423     	}
1424     	audio_status = CDROM_AUDIO_PAUSED;
1425     	return 0;
1426     }
1427     
1428     
1429     static int cdromresume(void)
1430     {
1431     	int status;
1432     
1433     	if (audio_status != CDROM_AUDIO_PAUSED)
1434     		return -EINVAL;
1435     
1436     	status = exec_cmd(COMPAUSEOFF);
1437     	if (status < 0) {
1438     		DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status));
1439     		audio_status = CDROM_AUDIO_ERROR;
1440     		return -EIO;
1441     	}
1442     	audio_status = CDROM_AUDIO_PLAY;
1443     	return 0;
1444     }
1445     
1446     
1447     static int cdromplaymsf(unsigned long arg)
1448     {
1449     	int status;
1450     	struct cdrom_msf msf;
1451     
1452     	status = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
1453     	if (status)
1454     		return status;
1455     	copy_from_user(&msf, (void *) arg, sizeof msf);
1456     
1457     	bin2bcd(&msf);
1458     	status = exec_long_cmd(COMPLAY, &msf);
1459     	if (status < 0) {
1460     		DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1461     		audio_status = CDROM_AUDIO_ERROR;
1462     		return -EIO;
1463     	}
1464     
1465     	audio_status = CDROM_AUDIO_PLAY;
1466     	return 0;
1467     }
1468     
1469     
1470     static int cdromplaytrkind(unsigned long arg)
1471     {
1472     	int status;
1473     	struct cdrom_ti ti;
1474     	struct cdrom_msf msf;
1475     
1476     	status = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
1477     	if (status)
1478     		return status;
1479     	copy_from_user(&ti, (void *) arg, sizeof ti);
1480     
1481     	if (ti.cdti_trk0 < disk_info.first
1482     	    || ti.cdti_trk0 > disk_info.last
1483     	    || ti.cdti_trk1 < ti.cdti_trk0)
1484     		return -EINVAL;
1485     	if (ti.cdti_trk1 > disk_info.last)
1486     		ti.cdti_trk1 = disk_info.last;
1487     
1488     	msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute;
1489     	msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second;
1490     	msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame;
1491     	msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute;
1492     	msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second;
1493     	msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame;
1494     
1495     	DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d",
1496     		msf.cdmsf_min0,
1497     		msf.cdmsf_sec0,
1498     		msf.cdmsf_frame0,
1499     		msf.cdmsf_min1,
1500     		msf.cdmsf_sec1,
1501     		msf.cdmsf_frame1));
1502     
1503     	bin2bcd(&msf);
1504     	status = exec_long_cmd(COMPLAY, &msf);
1505     	if (status < 0) {
1506     		DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1507     		audio_status = CDROM_AUDIO_ERROR;
1508     		return -EIO;
1509     	}
1510     
1511     	audio_status = CDROM_AUDIO_PLAY;
1512     	return 0;
1513     }
1514     
1515     
1516     static int cdromreadtochdr(unsigned long arg)
1517     {
1518     	int status;
1519     	struct cdrom_tochdr tochdr;
1520     
1521     	status = verify_area(VERIFY_WRITE, (void *) arg, sizeof tochdr);
1522     	if (status)
1523     		return status;
1524     
1525     	tochdr.cdth_trk0 = disk_info.first;
1526     	tochdr.cdth_trk1 = disk_info.last;
1527     
1528     	copy_to_user((void *) arg, &tochdr, sizeof tochdr);
1529     	return 0;
1530     }
1531     
1532     
1533     static int cdromreadtocentry(unsigned long arg)
1534     {
1535     	int status;
1536     	struct cdrom_tocentry entry;
1537     	struct cdrom_subchnl *tocptr;
1538     
1539     	status = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
1540     	if (status)
1541     		return status;
1542     	copy_from_user(&entry, (void *) arg, sizeof entry);
1543     
1544     	if (entry.cdte_track == CDROM_LEADOUT)
1545     		tocptr = &toc[disk_info.last + 1];
1546     	else if (entry.cdte_track > disk_info.last
1547     		|| entry.cdte_track < disk_info.first)
1548     		return -EINVAL;
1549     	else
1550     		tocptr = &toc[entry.cdte_track];
1551     
1552     	entry.cdte_adr = tocptr->cdsc_adr;
1553     	entry.cdte_ctrl = tocptr->cdsc_ctrl;
1554     	entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute;
1555     	entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second;
1556     	entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame;
1557     	/* %% What should go into entry.cdte_datamode? */
1558     
1559     	if (entry.cdte_format == CDROM_LBA)
1560     		msf2lba(&entry.cdte_addr);
1561     	else if (entry.cdte_format != CDROM_MSF)
1562     		return -EINVAL;
1563     
1564     	copy_to_user((void *) arg, &entry, sizeof entry);
1565     	return 0;
1566     }
1567     
1568     
1569     static int cdromvolctrl(unsigned long arg)
1570     {
1571     	int status;
1572     	struct cdrom_volctrl volctrl;
1573     	struct cdrom_msf msf;
1574     
1575     	status = verify_area(VERIFY_READ, (void *) arg, sizeof volctrl);
1576     	if (status)
1577     		return status;
1578     	copy_from_user(&volctrl, (char *) arg, sizeof volctrl);
1579     
1580     	msf.cdmsf_min0 = 0x10;
1581     	msf.cdmsf_sec0 = 0x32;
1582     	msf.cdmsf_frame0 = volctrl.channel0;
1583     	msf.cdmsf_min1 = volctrl.channel1;
1584     	msf.cdmsf_sec1 = volctrl.channel2;
1585     	msf.cdmsf_frame1 = volctrl.channel3;
1586     
1587     	status = exec_long_cmd(COMCHCTRL, &msf);
1588     	if (status < 0) {
1589     		DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status));
1590     		return -EIO;
1591     	}
1592     	return 0;
1593     }
1594     
1595     
1596     static int cdromsubchnl(unsigned long arg)
1597     {
1598     	int status;
1599     	struct cdrom_subchnl subchnl;
1600     
1601     	status = verify_area(VERIFY_WRITE, (void *) arg, sizeof subchnl);
1602     	if (status)
1603     		return status;
1604     	copy_from_user(&subchnl, (void *) arg, sizeof subchnl);
1605     
1606     	if (subchnl.cdsc_format != CDROM_LBA
1607     	    && subchnl.cdsc_format != CDROM_MSF)
1608     		return -EINVAL;
1609     
1610     	status = get_q_channel(&subchnl);
1611     	if (status < 0) {
1612     		DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status));
1613     		return -EIO;
1614     	}
1615     
1616     	copy_to_user((void *) arg, &subchnl, sizeof subchnl);
1617     	return 0;
1618     }
1619     
1620     
1621     static int cdromread(unsigned long arg, int blocksize, int cmd)
1622     {
1623     	int status;
1624     	struct cdrom_msf msf;
1625     	char buf[CD_FRAMESIZE_RAWER];
1626     
1627     	status = verify_area(VERIFY_WRITE, (void *) arg, blocksize);
1628     	if (status)
1629     		return status;
1630     	copy_from_user(&msf, (void *) arg, sizeof msf);
1631     
1632     	bin2bcd(&msf);
1633     	msf.cdmsf_min1 = 0;
1634     	msf.cdmsf_sec1 = 0;
1635     	msf.cdmsf_frame1 = 1;	/* read only one frame */
1636     	status = exec_read_cmd(cmd, &msf);
1637     
1638     	DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
1639     
1640     	if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
1641     		return -EIO;
1642     	fetch_data(buf, blocksize);
1643     
1644     	copy_to_user((void *) arg, &buf, blocksize);
1645     	return 0;
1646     }
1647     
1648     
1649     static int cdromseek(unsigned long arg)
1650     {
1651     	int status;
1652     	struct cdrom_msf msf;
1653     
1654     	status = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
1655     	if (status)
1656     		return status;
1657     	copy_from_user(&msf, (void *) arg, sizeof msf);
1658     
1659     	bin2bcd(&msf);
1660     	status = exec_seek_cmd(COMSEEK, &msf);
1661     
1662     	DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status));
1663     
1664     	if (status < 0)
1665     		return -EIO;
1666     	return 0;
1667     }
1668     
1669     
1670     #ifdef MULTISESSION
1671     static int cdrommultisession(unsigned long arg)
1672     {
1673     	int status;
1674     	struct cdrom_multisession ms;
1675     
1676     	status = verify_area(VERIFY_WRITE, (void*) arg, sizeof ms);
1677     	if (status)
1678     		return status;
1679     	copy_from_user(&ms, (void*) arg, sizeof ms);
1680     
1681     	ms.addr.msf.minute = disk_info.last_session.minute;
1682     	ms.addr.msf.second = disk_info.last_session.second;
1683     	ms.addr.msf.frame = disk_info.last_session.frame;
1684     
1685     	if (ms.addr_format != CDROM_LBA
1686     	   && ms.addr_format != CDROM_MSF)
1687     		return -EINVAL;
1688     	if (ms.addr_format == CDROM_LBA)
1689     		msf2lba(&ms.addr);
1690     
1691     	ms.xa_flag = disk_info.xa;
1692     
1693       	copy_to_user((void*) arg, &ms,
1694     		sizeof(struct cdrom_multisession));
1695     
1696     #if DEBUG_MULTIS
1697      	if (ms.addr_format == CDROM_MSF)
1698                    	printk(KERN_DEBUG
1699     			"optcd: multisession xa:%d, msf:%02d:%02d.%02d\n",
1700     			ms.xa_flag,
1701     			ms.addr.msf.minute,
1702     			ms.addr.msf.second,
1703     			ms.addr.msf.frame);
1704     	else
1705     		printk(KERN_DEBUG
1706     		    "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n",
1707     			ms.xa_flag,
1708     			ms.addr.lba,
1709     			disk_info.last_session.minute,
1710     			disk_info.last_session.second,
1711     			disk_info.last_session.frame);
1712     #endif /* DEBUG_MULTIS */
1713     
1714     	return 0;
1715     }
1716     #endif /* MULTISESSION */
1717     
1718     
1719     static int cdromreset(void)
1720     {
1721     	if (state != S_IDLE) {
1722     		error = 1;
1723     		tries = 0;
1724     	}
1725     
1726     	toc_uptodate = 0;
1727     	disk_changed = 1;
1728     	opt_invalidate_buffers();
1729     	audio_status = CDROM_AUDIO_NO_STATUS;
1730     
1731     	if (!reset_drive())
1732     		return -EIO;
1733     	return 0;
1734     }
1735     
1736     /* VFS calls */
1737     
1738     
1739     static int opt_ioctl(struct inode *ip, struct file *fp,
1740                          unsigned int cmd, unsigned long arg)
1741     {
1742     	int status, err, retval = 0;
1743     
1744     	DEBUG((DEBUG_VFS, "starting opt_ioctl"));
1745     
1746     	if (!ip)
1747     		return -EINVAL;
1748     
1749     	if (cmd == CDROMRESET)
1750     		return cdromreset();
1751     
1752     	/* is do_optcd_request or another ioctl busy? */
1753     	if (state != S_IDLE || in_vfs)
1754     		return -EBUSY;
1755     
1756     	in_vfs = 1;
1757     
1758     	status = drive_status();
1759     	if (status < 0) {
1760     		DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1761     		in_vfs = 0;
1762     		return -EIO;
1763     	}
1764     
1765     	if (status & ST_DOOR_OPEN)
1766     		switch (cmd) {	/* Actions that can be taken with door open */
1767     		case CDROMCLOSETRAY:
1768     			/* We do this before trying to read the toc. */
1769     			err = exec_cmd(COMCLOSE);
1770     			if (err < 0) {
1771     				DEBUG((DEBUG_VFS,
1772     				       "exec_cmd COMCLOSE: %02x", -err));
1773     				in_vfs = 0;
1774     				return -EIO;
1775     			}
1776     			break;
1777     		default:	in_vfs = 0;
1778     				return -EBUSY;
1779     		}
1780     
1781     	err = update_toc();
1782     	if (err < 0) {
1783     		DEBUG((DEBUG_VFS, "update_toc: %02x", -err));
1784     		in_vfs = 0;
1785     		return -EIO;
1786     	}
1787     
1788     	DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd));
1789     
1790     	switch (cmd) {
1791     	case CDROMPAUSE:	retval = cdrompause(); break;
1792     	case CDROMRESUME:	retval = cdromresume(); break;
1793     	case CDROMPLAYMSF:	retval = cdromplaymsf(arg); break;
1794     	case CDROMPLAYTRKIND:	retval = cdromplaytrkind(arg); break;
1795     	case CDROMREADTOCHDR:	retval = cdromreadtochdr(arg); break;
1796     	case CDROMREADTOCENTRY:	retval = cdromreadtocentry(arg); break;
1797     
1798     	case CDROMSTOP:		err = exec_cmd(COMSTOP);
1799     				if (err < 0) {
1800     					DEBUG((DEBUG_VFS,
1801     						"exec_cmd COMSTOP: %02x",
1802     						-err));
1803     					retval = -EIO;
1804     				} else
1805     					audio_status = CDROM_AUDIO_NO_STATUS;
1806     				break;
1807     	case CDROMSTART:	break;	/* This is a no-op */
1808     	case CDROMEJECT:	err = exec_cmd(COMUNLOCK);
1809     				if (err < 0) {
1810     					DEBUG((DEBUG_VFS,
1811     						"exec_cmd COMUNLOCK: %02x",
1812     						-err));
1813     					retval = -EIO;
1814     					break;
1815     				}
1816     				err = exec_cmd(COMOPEN);
1817     				if (err < 0) {
1818     					DEBUG((DEBUG_VFS,
1819     						"exec_cmd COMOPEN: %02x",
1820     						-err));
1821     					retval = -EIO;
1822     				}
1823     				break;
1824     
1825     	case CDROMVOLCTRL:	retval = cdromvolctrl(arg); break;
1826     	case CDROMSUBCHNL:	retval = cdromsubchnl(arg); break;
1827     
1828     	/* The drive detects the mode and automatically delivers the
1829     	   correct 2048 bytes, so we don't need these IOCTLs */
1830     	case CDROMREADMODE2:	retval = -EINVAL; break;
1831     	case CDROMREADMODE1:	retval = -EINVAL; break;
1832     
1833     	/* Drive doesn't support reading audio */
1834     	case CDROMREADAUDIO:	retval = -EINVAL; break;
1835     
1836     	case CDROMEJECT_SW:	auto_eject = (char) arg;
1837     				break;
1838     
1839     #ifdef MULTISESSION
1840     	case CDROMMULTISESSION:	retval = cdrommultisession(arg); break;
1841     #endif
1842     
1843     	case CDROM_GET_MCN:	retval = -EINVAL; break; /* not implemented */
1844     	case CDROMVOLREAD:	retval = -EINVAL; break; /* not implemented */
1845     
1846     	case CDROMREADRAW:
1847     			/* this drive delivers 2340 bytes in raw mode */
1848     			retval = cdromread(arg, CD_FRAMESIZE_RAW1, COMREADRAW);
1849     			break;
1850     	case CDROMREADCOOKED:
1851     			retval = cdromread(arg, CD_FRAMESIZE, COMREAD);
1852     			break;
1853     	case CDROMREADALL:
1854     			retval = cdromread(arg, CD_FRAMESIZE_RAWER, COMREADALL);
1855     			break;
1856     
1857     	case CDROMSEEK:		retval = cdromseek(arg); break;
1858     	case CDROMPLAYBLK:	retval = -EINVAL; break; /* not implemented */
1859     	case CDROMCLOSETRAY:	break;	/* The action was taken earlier */
1860     	default:		retval = -EINVAL;
1861     	}
1862     	in_vfs = 0;
1863     	return retval;
1864     }
1865     
1866     
1867     static int open_count = 0;
1868     
1869     /* Open device special file; check that a disk is in. */
1870     static int opt_open(struct inode *ip, struct file *fp)
1871     {
1872     	DEBUG((DEBUG_VFS, "starting opt_open"));
1873     
1874     	MOD_INC_USE_COUNT;
1875     
1876     	if (!open_count && state == S_IDLE) {
1877     		int status;
1878     
1879     		toc_uptodate = 0;
1880     		opt_invalidate_buffers();
1881     
1882     		status = exec_cmd(COMCLOSE);	/* close door */
1883     		if (status < 0) {
1884     			DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status));
1885     		}
1886     
1887     		status = drive_status();
1888     		if (status < 0) {
1889     			DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1890     			goto err_out;
1891     		}
1892     		DEBUG((DEBUG_VFS, "status: %02x", status));
1893     		if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1894     			printk(KERN_INFO "optcd: no disk or door open\n");
1895     			goto err_out;
1896     		}
1897     		status = exec_cmd(COMLOCK);		/* Lock door */
1898     		if (status < 0) {
1899     			DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status));
1900     		}
1901     		status = update_toc();	/* Read table of contents */
1902     		if (status < 0)	{
1903     			DEBUG((DEBUG_VFS, "update_toc: %02x", -status));
1904     	 		status = exec_cmd(COMUNLOCK);	/* Unlock door */
1905     			if (status < 0) {
1906     				DEBUG((DEBUG_VFS,
1907     				       "exec_cmd COMUNLOCK: %02x", -status));
1908     			}
1909     			goto err_out;
1910     		}
1911     		open_count++;
1912     	}
1913     
1914     	DEBUG((DEBUG_VFS, "exiting opt_open"));
1915     
1916     	return 0;
1917     
1918     err_out:
1919         MOD_DEC_USE_COUNT;
1920     	return -EIO;
1921     }
1922     
1923     
1924     /* Release device special file; flush all blocks from the buffer cache */
1925     static int opt_release(struct inode *ip, struct file *fp)
1926     {
1927     	int status;
1928     
1929     	DEBUG((DEBUG_VFS, "executing opt_release"));
1930     	DEBUG((DEBUG_VFS, "inode: %p, inode -> i_rdev: 0x%x, file: %p\n",
1931     		ip, ip -> i_rdev, fp));
1932     
1933     	if (!--open_count) {
1934     		toc_uptodate = 0;
1935     		opt_invalidate_buffers();
1936     	 	status = exec_cmd(COMUNLOCK);	/* Unlock door */
1937     		if (status < 0) {
1938     			DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status));
1939     		}
1940     		if (auto_eject) {
1941     			status = exec_cmd(COMOPEN);
1942     			DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
1943     		}
1944     		del_timer(&delay_timer);
1945     		del_timer(&req_timer);
1946     	}
1947     	MOD_DEC_USE_COUNT;
1948     	return 0;
1949     }
1950     
1951     
1952     /* Check if disk has been changed */
1953     static int opt_media_change(kdev_t dev)
1954     {
1955     	DEBUG((DEBUG_VFS, "executing opt_media_change"));
1956     	DEBUG((DEBUG_VFS, "dev: 0x%x; disk_changed = %d\n", dev, disk_changed));
1957     
1958     	if (disk_changed) {
1959     		disk_changed = 0;
1960     		return 1;
1961     	}
1962     	return 0;
1963     }
1964     
1965     /* Driver initialisation */
1966     
1967     
1968     /* Returns 1 if a drive is detected with a version string
1969        starting with "DOLPHIN". Otherwise 0. */
1970     static int __init version_ok(void)
1971     {
1972     	char devname[100];
1973     	int count, i, ch, status;
1974     
1975     	status = exec_cmd(COMVERSION);
1976     	if (status < 0) {
1977     		DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status));
1978     		return 0;
1979     	}
1980     	if ((count = get_data(1)) < 0) {
1981     		DEBUG((DEBUG_VFS, "get_data(1): %02x", -count));
1982     		return 0;
1983     	}
1984     	for (i = 0, ch = -1; count > 0; count--) {
1985     		if ((ch = get_data(1)) < 0) {
1986     			DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch));
1987     			break;
1988     		}
1989     		if (i < 99)
1990     			devname[i++] = ch;
1991     	}
1992     	devname[i] = '\0';
1993     	if (ch < 0)
1994     		return 0;
1995     
1996     	printk(KERN_INFO "optcd: Device %s detected\n", devname);
1997     	return ((devname[0] == 'D')
1998     	     && (devname[1] == 'O')
1999     	     && (devname[2] == 'L')
2000     	     && (devname[3] == 'P')
2001     	     && (devname[4] == 'H')
2002     	     && (devname[5] == 'I')
2003     	     && (devname[6] == 'N'));
2004     }
2005     
2006     
2007     static struct block_device_operations opt_fops = {
2008     	open:			opt_open,
2009     	release:		opt_release,
2010     	ioctl:			opt_ioctl,
2011     	check_media_change:	opt_media_change,
2012     };
2013     
2014     #ifndef MODULE
2015     /* Get kernel parameter when used as a kernel driver */
2016     static int optcd_setup(char *str)
2017     {
2018     	int ints[4];
2019     	(void)get_options(str, ARRAY_SIZE(ints), ints);
2020     	
2021     	if (ints[0] > 0)
2022     		optcd_port = ints[1];
2023     
2024      	return 1;
2025     }
2026     
2027     __setup("optcd=", optcd_setup);
2028     
2029     #endif /* MODULE */
2030     
2031     /* Test for presence of drive and initialize it. Called at boot time
2032        or during module initialisation. */
2033     int __init optcd_init(void)
2034     {
2035     	int status;
2036     
2037     	if (optcd_port <= 0) {
2038     		printk(KERN_INFO
2039     			"optcd: no Optics Storage CDROM Initialization\n");
2040     		return -EIO;
2041     	}
2042     	if (check_region(optcd_port, 4)) {
2043     		printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
2044     			optcd_port);
2045     		return -EIO;
2046     	}
2047     
2048     	if (!reset_drive()) {
2049     		printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
2050     		return -EIO;
2051     	}
2052     	if (!version_ok()) {
2053     		printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
2054     		return -EIO;
2055     	}
2056     	status = exec_cmd(COMINITDOUBLE);
2057     	if (status < 0) {
2058     		printk(KERN_ERR "optcd: cannot init double speed mode\n");
2059     		DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
2060     		return -EIO;
2061     	}
2062     	if (devfs_register_blkdev(MAJOR_NR, "optcd", &opt_fops) != 0)
2063     	{
2064     		printk(KERN_ERR "optcd: unable to get major %d\n", MAJOR_NR);
2065     		return -EIO;
2066     	}
2067     	devfs_register (NULL, "optcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
2068     			S_IFBLK | S_IRUGO | S_IWUGO, &opt_fops, NULL);
2069     	hardsect_size[MAJOR_NR] = &hsecsize;
2070     	blksize_size[MAJOR_NR] = &blksize;
2071     	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
2072     	read_ahead[MAJOR_NR] = 4;
2073     	request_region(optcd_port, 4, "optcd");
2074     	register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &opt_fops, 0);
2075     
2076     	printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
2077     	return 0;
2078     }
2079     
2080     
2081     void __exit optcd_exit(void)
2082     {
2083     	devfs_unregister(devfs_find_handle(NULL, "optcd", 0, 0,
2084     					   DEVFS_SPECIAL_BLK, 0));
2085     	if (devfs_unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
2086     		printk(KERN_ERR "optcd: what's that: can't unregister\n");
2087     		return;
2088     	}
2089     	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
2090     	release_region(optcd_port, 4);
2091     	printk(KERN_INFO "optcd: module released.\n");
2092     }
2093     
2094     #ifdef MODULE
2095     module_init(optcd_init);
2096     #endif
2097     module_exit(optcd_exit);
2098     
2099     
2100     MODULE_LICENSE("GPL");
2101