1 /*
2  * Sony CDU-535 interface device driver
3  *
4  * This is a modified version of the CDU-31A device driver (see below).
5  * Changes were made using documentation for the CDU-531 (which Sony
6  * assures me is very similar to the 535) and partial disassembly of the
7  * DOS driver.  I used Minyard's driver and replaced the CDU-31A
8  * commands with the CDU-531 commands.  This was complicated by a different
9  * interface protocol with the drive.  The driver is still polled.
10  *
11  * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
12  * I tried polling without the sony_sleep during the data transfers but
13  * it did not speed things up any.
14  *
15  * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
16  * with CDU-31A driver.  This is the also the number from the Linux
17  * Device Driver Registry for the Sony Drive.  Hope nobody else is using it.
18  *
19  * 1993-08-29 (rgj) remove the configuring of the interface board address
20  * from the top level configuration, you have to modify it in this file.
21  *
22  * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
23  *
24  * 1995-05-20
25  *  Modified to support CDU-510/515 series
26  *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
27  *  Fixed to report verify_area() failures
28  *      (Heiko Eissfeldt <heiko@colossus.escape.de>)
29  *
30  * 1995-06-01
31  *  More changes to support CDU-510/515 series
32  *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
33  *
34  * November 1999 -- Make kernel-parameter implementation work with 2.3.x
35  *	            Removed init_module & cleanup_module in favor of
36  *	            module_init & module_exit.
37  *                  Torben Mathiasen <tmm@image.dk>
38  *
39  * Things to do:
40  *  - handle errors and status better, put everything into a single word
41  *  - use interrupts (code mostly there, but a big hole still missing)
42  *  - handle multi-session CDs?
43  *  - use DMA?
44  *
45  *  Known Bugs:
46  *  -
47  *
48  *   Ken Pizzini (ken@halcyon.com)
49  *
50  * Original by:
51  *   Ron Jeppesen (ronj.an@site007.saic.com)
52  *
53  *
54  *------------------------------------------------------------------------
55  * Sony CDROM interface device driver.
56  *
57  * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above)
58  *
59  * Colossians 3:17
60  *
61  * The Sony interface device driver handles Sony interface CDROM
62  * drives and provides a complete block-level interface as well as an
63  * ioctl() interface compatible with the Sun (as specified in
64  * include/linux/cdrom.h).  With this interface, CDROMs can be
65  * accessed and standard audio CDs can be played back normally.
66  *
67  * This interface is (unfortunately) a polled interface.  This is
68  * because most Sony interfaces are set up with DMA and interrupts
69  * disables.  Some (like mine) do not even have the capability to
70  * handle interrupts or DMA.  For this reason you will see a bit of
71  * the following:
72  *
73  *   snap = jiffies;
74  *   while (jiffies-snap < SONY_JIFFIES_TIMEOUT)
75  *   {
76  *		if (some_condition())
77  *         break;
78  *      sony_sleep();
79  *   }
80  *   if (some_condition not met)
81  *   {
82  *      return an_error;
83  *   }
84  *
85  * This ugly hack waits for something to happen, sleeping a little
86  * between every try.  (The conditional is written so that jiffies
87  * wrap-around is handled properly.)
88  *
89  * One thing about these drives: They talk in MSF (Minute Second Frame) format.
90  * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
91  * disk.  The funny thing is that these are sent to the drive in BCD, but the
92  * interface wants to see them in decimal.  A lot of conversion goes on.
93  *
94  *  Copyright (C) 1993  Corey Minyard
95  *
96  *  This program is free software; you can redistribute it and/or modify
97  *  it under the terms of the GNU General Public License as published by
98  *  the Free Software Foundation; either version 2 of the License, or
99  *  (at your option) any later version.
100  *
101  *  This program is distributed in the hope that it will be useful,
102  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
103  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
104  *  GNU General Public License for more details.
105  *
106  *  You should have received a copy of the GNU General Public License
107  *  along with this program; if not, write to the Free Software
108  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
109  *
110  */
111 
112 
113 # include <linux/module.h>
114 
115 #include <linux/errno.h>
116 #include <linux/signal.h>
117 #include <linux/sched.h>
118 #include <linux/timer.h>
119 #include <linux/fs.h>
120 #include <linux/kernel.h>
121 #include <linux/ioport.h>
122 #include <linux/hdreg.h>
123 #include <linux/genhd.h>
124 #include <linux/mm.h>
125 #include <linux/slab.h>
126 #include <linux/init.h>
127 #include <linux/devfs_fs_kernel.h>
128 
129 #define REALLY_SLOW_IO
130 #include <asm/system.h>
131 #include <asm/io.h>
132 #include <asm/uaccess.h>
133 
134 #include <linux/cdrom.h>
135 
136 #define MAJOR_NR CDU535_CDROM_MAJOR
137 # include <linux/blk.h>
138 #define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
139 #include "sonycd535.h"
140 
141 /*
142  * this is the base address of the interface card for the Sony CDU-535
143  * CDROM drive.  If your jumpers are set for an address other than
144  * this one (the default), change the following line to the
145  * proper address.
146  */
147 #ifndef CDU535_ADDRESS
148 # define CDU535_ADDRESS			0x340
149 #endif
150 #ifndef CDU535_INTERRUPT
151 # define CDU535_INTERRUPT		0
152 #endif
153 #ifndef CDU535_HANDLE
154 # define CDU535_HANDLE			"cdu535"
155 #endif
156 #ifndef CDU535_MESSAGE_NAME
157 # define CDU535_MESSAGE_NAME	"Sony CDU-535"
158 #endif
159 
160 #define CDU535_BLOCK_SIZE	2048
161 
162 #ifndef MAX_SPINUP_RETRY
163 # define MAX_SPINUP_RETRY		3	/* 1 is sufficient for most drives... */
164 #endif
165 #ifndef RETRY_FOR_BAD_STATUS
166 # define RETRY_FOR_BAD_STATUS	100	/* in 10th of second */
167 #endif
168 
169 #ifndef DEBUG
170 # define DEBUG	1
171 #endif
172 
173 /*
174  *  SONY535_BUFFER_SIZE determines the size of internal buffer used
175  *  by the drive.  It must be at least 2K and the larger the buffer
176  *  the better the transfer rate.  It does however take system memory.
177  *  On my system I get the following transfer rates using dd to read
178  *  10 Mb off /dev/cdrom.
179  *
180  *    8K buffer      43 Kb/sec
181  *   16K buffer      66 Kb/sec
182  *   32K buffer      91 Kb/sec
183  *   64K buffer     111 Kb/sec
184  *  128K buffer     123 Kb/sec
185  *  512K buffer     123 Kb/sec
186  */
187 #define SONY535_BUFFER_SIZE	(64*1024)
188 
189 /*
190  *  if LOCK_DOORS is defined then the eject button is disabled while
191  * the device is open.
192  */
193 #ifndef NO_LOCK_DOORS
194 # define LOCK_DOORS
195 #endif
196 
197 static int read_subcode(void);
198 static void sony_get_toc(void);
199 static int cdu_open(struct inode *inode, struct file *filp);
200 static inline unsigned int int_to_bcd(unsigned int val);
201 static unsigned int bcd_to_int(unsigned int bcd);
202 static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
203 					   Byte * response, int n_response, int ignoreStatusBit7);
204 
205 /* The base I/O address of the Sony Interface.  This is a variable (not a
206    #define) so it can be easily changed via some future ioctl() */
207 static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
208 MODULE_PARM(sony535_cd_base_io, "i");
209 
210 /*
211  * The following are I/O addresses of the various registers for the drive.  The
212  * comment for the base address also applies here.
213  */
214 static unsigned short select_unit_reg;
215 static unsigned short result_reg;
216 static unsigned short command_reg;
217 static unsigned short read_status_reg;
218 static unsigned short data_reg;
219 
220 static int initialized;			/* Has the drive been initialized? */
221 static int sony_disc_changed = 1;	/* Has the disk been changed
222 					   since the last check? */
223 static int sony_toc_read;		/* Has the table of contents been
224 					   read? */
225 static unsigned int sony_buffer_size;	/* Size in bytes of the read-ahead
226 					   buffer. */
227 static unsigned int sony_buffer_sectors;	/* Size (in 2048 byte records) of
228 						   the read-ahead buffer. */
229 static unsigned int sony_usage;		/* How many processes have the
230 					   drive open. */
231 
232 static int sony_first_block = -1;	/* First OS block (512 byte) in
233 					   the read-ahead buffer */
234 static int sony_last_block = -1;	/* Last OS block (512 byte) in
235 					   the read-ahead buffer */
236 
237 static struct s535_sony_toc *sony_toc;	/* Points to the table of
238 					   contents. */
239 
240 static struct s535_sony_subcode *last_sony_subcode;		/* Points to the last
241 								   subcode address read */
242 static Byte **sony_buffer;		/* Points to the pointers
243 					   to the sector buffers */
244 
245 static int sony_inuse;			/* is the drive in use? Only one
246 					   open at a time allowed */
247 
248 /*
249  * The audio status uses the values from read subchannel data as specified
250  * in include/linux/cdrom.h.
251  */
252 static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
253 
254 /*
255  * The following are a hack for pausing and resuming audio play.  The drive
256  * does not work as I would expect it, if you stop it then start it again,
257  * the drive seeks back to the beginning and starts over.  This holds the
258  * position during a pause so a resume can restart it.  It uses the
259  * audio status variable above to tell if it is paused.
260  *   I just kept the CDU-31A driver behavior rather than using the PAUSE
261  * command on the CDU-535.
262  */
263 static Byte cur_pos_msf[3];
264 static Byte final_pos_msf[3];
265 
266 /* What IRQ is the drive using?  0 if none. */
267 static int sony535_irq_used = CDU535_INTERRUPT;
268 
269 /* The interrupt handler will wake this queue up when it gets an interrupt. */
270 static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait);
271 
272 
273 /*
274  * This routine returns 1 if the disk has been changed since the last
275  * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
276  */
277 static int
cdu535_check_media_change(kdev_t full_dev)278 cdu535_check_media_change(kdev_t full_dev)
279 {
280 	int retval;
281 
282 	if (MINOR(full_dev) != 0) {
283 		printk(CDU535_MESSAGE_NAME " request error: invalid device.\n");
284 		return 0;
285 	}
286 
287 	/* if driver is not initialized, always return 0 */
288 	retval = initialized ? sony_disc_changed : 0;
289 	sony_disc_changed = 0;
290 	return retval;
291 }
292 
293 static inline void
enable_interrupts(void)294 enable_interrupts(void)
295 {
296 #ifdef USE_IRQ
297 	/*
298 	 * This code was taken from cdu31a.c; it will not
299 	 * directly work for the cdu535 as written...
300 	 */
301 	curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
302 						| SONY_RES_RDY_INT_EN_BIT
303 						| SONY_DATA_RDY_INT_EN_BIT);
304 	outb(curr_control_reg, sony_cd_control_reg);
305 #endif
306 }
307 
308 static inline void
disable_interrupts(void)309 disable_interrupts(void)
310 {
311 #ifdef USE_IRQ
312 	/*
313 	 * This code was taken from cdu31a.c; it will not
314 	 * directly work for the cdu535 as written...
315 	 */
316 	curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
317 						| SONY_RES_RDY_INT_EN_BIT
318 						| SONY_DATA_RDY_INT_EN_BIT);
319 	outb(curr_control_reg, sony_cd_control_reg);
320 #endif
321 }
322 
323 static void
cdu535_interrupt(int irq,void * dev_id,struct pt_regs * regs)324 cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs)
325 {
326 	disable_interrupts();
327 	if (waitqueue_active(&cdu535_irq_wait))
328 		wake_up(&cdu535_irq_wait);
329 	else
330 		printk(CDU535_MESSAGE_NAME
331 				": Got an interrupt but nothing was waiting\n");
332 }
333 
334 
335 /*
336  * Wait a little while.
337  */
338 static inline void
sony_sleep(void)339 sony_sleep(void)
340 {
341 	if (sony535_irq_used <= 0) {	/* poll */
342 		current->state = TASK_INTERRUPTIBLE;
343 		schedule_timeout(0);
344 	} else {	/* Interrupt driven */
345 		cli();
346 		enable_interrupts();
347 		interruptible_sleep_on(&cdu535_irq_wait);
348 		sti();
349 	}
350 }
351 
352 /*------------------start of SONY CDU535 very specific ---------------------*/
353 
354 /****************************************************************************
355  * void select_unit( int unit_no )
356  *
357  *  Select the specified unit (0-3) so that subsequent commands reference it
358  ****************************************************************************/
359 static void
select_unit(int unit_no)360 select_unit(int unit_no)
361 {
362 	unsigned int select_mask = ~(1 << unit_no);
363 	outb(select_mask, select_unit_reg);
364 }
365 
366 /***************************************************************************
367  * int read_result_reg( Byte *data_ptr )
368  *
369  *  Read a result byte from the Sony CDU controller, store in location pointed
370  * to by data_ptr.  Return zero on success, TIME_OUT if we did not receive
371  * data.
372  ***************************************************************************/
373 static int
read_result_reg(Byte * data_ptr)374 read_result_reg(Byte *data_ptr)
375 {
376 	unsigned long snap;
377 	int read_status;
378 
379 	snap = jiffies;
380 	while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
381 		read_status = inb(read_status_reg);
382 		if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
383 #if DEBUG > 1
384 			printk(CDU535_MESSAGE_NAME
385 					": read_result_reg(): readStatReg = 0x%x\n", read_status);
386 #endif
387 			*data_ptr = inb(result_reg);
388 			return 0;
389 		} else {
390 			sony_sleep();
391 		}
392 	}
393 	printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n");
394 	return TIME_OUT;
395 }
396 
397 /****************************************************************************
398  * int read_exec_status( Byte status[2] )
399  *
400  *  Read the execution status of the last command and put into status.
401  * Handles reading second status word if available.  Returns 0 on success,
402  * TIME_OUT on failure.
403  ****************************************************************************/
404 static int
read_exec_status(Byte status[2])405 read_exec_status(Byte status[2])
406 {
407 	status[1] = 0;
408 	if (read_result_reg(&(status[0])) != 0)
409 		return TIME_OUT;
410 	if ((status[0] & 0x80) != 0) {	/* byte two follows */
411 		if (read_result_reg(&(status[1])) != 0)
412 			return TIME_OUT;
413 	}
414 #if DEBUG > 1
415 	printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n",
416 			status[0], status[1]);
417 #endif
418 	return 0;
419 }
420 
421 /****************************************************************************
422  * int check_drive_status( void )
423  *
424  *  Check the current drive status.  Using this before executing a command
425  * takes care of the problem of unsolicited drive status-2 messages.
426  * Add a check of the audio status if we think the disk is playing.
427  ****************************************************************************/
428 static int
check_drive_status(void)429 check_drive_status(void)
430 {
431 	Byte status, e_status[2];
432 	int  CDD, ATN;
433 	Byte cmd;
434 
435 	select_unit(0);
436 	if (sony_audio_status == CDROM_AUDIO_PLAY) {	/* check status */
437 		outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
438 		if (read_result_reg(&status) == 0) {
439 			switch (status) {
440 			case 0x0:
441 				break;		/* play in progress */
442 			case 0x1:
443 				break;		/* paused */
444 			case 0x3:		/* audio play completed */
445 			case 0x5:		/* play not requested */
446 				sony_audio_status = CDROM_AUDIO_COMPLETED;
447 				read_subcode();
448 				break;
449 			case 0x4:		/* error during play */
450 				sony_audio_status = CDROM_AUDIO_ERROR;
451 				break;
452 			}
453 		}
454 	}
455 	/* now check drive status */
456 	outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
457 	if (read_result_reg(&status) != 0)
458 		return TIME_OUT;
459 
460 #if DEBUG > 1
461 	printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status);
462 #endif
463 
464 	if (status == 0)
465 		return 0;
466 
467 	ATN = status & 0xf;
468 	CDD = (status >> 4) & 0xf;
469 
470 	switch (ATN) {
471 	case 0x0:
472 		break;					/* go on to CDD stuff */
473 	case SONY535_ATN_BUSY:
474 		if (initialized)
475 			printk(CDU535_MESSAGE_NAME " error: drive busy\n");
476 		return CD_BUSY;
477 	case SONY535_ATN_EJECT_IN_PROGRESS:
478 		printk(CDU535_MESSAGE_NAME " error: eject in progress\n");
479 		sony_audio_status = CDROM_AUDIO_INVALID;
480 		return CD_BUSY;
481 	case SONY535_ATN_RESET_OCCURRED:
482 	case SONY535_ATN_DISC_CHANGED:
483 	case SONY535_ATN_RESET_AND_DISC_CHANGED:
484 #if DEBUG > 0
485 		printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n");
486 #endif
487 		sony_disc_changed = 1;
488 		sony_toc_read = 0;
489 		sony_audio_status = CDROM_AUDIO_NO_STATUS;
490 		sony_first_block = -1;
491 		sony_last_block = -1;
492 		if (initialized) {
493 			cmd = SONY535_SPIN_UP;
494 			do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
495 			sony_get_toc();
496 		}
497 		return 0;
498 	default:
499 		printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN);
500 		return CD_BUSY;
501 	}
502 	switch (CDD) {			/* the 531 docs are not helpful in decoding this */
503 	case 0x0:				/* just use the values from the DOS driver */
504 	case 0x2:
505 	case 0xa:
506 		break;				/* no error */
507 	case 0xc:
508 		printk(CDU535_MESSAGE_NAME
509 				": check_drive_status(): CDD = 0xc! Not properly handled!\n");
510 		return CD_BUSY;		/* ? */
511 	default:
512 		return CD_BUSY;
513 	}
514 	return 0;
515 }	/* check_drive_status() */
516 
517 /*****************************************************************************
518  * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
519  *                Byte *response, int n_response, int ignore_status_bit7 )
520  *
521  *  Generic routine for executing commands.  The command and its parameters
522  *  should be placed in the cmd[] array, number of bytes in the command is
523  *  stored in nCmd.  The response from the command will be stored in the
524  *  response array.  The number of bytes you expect back (excluding status)
525  *  should be passed in n_response.  Finally, some
526  *  commands set bit 7 of the return status even when there is no second
527  *  status byte, on these commands set ignoreStatusBit7 TRUE.
528  *    If the command was sent and data received back, then we return 0,
529  *  else we return TIME_OUT.  You still have to check the status yourself.
530  *    You should call check_drive_status() before calling this routine
531  *  so that you do not lose notifications of disk changes, etc.
532  ****************************************************************************/
533 static int
do_sony_cmd(Byte * cmd,int n_cmd,Byte status[2],Byte * response,int n_response,int ignore_status_bit7)534 do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
535 			Byte * response, int n_response, int ignore_status_bit7)
536 {
537 	int i;
538 
539 	/* write out the command */
540 	for (i = 0; i < n_cmd; i++)
541 		outb(cmd[i], command_reg);
542 
543 	/* read back the status */
544 	if (read_result_reg(status) != 0)
545 		return TIME_OUT;
546 	if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
547 		/* get second status byte */
548 		if (read_result_reg(status + 1) != 0)
549 			return TIME_OUT;
550 	} else {
551 		status[1] = 0;
552 	}
553 #if DEBUG > 2
554 	printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n",
555 			*cmd, status[0], status[1]);
556 #endif
557 
558 	/* do not know about when I should read set of data and when not to */
559 	if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
560 		return 0;
561 
562 	/* else, read in rest of data */
563 	for (i = 0; 0 < n_response; n_response--, i++)
564 		if (read_result_reg(response + i) != 0)
565 			return TIME_OUT;
566 	return 0;
567 }	/* do_sony_cmd() */
568 
569 /**************************************************************************
570  * int set_drive_mode( int mode, Byte status[2] )
571  *
572  *  Set the drive mode to the specified value (mode=0 is audio, mode=e0
573  * is mode-1 CDROM
574  **************************************************************************/
575 static int
set_drive_mode(int mode,Byte status[2])576 set_drive_mode(int mode, Byte status[2])
577 {
578 	Byte cmd_buff[2];
579 	Byte ret_buff[1];
580 
581 	cmd_buff[0] = SONY535_SET_DRIVE_MODE;
582 	cmd_buff[1] = mode;
583 	return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
584 }
585 
586 /***************************************************************************
587  * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
588  *                             Byte *data_buff, int buff_size )
589  *
590  *  Read n_blocks of data from the CDROM starting at position params[0:2],
591  *  number of blocks in stored in params[3:5] -- both these are already
592  *  int bcd format.
593  *  Transfer the data into the buffer pointed at by data_buff.  buff_size
594  *  gives the number of bytes available in the buffer.
595  *    The routine returns number of bytes read in if successful, otherwise
596  *  it returns one of the standard error returns.
597  ***************************************************************************/
598 static int
seek_and_read_N_blocks(Byte params[],int n_blocks,Byte status[2],Byte ** buff,int buf_size)599 seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
600 					   Byte **buff, int buf_size)
601 {
602 	Byte cmd_buff[7];
603 	int  i;
604 	int  read_status;
605 	unsigned long snap;
606 	Byte *data_buff;
607 	int  sector_count = 0;
608 
609 	if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
610 		return NO_ROOM;
611 
612 	set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
613 
614 	/* send command to read the data */
615 	cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
616 	for (i = 0; i < 6; i++)
617 		cmd_buff[i + 1] = params[i];
618 	for (i = 0; i < 7; i++)
619 		outb(cmd_buff[i], command_reg);
620 
621 	/* read back the data one block at a time */
622 	while (0 < n_blocks--) {
623 		/* wait for data to be ready */
624 		int data_valid = 0;
625 		snap = jiffies;
626 		while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
627 			read_status = inb(read_status_reg);
628 			if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
629 				read_exec_status(status);
630 				return BAD_STATUS;
631 			}
632 			if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
633 				/* data is ready, read it */
634 				data_buff = buff[sector_count++];
635 				for (i = 0; i < CDU535_BLOCK_SIZE; i++)
636 					*data_buff++ = inb(data_reg);	/* unrolling this loop does not seem to help */
637 				data_valid = 1;
638 				break;			/* exit the timeout loop */
639 			}
640 			sony_sleep();		/* data not ready, sleep a while */
641 		}
642 		if (!data_valid)
643 			return TIME_OUT;	/* if we reach this stage */
644 	}
645 
646 	/* read all the data, now read the status */
647 	if ((i = read_exec_status(status)) != 0)
648 		return i;
649 	return CDU535_BLOCK_SIZE * sector_count;
650 }	/* seek_and_read_N_blocks() */
651 
652 /****************************************************************************
653  * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
654  *
655  *  Read in the table of contents data.  Converts all the bcd data
656  * into integers in the toc structure.
657  ****************************************************************************/
658 static int
request_toc_data(Byte status[2],struct s535_sony_toc * toc)659 request_toc_data(Byte status[2], struct s535_sony_toc *toc)
660 {
661 	int  to_status;
662 	int  i, j, n_tracks, track_no;
663 	int  first_track_num, last_track_num;
664 	Byte cmd_no = 0xb2;
665 	Byte track_address_buffer[5];
666 
667 	/* read the fixed portion of the table of contents */
668 	if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
669 		return to_status;
670 
671 	/* convert the data into integers so we can use them */
672 	first_track_num = bcd_to_int(toc->first_track_num);
673 	last_track_num = bcd_to_int(toc->last_track_num);
674 	n_tracks = last_track_num - first_track_num + 1;
675 
676 	/* read each of the track address descriptors */
677 	for (i = 0; i < n_tracks; i++) {
678 		/* read the descriptor into a temporary buffer */
679 		for (j = 0; j < 5; j++) {
680 			if (read_result_reg(track_address_buffer + j) != 0)
681 				return TIME_OUT;
682 			if (j == 1)		/* need to convert from bcd */
683 				track_no = bcd_to_int(track_address_buffer[j]);
684 		}
685 		/* copy the descriptor to proper location - sonycd.c just fills */
686 		memcpy(toc->tracks + i, track_address_buffer, 5);
687 	}
688 	return 0;
689 }	/* request_toc_data() */
690 
691 /***************************************************************************
692  * int spin_up_drive( Byte status[2] )
693  *
694  *  Spin up the drive (unless it is already spinning).
695  ***************************************************************************/
696 static int
spin_up_drive(Byte status[2])697 spin_up_drive(Byte status[2])
698 {
699 	Byte cmd;
700 
701 	/* first see if the drive is already spinning */
702 	cmd = SONY535_REQUEST_DRIVE_STATUS_1;
703 	if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0)
704 		return TIME_OUT;
705 	if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
706 		return 0;	/* it's already spinning */
707 
708 	/* otherwise, give the spin-up command */
709 	cmd = SONY535_SPIN_UP;
710 	return do_sony_cmd(&cmd, 1, status, NULL, 0, 0);
711 }
712 
713 /*--------------------end of SONY CDU535 very specific ---------------------*/
714 
715 /* Convert from an integer 0-99 to BCD */
716 static inline unsigned int
int_to_bcd(unsigned int val)717 int_to_bcd(unsigned int val)
718 {
719 	int retval;
720 
721 	retval = (val / 10) << 4;
722 	retval = retval | val % 10;
723 	return retval;
724 }
725 
726 
727 /* Convert from BCD to an integer from 0-99 */
728 static unsigned int
bcd_to_int(unsigned int bcd)729 bcd_to_int(unsigned int bcd)
730 {
731 	return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
732 }
733 
734 
735 /*
736  * Convert a logical sector value (like the OS would want to use for
737  * a block device) to an MSF format.
738  */
739 static void
log_to_msf(unsigned int log,Byte * msf)740 log_to_msf(unsigned int log, Byte *msf)
741 {
742 	log = log + LOG_START_OFFSET;
743 	msf[0] = int_to_bcd(log / 4500);
744 	log = log % 4500;
745 	msf[1] = int_to_bcd(log / 75);
746 	msf[2] = int_to_bcd(log % 75);
747 }
748 
749 
750 /*
751  * Convert an MSF format to a logical sector.
752  */
753 static unsigned int
msf_to_log(Byte * msf)754 msf_to_log(Byte *msf)
755 {
756 	unsigned int log;
757 
758 
759 	log = bcd_to_int(msf[2]);
760 	log += bcd_to_int(msf[1]) * 75;
761 	log += bcd_to_int(msf[0]) * 4500;
762 	log = log - LOG_START_OFFSET;
763 
764 	return log;
765 }
766 
767 
768 /*
769  * Take in integer size value and put it into a buffer like
770  * the drive would want to see a number-of-sector value.
771  */
772 static void
size_to_buf(unsigned int size,Byte * buf)773 size_to_buf(unsigned int size, Byte *buf)
774 {
775 	buf[0] = size / 65536;
776 	size = size % 65536;
777 	buf[1] = size / 256;
778 	buf[2] = size % 256;
779 }
780 
781 
782 /*
783  * The OS calls this to perform a read or write operation to the drive.
784  * Write obviously fail.  Reads to a read ahead of sony_buffer_size
785  * bytes to help speed operations.  This especially helps since the OS
786  * may use 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
787  * data access on a CD is done sequentially, this saves a lot of operations.
788  */
789 static void
do_cdu535_request(request_queue_t * q)790 do_cdu535_request(request_queue_t * q)
791 {
792 	unsigned int dev;
793 	unsigned int read_size;
794 	int  block;
795 	int  nsect;
796 	int  copyoff;
797 	int  spin_up_retry;
798 	Byte params[10];
799 	Byte status[2];
800 	Byte cmd[2];
801 
802 	while (1) {
803 		/*
804 		 * The beginning here is stolen from the hard disk driver.  I hope
805 		 * it's right.
806 		 */
807 		if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) {
808 			return;
809 		}
810 		INIT_REQUEST;
811 		dev = MINOR(CURRENT->rq_dev);
812 		block = CURRENT->sector;
813 		nsect = CURRENT->nr_sectors;
814 		if (dev != 0) {
815 			end_request(0);
816 			continue;
817 		}
818 		switch (CURRENT->cmd) {
819 		case READ:
820 			/*
821 			 * If the block address is invalid or the request goes beyond the end of
822 			 * the media, return an error.
823 			 */
824 
825 			if (sony_toc->lead_out_start_lba <= (block / 4)) {
826 				end_request(0);
827 				return;
828 			}
829 			if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
830 				end_request(0);
831 				return;
832 			}
833 			while (0 < nsect) {
834 				/*
835 				 * If the requested sector is not currently in the read-ahead buffer,
836 				 * it must be read in.
837 				 */
838 				if ((block < sony_first_block) || (sony_last_block < block)) {
839 					sony_first_block = (block / 4) * 4;
840 					log_to_msf(block / 4, params);
841 
842 					/*
843 					 * If the full read-ahead would go beyond the end of the media, trim
844 					 * it back to read just till the end of the media.
845 					 */
846 					if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
847 						sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
848 						read_size = sony_toc->lead_out_start_lba - (block / 4);
849 					} else {
850 						sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
851 						read_size = sony_buffer_sectors;
852 					}
853 					size_to_buf(read_size, &params[3]);
854 
855 					/*
856 					 * Read the data.  If the drive was not spinning,
857 					 * spin it up and try some more.
858 					 */
859 					for (spin_up_retry=0 ;; ++spin_up_retry) {
860 						/* This loop has been modified to support the Sony
861 						 * CDU-510/515 series, thanks to Claudio Porfiri
862 						 * <C.Porfiri@nisms.tei.ericsson.se>.
863 						 */
864 						/*
865 						 * This part is to deal with very slow hardware.  We
866 						 * try at most MAX_SPINUP_RETRY times to read the same
867 						 * block.  A check for seek_and_read_N_blocks' result is
868 						 * performed; if the result is wrong, the CDROM's engine
869 						 * is restarted and the operation is tried again.
870 						 */
871 						/*
872 						 * 1995-06-01: The system got problems when downloading
873 						 * from Slackware CDROM, the problem seems to be:
874 						 * seek_and_read_N_blocks returns BAD_STATUS and we
875 						 * should wait for a while before retrying, so a new
876 						 * part was added to discriminate the return value from
877 						 * seek_and_read_N_blocks for the various cases.
878 						 */
879 						int readStatus = seek_and_read_N_blocks(params, read_size,
880 									status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
881 						if (0 <= readStatus)	/* Good data; common case, placed first */
882 							break;
883 						if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
884 							/* give up */
885 							if (readStatus == NO_ROOM)
886 								printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
887 							else
888 								printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
889 										status[0]);
890 							sony_first_block = -1;
891 							sony_last_block = -1;
892 							end_request(0);
893 							return;
894 						}
895 						if (readStatus == BAD_STATUS) {
896 							/* Sleep for a while, then retry */
897 							current->state = TASK_INTERRUPTIBLE;
898 							schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
899 						}
900 #if DEBUG > 0
901 						printk(CDU535_MESSAGE_NAME
902 							" debug: calling spin up when reading data!\n");
903 #endif
904 						cmd[0] = SONY535_SPIN_UP;
905 						do_sony_cmd(cmd, 1, status, NULL, 0, 0);
906 					}
907 				}
908 				/*
909 				 * The data is in memory now, copy it to the buffer and advance to the
910 				 * next block to read.
911 				 */
912 				copyoff = block - sony_first_block;
913 				memcpy(CURRENT->buffer,
914 					   sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
915 
916 				block += 1;
917 				nsect -= 1;
918 				CURRENT->buffer += 512;
919 			}
920 
921 			end_request(1);
922 			break;
923 
924 		case WRITE:
925 			end_request(0);
926 			break;
927 
928 		default:
929 			panic("Unknown SONY CD cmd");
930 		}
931 	}
932 }
933 
934 
935 /*
936  * Read the table of contents from the drive and set sony_toc_read if
937  * successful.
938  */
939 static void
sony_get_toc(void)940 sony_get_toc(void)
941 {
942 	Byte status[2];
943 	if (!sony_toc_read) {
944 		/* do not call check_drive_status() from here since it can call this routine */
945 		if (request_toc_data(status, sony_toc) < 0)
946 			return;
947 		sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
948 		sony_toc_read = 1;
949 	}
950 }
951 
952 
953 /*
954  * Search for a specific track in the table of contents.  track is
955  * passed in bcd format
956  */
957 static int
find_track(int track)958 find_track(int track)
959 {
960 	int i;
961 	int num_tracks;
962 
963 
964 	num_tracks = bcd_to_int(sony_toc->last_track_num) -
965 		bcd_to_int(sony_toc->first_track_num) + 1;
966 	for (i = 0; i < num_tracks; i++) {
967 		if (sony_toc->tracks[i].track == track) {
968 			return i;
969 		}
970 	}
971 
972 	return -1;
973 }
974 
975 /*
976  * Read the subcode and put it int last_sony_subcode for future use.
977  */
978 static int
read_subcode(void)979 read_subcode(void)
980 {
981 	Byte cmd = SONY535_REQUEST_SUB_Q_DATA;
982 	Byte status[2];
983 	int  dsc_status;
984 
985 	if (check_drive_status() != 0)
986 		return -EIO;
987 
988 	if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
989 							   sizeof(struct s535_sony_subcode), 1)) != 0) {
990 		printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n",
991 				status[0], dsc_status);
992 		return -EIO;
993 	}
994 	return 0;
995 }
996 
997 
998 /*
999  * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
1000  * the drive is playing, the subchannel needs to be read (since it would be
1001  * changing).  If the drive is paused or completed, the subcode information has
1002  * already been stored, just use that.  The ioctl call wants things in decimal
1003  * (not BCD), so all the conversions are done.
1004  */
1005 static int
sony_get_subchnl_info(long arg)1006 sony_get_subchnl_info(long arg)
1007 {
1008 	struct cdrom_subchnl schi;
1009 	int err;
1010 
1011 	/* Get attention stuff */
1012 	if (check_drive_status() != 0)
1013 		return -EIO;
1014 
1015 	sony_get_toc();
1016 	if (!sony_toc_read) {
1017 		return -EIO;
1018 	}
1019 	err = verify_area(VERIFY_WRITE /* and read */ , (char *)arg, sizeof schi);
1020 	if (err)
1021 		return err;
1022 
1023 	copy_from_user(&schi, (char *)arg, sizeof schi);
1024 
1025 	switch (sony_audio_status) {
1026 	case CDROM_AUDIO_PLAY:
1027 		if (read_subcode() < 0) {
1028 			return -EIO;
1029 		}
1030 		break;
1031 
1032 	case CDROM_AUDIO_PAUSED:
1033 	case CDROM_AUDIO_COMPLETED:
1034 		break;
1035 
1036 	case CDROM_AUDIO_NO_STATUS:
1037 		schi.cdsc_audiostatus = sony_audio_status;
1038 		copy_to_user((char *)arg, &schi, sizeof schi);
1039 		return 0;
1040 		break;
1041 
1042 	case CDROM_AUDIO_INVALID:
1043 	case CDROM_AUDIO_ERROR:
1044 	default:
1045 		return -EIO;
1046 	}
1047 
1048 	schi.cdsc_audiostatus = sony_audio_status;
1049 	schi.cdsc_adr = last_sony_subcode->address;
1050 	schi.cdsc_ctrl = last_sony_subcode->control;
1051 	schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
1052 	schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
1053 	if (schi.cdsc_format == CDROM_MSF) {
1054 		schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
1055 		schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
1056 		schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
1057 
1058 		schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
1059 		schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
1060 		schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
1061 	} else if (schi.cdsc_format == CDROM_LBA) {
1062 		schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
1063 		schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
1064 	}
1065 	copy_to_user((char *)arg, &schi, sizeof schi);
1066 	return 0;
1067 }
1068 
1069 
1070 /*
1071  * The big ugly ioctl handler.
1072  */
1073 static int
cdu_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)1074 cdu_ioctl(struct inode *inode,
1075 		  struct file *file,
1076 		  unsigned int cmd,
1077 		  unsigned long arg)
1078 {
1079 	unsigned int dev;
1080 	Byte status[2];
1081 	Byte cmd_buff[10], params[10];
1082 	int  i;
1083 	int  dsc_status;
1084 	int  err;
1085 
1086 	if (!inode) {
1087 		return -EINVAL;
1088 	}
1089 	dev = MINOR(inode->i_rdev) >> 6;
1090 	if (dev != 0) {
1091 		return -EINVAL;
1092 	}
1093 	if (check_drive_status() != 0)
1094 		return -EIO;
1095 
1096 	switch (cmd) {
1097 	case CDROMSTART:			/* Spin up the drive */
1098 		if (spin_up_drive(status) < 0) {
1099 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n",
1100 					status[0]);
1101 			return -EIO;
1102 		}
1103 		return 0;
1104 		break;
1105 
1106 	case CDROMSTOP:			/* Spin down the drive */
1107 		cmd_buff[0] = SONY535_HOLD;
1108 		do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1109 
1110 		/*
1111 		 * Spin the drive down, ignoring the error if the disk was
1112 		 * already not spinning.
1113 		 */
1114 		sony_audio_status = CDROM_AUDIO_NO_STATUS;
1115 		cmd_buff[0] = SONY535_SPIN_DOWN;
1116 		dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1117 		if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
1118 			((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
1119 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n",
1120 					status[0]);
1121 			return -EIO;
1122 		}
1123 		return 0;
1124 		break;
1125 
1126 	case CDROMPAUSE:			/* Pause the drive */
1127 		cmd_buff[0] = SONY535_HOLD;		/* CDU-31 driver uses AUDIO_STOP, not pause */
1128 		if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1129 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n",
1130 					status[0]);
1131 			return -EIO;
1132 		}
1133 		/* Get the current position and save it for resuming */
1134 		if (read_subcode() < 0) {
1135 			return -EIO;
1136 		}
1137 		cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1138 		cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1139 		cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1140 		sony_audio_status = CDROM_AUDIO_PAUSED;
1141 		return 0;
1142 		break;
1143 
1144 	case CDROMRESUME:			/* Start the drive after being paused */
1145 		set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1146 
1147 		if (sony_audio_status != CDROM_AUDIO_PAUSED) {
1148 			return -EINVAL;
1149 		}
1150 		spin_up_drive(status);
1151 
1152 		/* Start the drive at the saved position. */
1153 		cmd_buff[0] = SONY535_PLAY_AUDIO;
1154 		cmd_buff[1] = 0;		/* play back starting at this address */
1155 		cmd_buff[2] = cur_pos_msf[0];
1156 		cmd_buff[3] = cur_pos_msf[1];
1157 		cmd_buff[4] = cur_pos_msf[2];
1158 		cmd_buff[5] = SONY535_PLAY_AUDIO;
1159 		cmd_buff[6] = 2;		/* set ending address */
1160 		cmd_buff[7] = final_pos_msf[0];
1161 		cmd_buff[8] = final_pos_msf[1];
1162 		cmd_buff[9] = final_pos_msf[2];
1163 		if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1164 			(do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1165 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n",
1166 					status[0]);
1167 			return -EIO;
1168 		}
1169 		sony_audio_status = CDROM_AUDIO_PLAY;
1170 		return 0;
1171 		break;
1172 
1173 	case CDROMPLAYMSF:			/* Play starting at the given MSF address. */
1174 		err = verify_area(VERIFY_READ, (char *)arg, 6);
1175 		if (err)
1176 			return err;
1177 		spin_up_drive(status);
1178 		set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1179 		copy_from_user(params, (void *)arg, 6);
1180 
1181 		/* The parameters are given in int, must be converted */
1182 		for (i = 0; i < 3; i++) {
1183 			cmd_buff[2 + i] = int_to_bcd(params[i]);
1184 			cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
1185 		}
1186 		cmd_buff[0] = SONY535_PLAY_AUDIO;
1187 		cmd_buff[1] = 0;		/* play back starting at this address */
1188 		/* cmd_buff[2-4] are filled in for loop above */
1189 		cmd_buff[5] = SONY535_PLAY_AUDIO;
1190 		cmd_buff[6] = 2;		/* set ending address */
1191 		/* cmd_buff[7-9] are filled in for loop above */
1192 		if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1193 			(do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1194 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n",
1195 					status[0]);
1196 			return -EIO;
1197 		}
1198 		/* Save the final position for pauses and resumes */
1199 		final_pos_msf[0] = cmd_buff[7];
1200 		final_pos_msf[1] = cmd_buff[8];
1201 		final_pos_msf[2] = cmd_buff[9];
1202 		sony_audio_status = CDROM_AUDIO_PLAY;
1203 		return 0;
1204 		break;
1205 
1206 	case CDROMREADTOCHDR:		/* Read the table of contents header */
1207 		{
1208 			struct cdrom_tochdr *hdr;
1209 			struct cdrom_tochdr loc_hdr;
1210 
1211 			sony_get_toc();
1212 			if (!sony_toc_read)
1213 				return -EIO;
1214 			hdr = (struct cdrom_tochdr *)arg;
1215 			err = verify_area(VERIFY_WRITE, hdr, sizeof *hdr);
1216 			if (err)
1217 				return err;
1218 			loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1219 			loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1220 			copy_to_user(hdr, &loc_hdr, sizeof *hdr);
1221 		}
1222 		return 0;
1223 		break;
1224 
1225 	case CDROMREADTOCENTRY:	/* Read a given table of contents entry */
1226 		{
1227 			struct cdrom_tocentry *entry;
1228 			struct cdrom_tocentry loc_entry;
1229 			int  track_idx;
1230 			Byte *msf_val = NULL;
1231 
1232 			sony_get_toc();
1233 			if (!sony_toc_read) {
1234 				return -EIO;
1235 			}
1236 			entry = (struct cdrom_tocentry *)arg;
1237 			err = verify_area(VERIFY_WRITE /* and read */ , entry, sizeof *entry);
1238 			if (err)
1239 				return err;
1240 
1241 			copy_from_user(&loc_entry, entry, sizeof loc_entry);
1242 
1243 			/* Lead out is handled separately since it is special. */
1244 			if (loc_entry.cdte_track == CDROM_LEADOUT) {
1245 				loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ;
1246 				loc_entry.cdte_ctrl = sony_toc->control2;
1247 				msf_val = sony_toc->lead_out_start_msf;
1248 			} else {
1249 				track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1250 				if (track_idx < 0)
1251 					return -EINVAL;
1252 				loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ;
1253 				loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1254 				msf_val = sony_toc->tracks[track_idx].track_start_msf;
1255 			}
1256 
1257 			/* Logical buffer address or MSF format requested? */
1258 			if (loc_entry.cdte_format == CDROM_LBA) {
1259 				loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1260 			} else if (loc_entry.cdte_format == CDROM_MSF) {
1261 				loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1262 				loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
1263 				loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
1264 			}
1265 			copy_to_user(entry, &loc_entry, sizeof *entry);
1266 		}
1267 		return 0;
1268 		break;
1269 
1270 	case CDROMPLAYTRKIND:		/* Play a track.  This currently ignores index. */
1271 		{
1272 			struct cdrom_ti ti;
1273 			int track_idx;
1274 
1275 			sony_get_toc();
1276 			if (!sony_toc_read)
1277 				return -EIO;
1278 			err = verify_area(VERIFY_READ, (char *)arg, sizeof ti);
1279 			if (err)
1280 				return err;
1281 
1282 			copy_from_user(&ti, (char *)arg, sizeof ti);
1283 			if ((ti.cdti_trk0 < sony_toc->first_track_num)
1284 				|| (sony_toc->last_track_num < ti.cdti_trk0)
1285 				|| (ti.cdti_trk1 < ti.cdti_trk0)) {
1286 				return -EINVAL;
1287 			}
1288 			track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1289 			if (track_idx < 0)
1290 				return -EINVAL;
1291 			params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1292 			params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1293 			params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1294 			/*
1295 			 * If we want to stop after the last track, use the lead-out
1296 			 * MSF to do that.
1297 			 */
1298 			if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
1299 				log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
1300 						   &(params[4]));
1301 			} else {
1302 				track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
1303 				if (track_idx < 0)
1304 					return -EINVAL;
1305 				log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
1306 						   &(params[4]));
1307 			}
1308 			params[0] = 0x03;
1309 
1310 			spin_up_drive(status);
1311 
1312 			set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1313 
1314 			/* Start the drive at the saved position. */
1315 			cmd_buff[0] = SONY535_PLAY_AUDIO;
1316 			cmd_buff[1] = 0;	/* play back starting at this address */
1317 			cmd_buff[2] = params[1];
1318 			cmd_buff[3] = params[2];
1319 			cmd_buff[4] = params[3];
1320 			cmd_buff[5] = SONY535_PLAY_AUDIO;
1321 			cmd_buff[6] = 2;	/* set ending address */
1322 			cmd_buff[7] = params[4];
1323 			cmd_buff[8] = params[5];
1324 			cmd_buff[9] = params[6];
1325 			if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1326 				(do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1327 				printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n",
1328 						status[0]);
1329 				printk("... Params: %x %x %x %x %x %x %x\n",
1330 						params[0], params[1], params[2],
1331 						params[3], params[4], params[5], params[6]);
1332 				return -EIO;
1333 			}
1334 			/* Save the final position for pauses and resumes */
1335 			final_pos_msf[0] = params[4];
1336 			final_pos_msf[1] = params[5];
1337 			final_pos_msf[2] = params[6];
1338 			sony_audio_status = CDROM_AUDIO_PLAY;
1339 			return 0;
1340 		}
1341 
1342 	case CDROMSUBCHNL:			/* Get subchannel info */
1343 		return sony_get_subchnl_info(arg);
1344 
1345 	case CDROMVOLCTRL:			/* Volume control.  What volume does this change, anyway? */
1346 		{
1347 			struct cdrom_volctrl volctrl;
1348 
1349 			err = verify_area(VERIFY_READ, (char *)arg, sizeof volctrl);
1350 			if (err)
1351 				return err;
1352 
1353 			copy_from_user(&volctrl, (char *)arg, sizeof volctrl);
1354 			cmd_buff[0] = SONY535_SET_VOLUME;
1355 			cmd_buff[1] = volctrl.channel0;
1356 			cmd_buff[2] = volctrl.channel1;
1357 			if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
1358 				printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n",
1359 						status[0]);
1360 				return -EIO;
1361 			}
1362 		}
1363 		return 0;
1364 
1365 	case CDROMEJECT:			/* Eject the drive */
1366 		cmd_buff[0] = SONY535_STOP;
1367 		do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1368 		cmd_buff[0] = SONY535_SPIN_DOWN;
1369 		do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1370 
1371 		sony_audio_status = CDROM_AUDIO_INVALID;
1372 		cmd_buff[0] = SONY535_EJECT_CADDY;
1373 		if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1374 			printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n",
1375 					status[0]);
1376 			return -EIO;
1377 		}
1378 		return 0;
1379 		break;
1380 
1381 	default:
1382 		return -EINVAL;
1383 	}
1384 }
1385 
1386 
1387 /*
1388  * Open the drive for operations.  Spin the drive up and read the table of
1389  * contents if these have not already been done.
1390  */
1391 static int
cdu_open(struct inode * inode,struct file * filp)1392 cdu_open(struct inode *inode,
1393 		 struct file *filp)
1394 {
1395 	Byte status[2], cmd_buff[2];
1396 
1397 	if (sony_inuse)
1398 		return -EBUSY;
1399 	if (check_drive_status() != 0)
1400 		return -EIO;
1401 	sony_inuse = 1;
1402 
1403 	if (spin_up_drive(status) != 0) {
1404 		printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n",
1405 				status[0]);
1406 		sony_inuse = 0;
1407 		return -EIO;
1408 	}
1409 	sony_get_toc();
1410 	if (!sony_toc_read) {
1411 		cmd_buff[0] = SONY535_SPIN_DOWN;
1412 		do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1413 		sony_inuse = 0;
1414 		return -EIO;
1415 	}
1416 	if (inode) {
1417 		check_disk_change(inode->i_rdev);
1418 	}
1419 	sony_usage++;
1420 
1421 #ifdef LOCK_DOORS
1422 	/* disable the eject button while mounted */
1423 	cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
1424 	do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1425 #endif
1426 
1427 	return 0;
1428 }
1429 
1430 
1431 /*
1432  * Close the drive.  Spin it down if no task is using it.  The spin
1433  * down will fail if playing audio, so audio play is OK.
1434  */
1435 static int
cdu_release(struct inode * inode,struct file * filp)1436 cdu_release(struct inode *inode,
1437 			struct file *filp)
1438 {
1439 	Byte status[2], cmd_no;
1440 
1441 	sony_inuse = 0;
1442 
1443 	if (0 < sony_usage) {
1444 		sony_usage--;
1445 	}
1446 	if (sony_usage == 0) {
1447 		check_drive_status();
1448 
1449 		if (sony_audio_status != CDROM_AUDIO_PLAY) {
1450 			cmd_no = SONY535_SPIN_DOWN;
1451 			do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1452 		}
1453 #ifdef LOCK_DOORS
1454 		/* enable the eject button after umount */
1455 		cmd_no = SONY535_ENABLE_EJECT_BUTTON;
1456 		do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1457 #endif
1458 	}
1459 	return 0;
1460 }
1461 
1462 static struct block_device_operations cdu_fops =
1463 {
1464 	owner:			THIS_MODULE,
1465 	open:			cdu_open,
1466 	release:		cdu_release,
1467 	ioctl:			cdu_ioctl,
1468 	check_media_change:	cdu535_check_media_change,
1469 };
1470 
1471 static int sonycd535_block_size = CDU535_BLOCK_SIZE;
1472 
1473 /*
1474  * Initialize the driver.
1475  */
1476 int __init
sony535_init(void)1477 sony535_init(void)
1478 {
1479 	struct s535_sony_drive_config drive_config;
1480 	Byte cmd_buff[3];
1481 	Byte ret_buff[2];
1482 	Byte status[2];
1483 	unsigned long snap;
1484 	int  got_result = 0;
1485 	int  tmp_irq;
1486 	int  i;
1487 
1488 	/* Setting the base I/O address to 0 will disable it. */
1489 	if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
1490 		return 0;
1491 
1492 	/* Set up all the register locations */
1493 	result_reg = sony535_cd_base_io;
1494 	command_reg = sony535_cd_base_io;
1495 	data_reg = sony535_cd_base_io + 1;
1496 	read_status_reg = sony535_cd_base_io + 2;
1497 	select_unit_reg = sony535_cd_base_io + 3;
1498 
1499 #ifndef USE_IRQ
1500 	sony535_irq_used = 0;	/* polling only until this is ready... */
1501 #endif
1502 	/* we need to poll until things get initialized */
1503 	tmp_irq = sony535_irq_used;
1504 	sony535_irq_used = 0;
1505 
1506 #if DEBUG > 0
1507 	printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n",
1508 			sony535_cd_base_io);
1509 #endif
1510 	if (check_region(sony535_cd_base_io,4)) {
1511 		printk(CDU535_MESSAGE_NAME ": my base address is not free!\n");
1512 		return -EIO;
1513 	}
1514 
1515 	/* look for the CD-ROM, follows the procedure in the DOS driver */
1516 	inb(select_unit_reg);
1517 	/* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
1518 	current->state = TASK_INTERRUPTIBLE;
1519 	schedule_timeout((HZ+17)*40/18);
1520 	inb(result_reg);
1521 
1522 	outb(0, read_status_reg);	/* does a reset? */
1523 	snap = jiffies;
1524 	while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
1525 		select_unit(0);
1526 		if (inb(result_reg) != 0xff) {
1527 			got_result = 1;
1528 			break;
1529 		}
1530 		sony_sleep();
1531 	}
1532 
1533 	if (got_result && (check_drive_status() != TIME_OUT)) {
1534 		/* CD-ROM drive responded --  get the drive configuration */
1535 		cmd_buff[0] = SONY535_INQUIRY;
1536 		if (do_sony_cmd(cmd_buff, 1, status,
1537 						(Byte *)&drive_config, 28, 1) == 0) {
1538 			/* was able to get the configuration,
1539 			 * set drive mode as rest of init
1540 			 */
1541 #if DEBUG > 0
1542 			/* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
1543 			if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
1544 				printk(CDU535_MESSAGE_NAME
1545 						"Inquiry command returned status = 0x%x\n", status[0]);
1546 #endif
1547 			/* now ready to use interrupts, if available */
1548 			sony535_irq_used = tmp_irq;
1549 #ifndef MODULE
1550 /* This code is not in MODULEs by default, since the autoirq stuff might
1551  * not be in the module-accessible symbol table.
1552  */
1553 			/* A negative sony535_irq_used will attempt an autoirq. */
1554 			if (sony535_irq_used < 0) {
1555 				autoirq_setup(0);
1556 				enable_interrupts();
1557 				outb(0, read_status_reg);	/* does a reset? */
1558 				sony535_irq_used = autoirq_report(10);
1559 				disable_interrupts();
1560 			}
1561 #endif
1562 			if (sony535_irq_used > 0) {
1563 			    if (request_irq(sony535_irq_used, cdu535_interrupt,
1564 								SA_INTERRUPT, CDU535_HANDLE, NULL)) {
1565 					printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
1566 							" driver; polling instead.\n", sony535_irq_used);
1567 					sony535_irq_used = 0;
1568 				}
1569 			}
1570 			cmd_buff[0] = SONY535_SET_DRIVE_MODE;
1571 			cmd_buff[1] = 0x0;	/* default audio */
1572 			if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) == 0) {
1573 				/* set the drive mode successful, we are set! */
1574 				sony_buffer_size = SONY535_BUFFER_SIZE;
1575 				sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
1576 
1577 				printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
1578 					   drive_config.vendor_id,
1579 					   drive_config.product_id,
1580 					   drive_config.product_rev_level);
1581 				printk("  base address %03X, ", sony535_cd_base_io);
1582 				if (tmp_irq > 0)
1583 					printk("IRQ%d, ", tmp_irq);
1584 				printk("using %d byte buffer\n", sony_buffer_size);
1585 
1586 				devfs_register (NULL, CDU535_HANDLE,
1587 						DEVFS_FL_DEFAULT,
1588 						MAJOR_NR, 0,
1589 						S_IFBLK | S_IRUGO | S_IWUGO,
1590 						&cdu_fops, NULL);
1591 				if (devfs_register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) {
1592 					printk("Unable to get major %d for %s\n",
1593 							MAJOR_NR, CDU535_MESSAGE_NAME);
1594 					return -EIO;
1595 				}
1596 				blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1597 				blksize_size[MAJOR_NR] = &sonycd535_block_size;
1598 				read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read-ahead */
1599 
1600 				sony_toc = (struct s535_sony_toc *)
1601 					kmalloc(sizeof *sony_toc, GFP_KERNEL);
1602 				if (sony_toc == NULL) {
1603 					blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1604 					return -ENOMEM;
1605 				}
1606 				last_sony_subcode = (struct s535_sony_subcode *)
1607 					kmalloc(sizeof *last_sony_subcode, GFP_KERNEL);
1608 				if (last_sony_subcode == NULL) {
1609 					blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1610 					kfree(sony_toc);
1611 					return -ENOMEM;
1612 				}
1613 				sony_buffer = (Byte **)
1614 					kmalloc(4 * sony_buffer_sectors, GFP_KERNEL);
1615 				if (sony_buffer == NULL) {
1616 					blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1617 					kfree(sony_toc);
1618 					kfree(last_sony_subcode);
1619 					return -ENOMEM;
1620 				}
1621 				for (i = 0; i < sony_buffer_sectors; i++) {
1622 					sony_buffer[i] =
1623 								(Byte *)kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
1624 					if (sony_buffer[i] == NULL) {
1625 						while (--i>=0)
1626 							kfree(sony_buffer[i]);
1627 						blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1628 						kfree(sony_buffer);
1629 						kfree(sony_toc);
1630 						kfree(last_sony_subcode);
1631 						return -ENOMEM;
1632 					}
1633 				}
1634 				initialized = 1;
1635 			}
1636 		}
1637 	}
1638 
1639 	if (!initialized) {
1640 		printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
1641 		return -EIO;
1642 	}
1643 	request_region(sony535_cd_base_io, 4, CDU535_HANDLE);
1644 	register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &cdu_fops, 0);
1645 	return 0;
1646 }
1647 
1648 #ifndef MODULE
1649 
1650 /*
1651  * accept "kernel command line" parameters
1652  * (added by emoenke@gwdg.de)
1653  *
1654  * use: tell LILO:
1655  *                 sonycd535=0x320
1656  *
1657  * the address value has to be the existing CDROM port address.
1658  */
1659 static int __init
sonycd535_setup(char * strings)1660 sonycd535_setup(char *strings)
1661 {
1662 	int ints[3];
1663 	(void)get_options(strings, ARRAY_SIZE(ints), ints);
1664 	/* if IRQ change and default io base desired,
1665 	 * then call with io base of 0
1666 	 */
1667 	if (ints[0] > 0)
1668 		if (ints[1] != 0)
1669 			sony535_cd_base_io = ints[1];
1670 	if (ints[0] > 1)
1671 		sony535_irq_used = ints[2];
1672 	if ((strings != NULL) && (*strings != '\0'))
1673 		printk(CDU535_MESSAGE_NAME
1674 				": Warning: Unknown interface type: %s\n", strings);
1675 
1676 	return 1;
1677 }
1678 
1679 __setup("sonycd535=", sonycd535_setup);
1680 
1681 #endif /* MODULE */
1682 
1683 void __exit
sony535_exit(void)1684 sony535_exit(void)
1685 {
1686 	int i;
1687 
1688 	release_region(sony535_cd_base_io, 4);
1689 	for (i = 0; i < sony_buffer_sectors; i++)
1690 		kfree(sony_buffer[i]);
1691 	kfree(sony_buffer);
1692 	kfree(last_sony_subcode);
1693 	kfree(sony_toc);
1694 	devfs_unregister(devfs_find_handle(NULL, CDU535_HANDLE, 0, 0,
1695 					   DEVFS_SPECIAL_BLK, 0));
1696 	if (devfs_unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
1697 		printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
1698 	else
1699 		printk(KERN_INFO CDU535_HANDLE " module released\n");
1700 }
1701 
1702 #ifdef MODULE
1703 module_init(sony535_init);
1704 #endif
1705 module_exit(sony535_exit);
1706 
1707 
1708 MODULE_LICENSE("GPL");
1709