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, ¶ms[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