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