OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [cdrom/] [sonycd535.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
790
do_cdu535_request(request_queue_t * q)
791
{
792
        unsigned int dev;
793
        unsigned int read_size;
794
        int  block;
795
        int  nsect;
796
        int  copyoff;
797
        int  spin_up_retry;
798
        Byte params[10];
799
        Byte status[2];
800
        Byte cmd[2];
801
 
802
        while (1) {
803
                /*
804
                 * The beginning here is stolen from the hard disk driver.  I hope
805
                 * it's right.
806
                 */
807
                if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) {
808
                        return;
809
                }
810
                INIT_REQUEST;
811
                dev = MINOR(CURRENT->rq_dev);
812
                block = CURRENT->sector;
813
                nsect = CURRENT->nr_sectors;
814
                if (dev != 0) {
815
                        end_request(0);
816
                        continue;
817
                }
818
                switch (CURRENT->cmd) {
819
                case READ:
820
                        /*
821
                         * If the block address is invalid or the request goes beyond the end of
822
                         * the media, return an error.
823
                         */
824
 
825
                        if (sony_toc->lead_out_start_lba <= (block / 4)) {
826
                                end_request(0);
827
                                return;
828
                        }
829
                        if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
830
                                end_request(0);
831
                                return;
832
                        }
833
                        while (0 < nsect) {
834
                                /*
835
                                 * If the requested sector is not currently in the read-ahead buffer,
836
                                 * it must be read in.
837
                                 */
838
                                if ((block < sony_first_block) || (sony_last_block < block)) {
839
                                        sony_first_block = (block / 4) * 4;
840
                                        log_to_msf(block / 4, params);
841
 
842
                                        /*
843
                                         * If the full read-ahead would go beyond the end of the media, trim
844
                                         * it back to read just till the end of the media.
845
                                         */
846
                                        if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
847
                                                sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
848
                                                read_size = sony_toc->lead_out_start_lba - (block / 4);
849
                                        } else {
850
                                                sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
851
                                                read_size = sony_buffer_sectors;
852
                                        }
853
                                        size_to_buf(read_size, &params[3]);
854
 
855
                                        /*
856
                                         * Read the data.  If the drive was not spinning,
857
                                         * spin it up and try some more.
858
                                         */
859
                                        for (spin_up_retry=0 ;; ++spin_up_retry) {
860
                                                /* This loop has been modified to support the Sony
861
                                                 * CDU-510/515 series, thanks to Claudio Porfiri
862
                                                 * <C.Porfiri@nisms.tei.ericsson.se>.
863
                                                 */
864
                                                /*
865
                                                 * This part is to deal with very slow hardware.  We
866
                                                 * try at most MAX_SPINUP_RETRY times to read the same
867
                                                 * block.  A check for seek_and_read_N_blocks' result is
868
                                                 * performed; if the result is wrong, the CDROM's engine
869
                                                 * is restarted and the operation is tried again.
870
                                                 */
871
                                                /*
872
                                                 * 1995-06-01: The system got problems when downloading
873
                                                 * from Slackware CDROM, the problem seems to be:
874
                                                 * seek_and_read_N_blocks returns BAD_STATUS and we
875
                                                 * should wait for a while before retrying, so a new
876
                                                 * part was added to discriminate the return value from
877
                                                 * seek_and_read_N_blocks for the various cases.
878
                                                 */
879
                                                int readStatus = seek_and_read_N_blocks(params, read_size,
880
                                                                        status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
881
                                                if (0 <= readStatus)     /* Good data; common case, placed first */
882
                                                        break;
883
                                                if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
884
                                                        /* give up */
885
                                                        if (readStatus == NO_ROOM)
886
                                                                printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
887
                                                        else
888
                                                                printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
889
                                                                                status[0]);
890
                                                        sony_first_block = -1;
891
                                                        sony_last_block = -1;
892
                                                        end_request(0);
893
                                                        return;
894
                                                }
895
                                                if (readStatus == BAD_STATUS) {
896
                                                        /* Sleep for a while, then retry */
897
                                                        current->state = TASK_INTERRUPTIBLE;
898
                                                        schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
899
                                                }
900
#if DEBUG > 0
901
                                                printk(CDU535_MESSAGE_NAME
902
                                                        " debug: calling spin up when reading data!\n");
903
#endif
904
                                                cmd[0] = SONY535_SPIN_UP;
905
                                                do_sony_cmd(cmd, 1, status, NULL, 0, 0);
906
                                        }
907
                                }
908
                                /*
909
                                 * The data is in memory now, copy it to the buffer and advance to the
910
                                 * next block to read.
911
                                 */
912
                                copyoff = block - sony_first_block;
913
                                memcpy(CURRENT->buffer,
914
                                           sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
915
 
916
                                block += 1;
917
                                nsect -= 1;
918
                                CURRENT->buffer += 512;
919
                        }
920
 
921
                        end_request(1);
922
                        break;
923
 
924
                case WRITE:
925
                        end_request(0);
926
                        break;
927
 
928
                default:
929
                        panic("Unknown SONY CD cmd");
930
                }
931
        }
932
}
933
 
934
 
935
/*
936
 * Read the table of contents from the drive and set sony_toc_read if
937
 * successful.
938
 */
939
static void
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
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
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
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
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
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
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
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
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
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");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.