root/drivers/block/cdu31a.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_cdu31a_media_change
  2. sony_sleep
  3. is_attention
  4. is_busy
  5. is_data_ready
  6. is_data_requested
  7. is_result_ready
  8. is_param_write_rdy
  9. reset_drive
  10. clear_attention
  11. clear_result_ready
  12. clear_data_ready
  13. clear_param_reg
  14. read_status_register
  15. read_result_register
  16. read_data_register
  17. write_param
  18. write_cmd
  19. set_drive_params
  20. restart_on_error
  21. write_params
  22. get_result
  23. read_data_block
  24. get_data
  25. do_sony_cd_cmd
  26. handle_sony_cd_attention
  27. int_to_bcd
  28. bcd_to_int
  29. log_to_msf
  30. msf_to_log
  31. size_to_buf
  32. do_cdu31a_request
  33. sony_get_toc
  34. find_track
  35. read_subcode
  36. sony_get_subchnl_info
  37. scd_ioctl
  38. scd_open
  39. scd_release
  40. get_drive_configuration
  41. cdu31a_init

   1 /*
   2  * Sony CDU-31A CDROM interface device driver.
   3  *
   4  * Corey Minyard (minyard@wf-rch.cirr.com)
   5  *
   6  * Colossians 3:17
   7  *
   8  * The Sony interface device driver handles Sony interface CDROM
   9  * drives and provides a complete block-level interface as well as an
  10  * ioctl() interface compatible with the Sun (as specified in
  11  * include/linux/cdrom.h).  With this interface, CDROMs can be
  12  * accessed and standard audio CDs can be played back normally.
  13  *
  14  * This interface is (unfortunatly) a polled interface.  This is
  15  * because most Sony interfaces are set up with DMA and interrupts
  16  * disables.  Some (like mine) do not even have the capability to
  17  * handle interrupts or DMA.  For this reason you will see a lot of
  18  * the following:
  19  *
  20  *   retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
  21  *   while ((retry_count > jiffies) && (! <some condition to wait for))
  22  *   {
  23  *      while (handle_sony_cd_attention())
  24  *         ;
  25  *
  26  *      sony_sleep();
  27  *   }
  28  *   if (the condition not met)
  29  *   {
  30  *      return an error;
  31  *   }
  32  *
  33  * This ugly hack waits for something to happen, sleeping a little
  34  * between every try.  it also handles attentions, which are
  35  * asyncronous events from the drive informing the driver that a disk
  36  * has been inserted, removed, etc.
  37  *
  38  * One thing about these drives: They talk in MSF (Minute Second Frame) format.
  39  * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
  40  * disk.  The funny thing is that these are sent to the drive in BCD, but the
  41  * interface wants to see them in decimal.  A lot of conversion goes on.
  42  *
  43  *  Copyright (C) 1993  Corey Minyard
  44  *
  45  *  This program is free software; you can redistribute it and/or modify
  46  *  it under the terms of the GNU General Public License as published by
  47  *  the Free Software Foundation; either version 2 of the License, or
  48  *  (at your option) any later version.
  49  *
  50  *  This program is distributed in the hope that it will be useful,
  51  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  52  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  53  *  GNU General Public License for more details.
  54  *
  55  *  You should have received a copy of the GNU General Public License
  56  *  along with this program; if not, write to the Free Software
  57  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  58  *
  59  */
  60 
  61 
  62 
  63 #include <linux/errno.h>
  64 #include <linux/signal.h>
  65 #include <linux/sched.h>
  66 #include <linux/timer.h>
  67 #include <linux/fs.h>
  68 #include <linux/kernel.h>
  69 #include <linux/hdreg.h>
  70 #include <linux/genhd.h>
  71 #include <linux/ioport.h>
  72 
  73 #include <asm/system.h>
  74 #include <asm/io.h>
  75 #include <asm/segment.h>
  76 
  77 #include <linux/cdrom.h>
  78 #include <linux/cdu31a.h>
  79 
  80 #define MAJOR_NR CDU31A_CDROM_MAJOR
  81 #include "blk.h"
  82 
  83 #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
  84 
  85 static unsigned short cdu31a_addresses[] =
  86 {
  87    0x340,       /* Standard configuration Sony Interface */
  88    0x1f88,      /* Fusion CD-16 */
  89    0x230,       /* SoundBlaster 16 card */
  90    0x360,       /* Secondary standard Sony Interface */
  91    0x320,       /* Secondary standard Sony Interface */
  92    0x330,       /* Secondary standard Sony Interface */
  93    0
  94 };
  95 
  96 
  97 static int handle_sony_cd_attention(void);
  98 static int read_subcode(void);
  99 static void sony_get_toc(void);
 100 static int scd_open(struct inode *inode, struct file *filp);
 101 static void do_sony_cd_cmd(unsigned char cmd,
 102                            unsigned char *params,
 103                            unsigned int num_params,
 104                            unsigned char *result_buffer,
 105                            unsigned int *result_size);
 106 static void size_to_buf(unsigned int size,
 107                         unsigned char *buf);
 108 
 109 
 110 /* The base I/O address of the Sony Interface.  This is a variable (not a
 111    #define) so it can be easily changed via some future ioctl() */
 112 static unsigned short sony_cd_base_io = 0;
 113 
 114 /*
 115  * The following are I/O addresses of the various registers for the drive.  The
 116  * comment for the base address also applies here.
 117  */
 118 static volatile unsigned short sony_cd_cmd_reg;
 119 static volatile unsigned short sony_cd_param_reg;
 120 static volatile unsigned short sony_cd_write_reg;
 121 static volatile unsigned short sony_cd_control_reg;
 122 static volatile unsigned short sony_cd_status_reg;
 123 static volatile unsigned short sony_cd_result_reg;
 124 static volatile unsigned short sony_cd_read_reg;
 125 static volatile unsigned short sony_cd_fifost_reg;
 126 
 127 
 128 static int sony_disc_changed = 1;          /* Has the disk been changed
 129                                               since the last check? */
 130 static int sony_toc_read = 0;              /* Has the table of contents been
 131                                               read? */
 132 static int sony_spun_up = 0;               /* Has the drive been spun up? */
 133 static unsigned int sony_buffer_size;      /* Size in bytes of the read-ahead
 134                                               buffer. */
 135 static unsigned int sony_buffer_sectors;   /* Size (in 2048 byte records) of
 136                                               the read-ahead buffer. */
 137 static unsigned int sony_usage = 0;        /* How many processes have the
 138                                               drive open. */
 139 
 140 static volatile int sony_first_block = -1; /* First OS block (512 byte) in
 141                                               the read-ahead buffer */
 142 static volatile int sony_last_block = -1;  /* Last OS block (512 byte) in
 143                                               the read-ahead buffer */
 144 
 145 static struct s_sony_toc *sony_toc;              /* Points to the table of
 146                                                     contents. */
 147 static struct s_sony_subcode * volatile last_sony_subcode; /* Points to the last
 148                                                     subcode address read */
 149 static unsigned char * volatile sony_buffer;     /* Points to the read-ahead
 150                                                     buffer */
 151 
 152 static volatile int sony_inuse = 0;  /* Is the drive in use?  Only one operation at a time
 153                                         allowed */
 154 
 155 static struct wait_queue * sony_wait = NULL;
 156 
 157 static struct task_struct *has_cd_task = NULL;  /* The task that is currently using the
 158                                                    CDROM drive, or NULL if none. */
 159 
 160 /*
 161  * The audio status uses the values from read subchannel data as specified
 162  * in include/linux/cdrom.h.
 163  */
 164 static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
 165 
 166 /*
 167  * The following are a hack for pausing and resuming audio play.  The drive
 168  * does not work as I would expect it, if you stop it then start it again,
 169  * the drive seeks back to the beginning and starts over.  This holds the
 170  * position during a pause so a resume can restart it.  It uses the
 171  * audio status variable above to tell if it is paused.
 172  */
 173 unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
 174 unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
 175 
 176 /*
 177  * This routine returns 1 if the disk has been changed since the last
 178  * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
 179  */
 180 int
 181 check_cdu31a_media_change(int full_dev, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183    int retval, target;
 184 
 185 
 186    target = MINOR(full_dev);
 187 
 188    if (target > 0) {
 189       printk("Sony CD-ROM request error: invalid device.\n");
 190       return 0;
 191    }
 192 
 193    retval = sony_disc_changed;
 194    if (!flag)
 195    {
 196       sony_disc_changed = 0;
 197    }
 198 
 199    return retval;
 200 }
 201 
 202 
 203 /*
 204  * Wait a little while (used for polling the drive).  If in initialization,
 205  * setting a timeout doesn't work, so just loop for a while.
 206  */
 207 static inline void
 208 sony_sleep(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210    current->state = TASK_INTERRUPTIBLE;
 211    current->timeout = jiffies;
 212    schedule();
 213 }
 214 
 215 
 216 /*
 217  * The following are convenience routine to read various status and set
 218  * various conditions in the drive.
 219  */
 220 static inline int
 221 is_attention(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223    return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
 224 }
 225 
 226 static inline int
 227 is_busy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229    return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
 230 }
 231 
 232 static inline int
 233 is_data_ready(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235    return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
 236 }
 237 
 238 static inline int
 239 is_data_requested(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241    return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
 242 }
 243 
 244 static inline int
 245 is_result_ready(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247    return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
 248 }
 249 
 250 static inline int
 251 is_param_write_rdy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 252 {
 253    return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
 254 }
 255 
 256 static inline void
 257 reset_drive(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 258 {
 259    outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
 260 }
 261 
 262 static inline void
 263 clear_attention(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265    outb(SONY_ATTN_CLR_BIT, sony_cd_control_reg);
 266 }
 267 
 268 static inline void
 269 clear_result_ready(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 270 {
 271    outb(SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
 272 }
 273 
 274 static inline void
 275 clear_data_ready(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277    outb(SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
 278 }
 279 
 280 static inline void
 281 clear_param_reg(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 282 {
 283    outb(SONY_PARAM_CLR_BIT, sony_cd_control_reg);
 284 }
 285 
 286 static inline unsigned char
 287 read_status_register(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 288 {
 289    return(inb(sony_cd_status_reg));
 290 }
 291 
 292 static inline unsigned char
 293 read_result_register(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295    return(inb(sony_cd_result_reg));
 296 }
 297 
 298 static inline unsigned char
 299 read_data_register(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301    return(inb(sony_cd_read_reg));
 302 }
 303 
 304 static inline void
 305 write_param(unsigned char param)
     /* [previous][next][first][last][top][bottom][index][help] */
 306 {
 307    outb(param, sony_cd_param_reg);
 308 }
 309 
 310 static inline void
 311 write_cmd(unsigned char cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313    outb(cmd, sony_cd_cmd_reg);
 314    outb(SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
 315 }
 316 
 317 /*
 318  * Set the drive parameters so the drive will auto-spin-up when a
 319  * disk is inserted.
 320  */
 321 static void
 322 set_drive_params(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 323 {
 324    unsigned char res_reg[2];
 325    unsigned int res_size;
 326    unsigned char params[3];
 327 
 328 
 329    params[0] = SONY_SD_MECH_CONTROL;
 330    params[1] = 0x03;
 331    do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
 332                   params,
 333                   2,
 334                   res_reg,
 335                   &res_size);
 336    if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
 337    {
 338       printk("  Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
 339    }
 340 }
 341 
 342 /*
 343  * This code will reset the drive and attempt to restore sane parameters.
 344  */
 345 static void
 346 restart_on_error(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 347 {
 348    unsigned char res_reg[2];
 349    unsigned int res_size;
 350    unsigned int retry_count;
 351 
 352 
 353    printk("cdu31a: Resetting drive on error\n");
 354    reset_drive();
 355    retry_count = jiffies + SONY_RESET_TIMEOUT;
 356    while ((retry_count > jiffies) && (!is_attention()))
 357    {
 358       sony_sleep();
 359    }
 360    set_drive_params();
 361    do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
 362    if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
 363    {
 364       printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", res_reg[1]);
 365    }
 366 
 367    current->state = TASK_INTERRUPTIBLE;
 368    current->timeout = jiffies + 200;
 369    schedule();
 370 
 371    do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
 372    if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
 373    {
 374       printk("cdu31a: Unable to read TOC: 0x%2.2x\n", res_reg[1]);
 375    }
 376    sony_get_toc();
 377    if (!sony_toc_read)
 378    {
 379       printk("cdu31a: Unable to get TOC data\n");
 380    }
 381 }
 382 
 383 /*
 384  * This routine writes data to the parameter register.  Since this should
 385  * happen fairly fast, it is polled with no OS waits between.
 386  */
 387 static int
 388 write_params(unsigned char *params,
     /* [previous][next][first][last][top][bottom][index][help] */
 389              int num_params)
 390 {
 391    unsigned int retry_count;
 392 
 393 
 394    retry_count = SONY_READY_RETRIES;
 395    while ((retry_count > 0) && (!is_param_write_rdy()))
 396    {
 397       retry_count--;
 398    }
 399    if (!is_param_write_rdy())
 400    {
 401       return -EIO;
 402    }
 403 
 404    while (num_params > 0)
 405    {
 406       write_param(*params);
 407       params++;
 408       num_params--;
 409    }
 410 
 411    return 0;
 412 }
 413 
 414 
 415 /*
 416  * The following reads data from the command result register.  It is a
 417  * fairly complex routine, all status info flows back through this
 418  * interface.  The algorithm is stolen directly from the flowcharts in
 419  * the drive manual.
 420  */
 421 static void
 422 get_result(unsigned char *result_buffer,
     /* [previous][next][first][last][top][bottom][index][help] */
 423            unsigned int *result_size)
 424 {
 425    unsigned char a, b;
 426    int i;
 427    unsigned int retry_count;
 428 
 429 
 430    while (handle_sony_cd_attention())
 431       ;
 432    /* Wait for the result data to be ready */
 433    retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
 434    while ((retry_count > jiffies) && (is_busy() || (!(is_result_ready()))))
 435    {
 436       sony_sleep();
 437 
 438       while (handle_sony_cd_attention())
 439          ;
 440    }
 441    if (is_busy() || (!(is_result_ready())))
 442    {
 443       result_buffer[0] = 0x20;
 444       result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 445       *result_size = 2;
 446       return;
 447    }
 448 
 449    /*
 450     * Get the first two bytes.  This determines what else needs
 451     * to be done.
 452     */
 453    clear_result_ready();
 454    a = read_result_register();
 455    *result_buffer = a;
 456    result_buffer++;
 457    b = read_result_register();
 458    *result_buffer = b;
 459    result_buffer++;
 460    *result_size = 2;
 461 
 462    /*
 463     * 0x20 means an error occured.  Byte 2 will have the error code.
 464     * Otherwise, the command succeded, byte 2 will have the count of
 465     * how many more status bytes are coming.
 466     *
 467     * The result register can be read 10 bytes at a time, a wait for
 468     * result ready to be asserted must be done between every 10 bytes.
 469     */
 470    if ((a & 0xf0) != 0x20)
 471    {
 472       if (b > 8)
 473       {
 474          for (i=0; i<8; i++)
 475          {
 476             *result_buffer = read_result_register();
 477             result_buffer++;
 478             (*result_size)++;
 479          }
 480          b = b - 8;
 481 
 482          while (b > 10)
 483          {
 484             retry_count = SONY_READY_RETRIES;
 485             while ((retry_count > 0) && (!is_result_ready()))
 486             {
 487                retry_count--;
 488             }
 489             if (!is_result_ready())
 490             {
 491                result_buffer[0] = 0x20;
 492                result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 493                *result_size = 2;
 494                return;
 495             }
 496 
 497             clear_result_ready();
 498                                 
 499             for (i=0; i<10; i++)
 500             {
 501                *result_buffer = read_result_register();
 502                result_buffer++;
 503                (*result_size)++;
 504             }
 505             b = b - 10;
 506          }
 507 
 508          if (b > 0)
 509          {
 510             retry_count = SONY_READY_RETRIES;
 511             while ((retry_count > 0) && (!is_result_ready()))
 512             {
 513                retry_count--;
 514             }
 515             if (!is_result_ready())
 516             {
 517                result_buffer[0] = 0x20;
 518                result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 519                *result_size = 2;
 520                return;
 521             }
 522          }
 523       }
 524 
 525       while (b > 0)
 526       {
 527          *result_buffer = read_result_register();
 528          result_buffer++;
 529          (*result_size)++;
 530          b--;
 531       }
 532    }
 533 }
 534 
 535 /*
 536  * Read in a 2048 byte block of data.
 537  */
 538 static void
 539 read_data_block(unsigned char *data,
     /* [previous][next][first][last][top][bottom][index][help] */
 540                 unsigned char *result_buffer,
 541                 unsigned int  *result_size)
 542 {
 543    int i;
 544    unsigned int retry_count;
 545 
 546    for (i=0; i<2048; i++)
 547    {
 548       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
 549       while ((retry_count > jiffies) && (!is_data_requested()))
 550       {
 551          while (handle_sony_cd_attention())
 552             ;
 553          
 554          sony_sleep();
 555       }
 556       if (!is_data_requested())
 557       {
 558          result_buffer[0] = 0x20;
 559          result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 560          *result_size = 2;
 561          return;
 562       }
 563       
 564       *data = read_data_register();
 565       data++;
 566    }
 567 }
 568 
 569 /*
 570  * This routine issues a read data command and gets the data.  I don't
 571  * really like the way this is done (I would prefer for do_sony_cmd() to
 572  * handle it automatically) but I found that the drive returns status
 573  * when it finishes reading (not when the host has read all the data)
 574  * or after it gets an error.  This means that the status can be
 575  * received at any time and should be handled immediately (at least
 576  * between every 2048 byte block) to check for errors, we can't wait
 577  * until all the data is read.
 578  *
 579  * This routine returns the total number of sectors read.  It will
 580  * not return an error if it reads at least one sector successfully.
 581  */
 582 static unsigned int
 583 get_data(unsigned char *orig_data,
     /* [previous][next][first][last][top][bottom][index][help] */
 584          unsigned char *params,         /* 6 bytes with the MSF start address
 585                                            and number of sectors to read. */
 586          unsigned int orig_data_size,
 587          unsigned char *result_buffer,
 588          unsigned int *result_size)
 589 {
 590    unsigned int cur_offset;
 591    unsigned int retry_count;
 592    int result_read;
 593    int num_retries;
 594    unsigned int num_sectors_read = 0;
 595    unsigned char *data = orig_data;
 596    unsigned int data_size = orig_data_size;
 597 
 598 
 599    cli();
 600    while (sony_inuse)
 601    {
 602       interruptible_sleep_on(&sony_wait);
 603       if (current->signal & ~current->blocked)
 604       {
 605          result_buffer[0] = 0x20;
 606          result_buffer[1] = SONY_SIGNAL_OP_ERR;
 607          *result_size = 2;
 608          return 0;
 609       }
 610    }
 611    sony_inuse = 1;
 612    has_cd_task = current;
 613    sti();
 614 
 615    num_retries = 0;
 616 retry_data_operation:
 617    result_buffer[0] = 0;
 618    result_buffer[1] = 0;
 619 
 620    /*
 621     * Clear any outstanding attentions and wait for the drive to
 622     * complete any pending operations.
 623     */
 624    while (handle_sony_cd_attention())
 625       ;
 626 
 627    retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
 628    while ((retry_count > jiffies) && (is_busy()))
 629    {
 630       sony_sleep();
 631       
 632       while (handle_sony_cd_attention())
 633          ;
 634    }
 635 
 636    if (is_busy())
 637    {
 638       result_buffer[0] = 0x20;
 639       result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 640       *result_size = 2;
 641    }
 642    else
 643    {
 644       /* Issue the command */
 645       clear_result_ready();
 646       clear_param_reg();
 647 
 648       write_params(params, 6);
 649       write_cmd(SONY_READ_CMD);
 650 
 651       /*
 652        * Read the data from the drive one 2048 byte sector at a time.  Handle
 653        * any results received between sectors, if an error result is returned
 654        * terminate the operation immediately.
 655        */
 656       cur_offset = 0;
 657       result_read = 0;
 658       while ((data_size > 0) && (result_buffer[0] == 0))
 659       {
 660          /* Wait for the drive to tell us we have something */
 661          retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
 662          while ((retry_count > jiffies) && (!(is_result_ready() || is_data_ready())))
 663          {
 664             while (handle_sony_cd_attention())
 665                ;
 666 
 667             sony_sleep();
 668          }
 669          if (!(is_result_ready() || is_data_ready()))
 670          {
 671             result_buffer[0] = 0x20;
 672             result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 673             *result_size = 2;
 674          }
 675       
 676          /* Handle results first */
 677          else if (is_result_ready())
 678          {
 679             result_read = 1;
 680             get_result(result_buffer, result_size);
 681          }
 682          else /* Handle data next */
 683          {
 684             /*
 685              * The drive has to be polled for status on a byte-by-byte basis
 686              * to know if the data is ready.  Yuck.  I really wish I could use DMA.
 687              */
 688             clear_data_ready();
 689             read_data_block(data, result_buffer, result_size);
 690             data += 2048;
 691             data_size -= 2048;
 692             cur_offset = cur_offset + 2048;
 693             num_sectors_read++;
 694          }
 695       }
 696 
 697       /* Make sure the result has been read */
 698       if (!result_read)
 699       {
 700          get_result(result_buffer, result_size);
 701       }
 702    }
 703 
 704    if (   ((result_buffer[0] & 0x20) == 0x20)
 705        && (result_buffer[1] != SONY_NOT_SPIN_ERR) /* No retry when not spin */
 706        && (num_retries < MAX_CDU31A_RETRIES))
 707    {
 708       /*
 709        * If an error occurs, go back and only read one sector at the
 710        * given location.  Hopefully the error occurred on an unused
 711        * sector after the first one.  It is hard to say which sector
 712        * the error occurred on because the drive returns status before
 713        * the data transfer is finished and doesn't say which sector.
 714        */
 715       data_size = 2048;
 716       data = orig_data;
 717       num_sectors_read = 0;
 718       size_to_buf(1, &params[3]);
 719 
 720       num_retries++;
 721       /* Issue a reset on an error (the second time), othersize just delay */
 722       if (num_retries == 2)
 723       {
 724          restart_on_error();
 725       }
 726       else
 727       {
 728          current->state = TASK_INTERRUPTIBLE;
 729          current->timeout = jiffies + 10;
 730          schedule();
 731       }
 732 
 733       /* Restart the operation. */
 734       goto retry_data_operation;
 735    }
 736 
 737    has_cd_task = NULL;
 738    sony_inuse = 0;
 739    wake_up_interruptible(&sony_wait);
 740 
 741    return(num_sectors_read);
 742 }
 743 
 744 
 745 /*
 746  * Do a command that does not involve data transfer.  This routine must
 747  * be re-entrant from the same task to support being called from the
 748  * data operation code when an error occurs.
 749  */
 750 static void
 751 do_sony_cd_cmd(unsigned char cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 752                unsigned char *params,
 753                unsigned int num_params,
 754                unsigned char *result_buffer,
 755                unsigned int *result_size)
 756 {
 757    unsigned int retry_count;
 758    int num_retries;
 759    int recursive_call;
 760 
 761 
 762    cli();
 763    if (current != has_cd_task) /* Allow recursive calls to this routine */
 764    {
 765       while (sony_inuse)
 766       {
 767          interruptible_sleep_on(&sony_wait);
 768          if (current->signal & ~current->blocked)
 769          {
 770             result_buffer[0] = 0x20;
 771             result_buffer[1] = SONY_SIGNAL_OP_ERR;
 772             *result_size = 2;
 773             return;
 774          }
 775       }
 776       sony_inuse = 1;
 777       has_cd_task = current;
 778       recursive_call = 0;
 779    }
 780    else
 781    {
 782       recursive_call = 1;
 783    }
 784    sti();
 785 
 786    num_retries = 0;
 787 retry_cd_operation:
 788 
 789    while (handle_sony_cd_attention())
 790       ;
 791    
 792    retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
 793    while ((retry_count > jiffies) && (is_busy()))
 794    {
 795       sony_sleep();
 796       
 797       while (handle_sony_cd_attention())
 798          ;
 799    }
 800    if (is_busy())
 801    {
 802       result_buffer[0] = 0x20;
 803       result_buffer[1] = SONY_TIMEOUT_OP_ERR;
 804       *result_size = 2;
 805    }
 806    else
 807    {
 808       clear_result_ready();
 809       clear_param_reg();
 810 
 811       write_params(params, num_params);
 812       write_cmd(cmd);
 813 
 814       get_result(result_buffer, result_size);
 815    }
 816 
 817    if (   ((result_buffer[0] & 0x20) == 0x20)
 818        && (num_retries < MAX_CDU31A_RETRIES))
 819    {
 820       num_retries++;
 821       current->state = TASK_INTERRUPTIBLE;
 822       current->timeout = jiffies + 10; /* Wait .1 seconds on retries */
 823       schedule();
 824       goto retry_cd_operation;
 825    }
 826 
 827    if (!recursive_call)
 828    {
 829       has_cd_task = NULL;
 830       sony_inuse = 0;
 831       wake_up_interruptible(&sony_wait);
 832    }
 833 }
 834 
 835 
 836 /*
 837  * Handle an attention from the drive.  This will return 1 if it found one
 838  * or 0 if not (if one is found, the caller might want to call again).
 839  *
 840  * This routine counts the number of consecutive times it is called
 841  * (since this is always called from a while loop until it returns
 842  * a 0), and returns a 0 if it happens too many times.  This will help
 843  * prevent a lockup.
 844  */
 845 static int
 846 handle_sony_cd_attention(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 847 {
 848    unsigned char atten_code;
 849    static int num_consecutive_attentions = 0;
 850 
 851 
 852    if (is_attention())
 853    {
 854       if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
 855       {
 856          printk("cdu31a: Too many consecutive attentions: %d\n",
 857                 num_consecutive_attentions);
 858          num_consecutive_attentions = 0;
 859          return(0);
 860       }
 861 
 862       clear_attention();
 863       atten_code = read_result_register();
 864 
 865       switch (atten_code)
 866       {
 867        /* Someone changed the CD.  Mark it as changed */
 868       case SONY_MECH_LOADED_ATTN:
 869          sony_disc_changed = 1;
 870          sony_toc_read = 0;
 871          sony_audio_status = CDROM_AUDIO_NO_STATUS;
 872          sony_first_block = -1;
 873          sony_last_block = -1;
 874          break;
 875 
 876       case SONY_AUDIO_PLAY_DONE_ATTN:
 877          sony_audio_status = CDROM_AUDIO_COMPLETED;
 878          read_subcode();
 879          break;
 880 
 881       case SONY_EJECT_PUSHED_ATTN:
 882          sony_audio_status = CDROM_AUDIO_INVALID;
 883          break;
 884 
 885       case SONY_LEAD_IN_ERR_ATTN:
 886       case SONY_LEAD_OUT_ERR_ATTN:
 887       case SONY_DATA_TRACK_ERR_ATTN:
 888       case SONY_AUDIO_PLAYBACK_ERR_ATTN:
 889          sony_audio_status = CDROM_AUDIO_ERROR;
 890          break;
 891       }
 892 
 893       num_consecutive_attentions++;
 894       return(1);
 895    }
 896 
 897    num_consecutive_attentions = 0;
 898    return(0);
 899 }
 900 
 901 
 902 /* Convert from an integer 0-99 to BCD */
 903 static inline unsigned int
 904 int_to_bcd(unsigned int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 905 {
 906    int retval;
 907 
 908 
 909    retval = (val / 10) << 4;
 910    retval = retval | val % 10;
 911    return(retval);
 912 }
 913 
 914 
 915 /* Convert from BCD to an integer from 0-99 */
 916 static unsigned int
 917 bcd_to_int(unsigned int bcd)
     /* [previous][next][first][last][top][bottom][index][help] */
 918 {
 919    return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
 920 }
 921 
 922 
 923 /*
 924  * Convert a logical sector value (like the OS would want to use for
 925  * a block device) to an MSF format.
 926  */
 927 static void
 928 log_to_msf(unsigned int log, unsigned char *msf)
     /* [previous][next][first][last][top][bottom][index][help] */
 929 {
 930    log = log + LOG_START_OFFSET;
 931    msf[0] = int_to_bcd(log / 4500);
 932    log = log % 4500;
 933    msf[1] = int_to_bcd(log / 75);
 934    msf[2] = int_to_bcd(log % 75);
 935 }
 936 
 937 
 938 /*
 939  * Convert an MSF format to a logical sector.
 940  */
 941 static unsigned int
 942 msf_to_log(unsigned char *msf)
     /* [previous][next][first][last][top][bottom][index][help] */
 943 {
 944    unsigned int log;
 945 
 946 
 947    log = bcd_to_int(msf[2]);
 948    log += bcd_to_int(msf[1]) * 75;
 949    log += bcd_to_int(msf[0]) * 4500;
 950    log = log - LOG_START_OFFSET;
 951 
 952    return log;
 953 }
 954 
 955 
 956 /*
 957  * Take in integer size value and put it into a buffer like
 958  * the drive would want to see a number-of-sector value.
 959  */
 960 static void
 961 size_to_buf(unsigned int size,
     /* [previous][next][first][last][top][bottom][index][help] */
 962             unsigned char *buf)
 963 {
 964    buf[0] = size / 65536;
 965    size = size % 65536;
 966    buf[1] = size / 256;
 967    buf[2] = size % 256;
 968 }
 969 
 970 
 971 /*
 972  * The OS calls this to perform a read or write operation to the drive.
 973  * Write obviously fail.  Reads to a read ahead of sony_buffer_size
 974  * bytes to help speed operations.  This especially helps since the OS
 975  * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
 976  * data access on a CD is done sequentially, this saves a lot of operations.
 977  */
 978 static void
 979 do_cdu31a_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 980 {
 981    int block;
 982    unsigned int dev;
 983    int nsect;
 984    unsigned char params[10];
 985    unsigned char res_reg[2];
 986    unsigned int res_size;
 987    int copyoff;
 988    int spin_up_retry;
 989    unsigned int read_size;
 990 
 991 
 992    if (!sony_spun_up)
 993    {
 994       scd_open (NULL,NULL);
 995    }
 996 
 997    while (1)
 998    {
 999 cdu31a_request_startover:
1000       /*
1001        * The beginning here is stolen from the hard disk driver.  I hope
1002        * its right.
1003        */
1004       if (!(CURRENT) || CURRENT->dev < 0)
1005       {
1006          return;
1007       }
1008 
1009       INIT_REQUEST;
1010       dev = MINOR(CURRENT->dev);
1011       block = CURRENT->sector;
1012       nsect = CURRENT->nr_sectors;
1013       if (dev != 0)
1014       {
1015          end_request(0);
1016          goto cdu31a_request_startover;
1017       }
1018 
1019       switch(CURRENT->cmd)
1020       {
1021       case READ:
1022          /*
1023           * If the block address is invalid or the request goes beyond the end of
1024           * the media, return an error.
1025           */
1026          if ((block / 4) >= sony_toc->lead_out_start_lba)
1027          {
1028             end_request(0);
1029             goto cdu31a_request_startover;
1030          }
1031          if (((block + nsect) / 4) >= sony_toc->lead_out_start_lba)
1032          {
1033             end_request(0);
1034             goto cdu31a_request_startover;
1035          }
1036 
1037          while (nsect > 0)
1038          {
1039             /*
1040              * If the requested sector is not currently in the read-ahead buffer,
1041              * it must be read in.
1042              */
1043             if ((block < sony_first_block) || (block > sony_last_block))
1044             {
1045                sony_first_block = (block / 4) * 4;
1046                log_to_msf(block/4, params);
1047 
1048                /*
1049                 * If the full read-ahead would go beyond the end of the media, trim
1050                 * it back to read just till the end of the media.
1051                 */
1052                if (((block / 4) + sony_buffer_sectors) >= sony_toc->lead_out_start_lba)
1053                {
1054                   read_size = sony_toc->lead_out_start_lba - (block / 4);
1055                }
1056                else
1057                {
1058                   read_size = sony_buffer_sectors;
1059                }
1060                size_to_buf(read_size, &params[3]);
1061 
1062                /*
1063                 * Read the data.  If the drive was not spinning, spin it up and try
1064                 * once more.  I know, the goto is ugly, but I am too lazy to fix it.
1065                 */
1066                spin_up_retry = 0;
1067 try_read_again:
1068                sony_last_block =   sony_first_block
1069                                  + (get_data(sony_buffer,
1070                                              params,
1071                                              (read_size * 2048),
1072                                              res_reg,
1073                                              &res_size) * 4) - 1;
1074                if ((res_size < 2) || (res_reg[0] != 0))
1075                {
1076                   if ((res_reg[1] == SONY_NOT_SPIN_ERR) && (!spin_up_retry))
1077                   {
1078                      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1079                      spin_up_retry = 1;
1080                      goto try_read_again;
1081                   }
1082 
1083                   printk("Sony CDROM Read error: 0x%2.2x\n", res_reg[1]);
1084                   sony_first_block = -1;
1085                   sony_last_block = -1;
1086                   end_request(0);
1087                   goto cdu31a_request_startover;
1088                }
1089             }
1090    
1091             /*
1092              * The data is in memory now, copy it to the buffer and advance to the
1093              * next block to read.
1094              */
1095             copyoff = (block - sony_first_block) * 512;
1096             memcpy(CURRENT->buffer, sony_buffer+copyoff, 512);
1097                
1098             block += 1;
1099             nsect -= 1;
1100             CURRENT->buffer += 512;
1101          }
1102                
1103          end_request(1);
1104          break;
1105             
1106       case WRITE:
1107          end_request(0);
1108          break;
1109             
1110       default:
1111          panic("Unkown SONY CD cmd");
1112       }
1113    }
1114 }
1115 
1116 
1117 /*
1118  * Read the table of contents from the drive and set sony_toc_read if
1119  * successful.
1120  */
1121 static void
1122 sony_get_toc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1123 {
1124    unsigned int res_size;
1125 
1126 
1127    if (!sony_toc_read)
1128    {
1129       do_sony_cd_cmd(SONY_REQ_TOC_DATA_CMD,
1130                      NULL,
1131                      0, 
1132                      (unsigned char *) sony_toc, 
1133                      &res_size);
1134       if ((res_size < 2) || ((sony_toc->exec_status[0] & 0x20) == 0x20))
1135       {
1136          return;
1137       }
1138       sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
1139       sony_toc_read = 1;
1140    }
1141 }
1142 
1143 
1144 /*
1145  * Search for a specific track in the table of contents.
1146  */
1147 static int
1148 find_track(int track)
     /* [previous][next][first][last][top][bottom][index][help] */
1149 {
1150    int i;
1151    int num_tracks;
1152 
1153 
1154    num_tracks = sony_toc->last_track_num + sony_toc->first_track_num + 1;
1155    for (i = 0; i < num_tracks; i++)
1156    {
1157       if (sony_toc->tracks[i].track == track)
1158       {
1159          return i;
1160       }
1161    }
1162 
1163    return -1;
1164 }
1165 
1166 
1167 /*
1168  * Read the subcode and put it int last_sony_subcode for future use.
1169  */
1170 static int
1171 read_subcode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1172 {
1173    unsigned int res_size;
1174 
1175 
1176    do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
1177                   NULL,
1178                   0, 
1179                   (unsigned char *) last_sony_subcode, 
1180                   &res_size);
1181    if ((res_size < 2) || ((last_sony_subcode->exec_status[0] & 0x20) == 0x20))
1182    {
1183       printk("Sony CDROM error 0x%2.2x (read_subcode)\n",
1184              last_sony_subcode->exec_status[1]);
1185       return -EIO;
1186    }
1187 
1188    return 0;
1189 }
1190 
1191 
1192 /*
1193  * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
1194  * the drive is playing, the subchannel needs to be read (since it would be
1195  * changing).  If the drive is paused or completed, the subcode information has
1196  * already been stored, just use that.  The ioctl call wants things in decimal
1197  * (not BCD), so all the conversions are done.
1198  */
1199 static int
1200 sony_get_subchnl_info(long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1201 {
1202    struct cdrom_subchnl schi;
1203 
1204 
1205    /* Get attention stuff */
1206    while (handle_sony_cd_attention())
1207       ;
1208 
1209    sony_get_toc();
1210    if (!sony_toc_read)
1211    {
1212       return -EIO;
1213    }
1214 
1215    verify_area(VERIFY_READ, (char *) arg, sizeof(schi));
1216    verify_area(VERIFY_WRITE, (char *) arg, sizeof(schi));
1217 
1218    memcpy_fromfs(&schi, (char *) arg, sizeof(schi));
1219    
1220    switch (sony_audio_status)
1221    {
1222    case CDROM_AUDIO_PLAY:
1223       if (read_subcode() < 0)
1224       {
1225          return -EIO;
1226       }
1227       break;
1228 
1229    case CDROM_AUDIO_PAUSED:
1230    case CDROM_AUDIO_COMPLETED:
1231       break;
1232 
1233    case CDROM_AUDIO_NO_STATUS:
1234       schi.cdsc_audiostatus = sony_audio_status;
1235       memcpy_tofs((char *) arg, &schi, sizeof(schi));
1236       return 0;
1237       break;
1238 
1239    case CDROM_AUDIO_INVALID:
1240    case CDROM_AUDIO_ERROR:
1241    default:
1242       return -EIO;
1243    }
1244 
1245    schi.cdsc_audiostatus = sony_audio_status;
1246    schi.cdsc_adr = last_sony_subcode->address;
1247    schi.cdsc_ctrl = last_sony_subcode->control;
1248    schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
1249    schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
1250    if (schi.cdsc_format == CDROM_MSF)
1251    {
1252       schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
1253       schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
1254       schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
1255 
1256       schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
1257       schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
1258       schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
1259    }
1260    else if (schi.cdsc_format == CDROM_LBA)
1261    {
1262       schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
1263       schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
1264    }
1265    
1266    memcpy_tofs((char *) arg, &schi, sizeof(schi));
1267    return 0;
1268 }
1269 
1270 
1271 /*
1272  * The big ugly ioctl handler.
1273  */
1274 static int
1275 scd_ioctl(struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
1276           struct file  *file,
1277           unsigned int  cmd,
1278           unsigned long arg)
1279 {
1280    unsigned int dev;
1281    unsigned char res_reg[2];
1282    unsigned int res_size;
1283    unsigned char params[7];
1284    int i;
1285 
1286 
1287    if (!inode)
1288    {
1289       return -EINVAL;
1290    }
1291    dev = MINOR(inode->i_rdev) >> 6;
1292    if (dev != 0)
1293    {
1294       return -EINVAL;
1295    }
1296 
1297    switch (cmd)
1298    {
1299    case CDROMSTART:     /* Spin up the drive */
1300       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1301       if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1302       {
1303          printk("Sony CDROM error 0x%2.2x (CDROMSTART)\n", res_reg[1]);
1304          return -EIO;
1305       }
1306       return 0;
1307       break;
1308       
1309    case CDROMSTOP:      /* Spin down the drive */
1310       do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1311 
1312       /*
1313        * Spin the drive down, ignoring the error if the disk was
1314        * already not spinning.
1315        */
1316       sony_audio_status = CDROM_AUDIO_NO_STATUS;
1317       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1318       if (   ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1319           && (res_reg[1] != SONY_NOT_SPIN_ERR))
1320       {
1321          printk("Sony CDROM error 0x%2.2x (CDROMSTOP)\n", res_reg[1]);
1322          return -EIO;
1323       }
1324       
1325       return 0;
1326       break;
1327 
1328    case CDROMPAUSE:     /* Pause the drive */
1329       do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1330       if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1331       {
1332          printk("Sony CDROM error 0x%2.2x (CDROMPAUSE)\n", res_reg[1]);
1333          return -EIO;
1334       }
1335 
1336       /* Get the current position and save it for resuming */
1337       if (read_subcode() < 0)
1338       {
1339          return -EIO;
1340       }
1341       cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1342       cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1343       cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1344       sony_audio_status = CDROM_AUDIO_PAUSED;
1345       return 0;
1346       break;
1347 
1348    case CDROMRESUME:    /* Start the drive after being paused */
1349       if (sony_audio_status != CDROM_AUDIO_PAUSED)
1350       {
1351          return -EINVAL;
1352       }
1353       
1354       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1355       
1356       /* Start the drive at the saved position. */
1357       params[1] = cur_pos_msf[0];
1358       params[2] = cur_pos_msf[1];
1359       params[3] = cur_pos_msf[2];
1360       params[4] = final_pos_msf[0];
1361       params[5] = final_pos_msf[1];
1362       params[6] = final_pos_msf[2];
1363       params[0] = 0x03;
1364       do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1365       if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1366       {
1367          printk("Sony CDROM error 0x%2.2x (CDROMRESUME)\n", res_reg[1]);
1368          return -EIO;
1369       }
1370       sony_audio_status = CDROM_AUDIO_PLAY;
1371       return 0;
1372       break;
1373 
1374    case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
1375       verify_area(VERIFY_READ, (char *) arg, 6);
1376       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1377       memcpy_fromfs(&(params[1]), (void *) arg, 6);
1378       
1379       /* The parameters are given in int, must be converted */
1380       for (i=1; i<7; i++)
1381       {
1382          params[i] = int_to_bcd(params[i]);
1383       }
1384       params[0] = 0x03;
1385       do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1386       if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1387       {
1388          printk("Sony CDROM error 0x%2.2x (CDROMPLAYMSF)\n", res_reg[1]);
1389          return -EIO;
1390       }
1391       
1392       /* Save the final position for pauses and resumes */
1393       final_pos_msf[0] = params[4];
1394       final_pos_msf[1] = params[5];
1395       final_pos_msf[2] = params[6];
1396       sony_audio_status = CDROM_AUDIO_PLAY;
1397       return 0;
1398       break;
1399 
1400    case CDROMREADTOCHDR:        /* Read the table of contents header */
1401       {
1402          struct cdrom_tochdr *hdr;
1403          struct cdrom_tochdr loc_hdr;
1404          
1405          sony_get_toc();
1406          if (!sony_toc_read)
1407          {
1408             return -EIO;
1409          }
1410          
1411          hdr = (struct cdrom_tochdr *) arg;
1412          verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
1413          loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1414          loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1415          memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
1416       }
1417       return 0;
1418       break;
1419 
1420    case CDROMREADTOCENTRY:      /* Read a given table of contents entry */
1421       {
1422          struct cdrom_tocentry *entry;
1423          struct cdrom_tocentry loc_entry;
1424          int track_idx;
1425          unsigned char *msf_val = NULL;
1426          
1427          sony_get_toc();
1428          if (!sony_toc_read)
1429          {
1430             return -EIO;
1431          }
1432          
1433          entry = (struct cdrom_tocentry *) arg;
1434          verify_area(VERIFY_READ, entry, sizeof(*entry));
1435          verify_area(VERIFY_WRITE, entry, sizeof(*entry));
1436          
1437          memcpy_fromfs(&loc_entry, entry, sizeof(loc_entry));
1438          
1439          /* Lead out is handled separately since it is special. */
1440          if (loc_entry.cdte_track == CDROM_LEADOUT)
1441          {
1442             loc_entry.cdte_adr = sony_toc->address2;
1443             loc_entry.cdte_ctrl = sony_toc->control2;
1444             msf_val = sony_toc->lead_out_start_msf;
1445          }
1446          else
1447          {
1448             track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1449             if (track_idx < 0)
1450             {
1451                return -EINVAL;
1452             }
1453             
1454             loc_entry.cdte_adr = sony_toc->tracks[track_idx].address;
1455             loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1456             msf_val = sony_toc->tracks[track_idx].track_start_msf;
1457          }
1458          
1459          /* Logical buffer address or MSF format requested? */
1460          if (loc_entry.cdte_format == CDROM_LBA)
1461          {
1462             loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1463          }
1464          else if (loc_entry.cdte_format == CDROM_MSF)
1465          {
1466             loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1467             loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val+1));
1468             loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val+2));
1469          }
1470          memcpy_tofs(entry, &loc_entry, sizeof(*entry));
1471       }
1472       return 0;
1473       break;
1474 
1475    case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
1476       {
1477          struct cdrom_ti ti;
1478          int track_idx;
1479          
1480          sony_get_toc();
1481          if (!sony_toc_read)
1482          {
1483             return -EIO;
1484          }
1485          
1486          verify_area(VERIFY_READ, (char *) arg, sizeof(ti));
1487          
1488          memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
1489          if (   (ti.cdti_trk0 < sony_toc->first_track_num)
1490              || (ti.cdti_trk0 > sony_toc->last_track_num)
1491              || (ti.cdti_trk1 < ti.cdti_trk0))
1492          {
1493             return -EINVAL;
1494          }
1495          
1496          track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1497          if (track_idx < 0)
1498          {
1499             return -EINVAL;
1500          }
1501          params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1502          params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1503          params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1504          
1505          /*
1506           * If we want to stop after the last track, use the lead-out
1507           * MSF to do that.
1508           */
1509          if (ti.cdti_trk1 >= bcd_to_int(sony_toc->last_track_num))
1510          {
1511             log_to_msf(msf_to_log(sony_toc->lead_out_start_msf)-1,
1512                        &(params[4]));
1513          }
1514          else
1515          {
1516             track_idx = find_track(int_to_bcd(ti.cdti_trk1+1));
1517             if (track_idx < 0)
1518             {
1519                return -EINVAL;
1520             }
1521             log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf)-1,
1522                        &(params[4]));
1523          }
1524          params[0] = 0x03;
1525          
1526          do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1527          
1528          do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
1529          if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1530          {
1531             printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
1532                    params[2], params[3], params[4], params[5], params[6]);
1533             printk("Sony CDROM error 0x%2.2x (CDROMPLAYTRKIND\n", res_reg[1]);
1534             return -EIO;
1535          }
1536          
1537          /* Save the final position for pauses and resumes */
1538          final_pos_msf[0] = params[4];
1539          final_pos_msf[1] = params[5];
1540          final_pos_msf[2] = params[6];
1541          sony_audio_status = CDROM_AUDIO_PLAY;
1542          return 0;
1543       }
1544      
1545    case CDROMSUBCHNL:   /* Get subchannel info */
1546       return sony_get_subchnl_info(arg);
1547 
1548    case CDROMVOLCTRL:   /* Volume control.  What volume does this change, anyway? */
1549       {
1550          struct cdrom_volctrl volctrl;
1551          
1552          verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
1553          
1554          memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
1555          params[0] = SONY_SD_AUDIO_VOLUME;
1556          params[1] = volctrl.channel0;
1557          params[2] = volctrl.channel1;
1558          do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
1559          if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1560          {
1561             printk("Sony CDROM error 0x%2.2x (CDROMVOLCTRL)\n", res_reg[1]);
1562             return -EIO;
1563          }
1564       }
1565       return 0;
1566 
1567    case CDROMEJECT:     /* Eject the drive */
1568       do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
1569       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1570 
1571       sony_audio_status = CDROM_AUDIO_INVALID;
1572       do_sony_cd_cmd(SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
1573       if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
1574       {
1575          printk("Sony CDROM error 0x%2.2x (CDROMEJECT)\n", res_reg[1]);
1576          return -EIO;
1577       }
1578       return 0;
1579       break;
1580      
1581    default:
1582       return -EINVAL;
1583    }
1584 }
1585 
1586 
1587 /*
1588  * Open the drive for operations.  Spin the drive up and read the table of
1589  * contents if these have not already been done.
1590  */
1591 static int
1592 scd_open(struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
1593          struct file *filp)
1594 {
1595    unsigned char res_reg[2];
1596    unsigned int res_size;
1597    int num_spin_ups;
1598 
1599 
1600    if (!sony_spun_up)
1601    {
1602       num_spin_ups = 0;
1603 
1604 respinup_on_open:
1605       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
1606 
1607       /* The drive sometimes returns error 0.  I don't know why, but ignore
1608          it.  It seems to mean the drive has already done the operation. */
1609       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1610       {
1611          printk("Sony CDROM error 0x%2.2x (scd_open, spin up)\n", res_reg[1]);
1612          return -EIO;
1613       }
1614       
1615       do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
1616 
1617       /* The drive sometimes returns error 0.  I don't know why, but ignore
1618          it.  It seems to mean the drive has already done the operation. */
1619       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
1620       {
1621          /* If the drive is already playing, its ok.  */
1622          if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
1623          {
1624             goto drive_spinning;
1625          }
1626 
1627          /* If the drive says it is not spun up (even though we just did it!)
1628             then retry the operation at least a few times. */
1629          if (   (res_reg[1] == SONY_NOT_SPIN_ERR)
1630              && (num_spin_ups < MAX_CDU31A_RETRIES))
1631          {
1632             num_spin_ups++;
1633             goto respinup_on_open;
1634          }
1635 
1636          printk("Sony CDROM error 0x%2.2x (scd_open, read toc)\n", res_reg[1]);
1637          do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1638          
1639          return -EIO;
1640       }
1641 
1642       sony_get_toc();
1643       if (!sony_toc_read)
1644       {
1645          do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1646          return -EIO;
1647       }
1648 
1649       sony_spun_up = 1;
1650    }
1651 
1652 drive_spinning:
1653 
1654    if (inode)
1655    {
1656       check_disk_change(inode->i_rdev);
1657    }
1658 
1659    sony_usage++;
1660 
1661    return 0;
1662 }
1663 
1664 
1665 /*
1666  * Close the drive.  Spin it down if no task is using it.  The spin
1667  * down will fail if playing audio, so audio play is OK.
1668  */
1669 static void
1670 scd_release(struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
1671          struct file *filp)
1672 {
1673    unsigned char res_reg[2];
1674    unsigned int  res_size;
1675 
1676 
1677    if (sony_usage > 0)
1678    {
1679       sony_usage--;
1680    }
1681    if (sony_usage == 0)
1682    {
1683       sync_dev(inode->i_rdev);
1684       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
1685 
1686       sony_spun_up = 0;
1687    }
1688 }
1689 
1690 
1691 static struct file_operations scd_fops = {
1692    NULL,                   /* lseek - default */
1693    block_read,             /* read - general block-dev read */
1694    block_write,            /* write - general block-dev write */
1695    NULL,                   /* readdir - bad */
1696    NULL,                   /* select */
1697    scd_ioctl,              /* ioctl */
1698    NULL,                   /* mmap */
1699    scd_open,               /* open */
1700    scd_release,            /* release */
1701    NULL                    /* fsync */
1702 };
1703 
1704 
1705 /* The different types of disc loading mechanisms supported */
1706 static char *load_mech[] = { "caddy", "tray", "pop-up", "unknown" };
1707 
1708 /* Read-ahead buffer sizes for different drives.  These are just arbitrary
1709    values, I don't know what is really optimum. */
1710 static unsigned int mem_size[] = { 16384, 16384, 16384, 2048 };
1711 
1712 void
1713 get_drive_configuration(unsigned short base_io,
     /* [previous][next][first][last][top][bottom][index][help] */
1714                         unsigned char res_reg[],
1715                         unsigned int *res_size)
1716 {
1717    int retry_count;
1718 
1719 
1720    /* Set the base address */
1721    sony_cd_base_io = base_io;
1722 
1723    /* Set up all the register locations */
1724    sony_cd_cmd_reg = sony_cd_base_io + SONY_CMD_REG_OFFSET;
1725    sony_cd_param_reg = sony_cd_base_io + SONY_PARAM_REG_OFFSET;
1726    sony_cd_write_reg = sony_cd_base_io + SONY_WRITE_REG_OFFSET;
1727    sony_cd_control_reg = sony_cd_base_io + SONY_CONTROL_REG_OFFSET;
1728    sony_cd_status_reg = sony_cd_base_io + SONY_STATUS_REG_OFFSET;
1729    sony_cd_result_reg = sony_cd_base_io + SONY_RESULT_REG_OFFSET;
1730    sony_cd_read_reg = sony_cd_base_io + SONY_READ_REG_OFFSET;
1731    sony_cd_fifost_reg = sony_cd_base_io + SONY_FIFOST_REG_OFFSET;
1732 
1733    /*
1734     * Check to see if anything exists at the status register location.
1735     * I don't know if this is a good way to check, but it seems to work
1736     * ok for me.
1737     */
1738    if (read_status_register() != 0xff)
1739    {
1740       /*
1741        * Reset the drive and wait for attention from it (to say its reset).
1742        * If you don't wait, the next operation will probably fail.
1743        */
1744       reset_drive();
1745       retry_count = jiffies + SONY_RESET_TIMEOUT;
1746       while ((retry_count > jiffies) && (!is_attention()))
1747       {
1748          sony_sleep();
1749       }
1750 
1751       /* If attention is never seen probably not a CDU31a present */
1752       if (!is_attention())
1753       {
1754          res_reg[0] = 0x20;
1755          return;
1756       }
1757 
1758       /*
1759        * Get the drive configuration.
1760        */
1761       do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
1762                      NULL,
1763                      0,
1764                      (unsigned char *) res_reg,
1765                      res_size);
1766       return;
1767    }
1768 
1769    /* Return an error */
1770    res_reg[0] = 0x20;
1771 }
1772 
1773 
1774 /*
1775  * Initialize the driver.
1776  */
1777 unsigned long
1778 cdu31a_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
1779 {
1780    struct s_sony_drive_config drive_config;
1781    unsigned int res_size;
1782    int i;
1783    int drive_found;
1784 
1785 
1786    /*
1787     * According to Alex Freed (freed@europa.orion.adobe.com), this is
1788     * required for the Fusion CD-16 package.  If the sound driver is
1789     * loaded, it should work fine, but just in case...
1790     *
1791     * The following turn on the CD-ROM interface for a Fusion CD-16.
1792     */
1793    outb(0xbc, 0x9a01);
1794    outb(0xe2, 0x9a01);
1795 
1796    i = 0;
1797    drive_found = 0;
1798    while (   (cdu31a_addresses[i] != 0)
1799           && (!drive_found))
1800    {
1801       if (check_region(cdu31a_addresses[i], 4)) {
1802           i++;
1803           continue;
1804       }
1805       get_drive_configuration(cdu31a_addresses[i],
1806                                drive_config.exec_status,
1807                                &res_size);
1808       if ((res_size > 2) && ((drive_config.exec_status[0] & 0x20) == 0x00))
1809       {
1810          drive_found = 1;
1811          snarf_region(cdu31a_addresses[i], 4);
1812 
1813          if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
1814          {
1815             printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
1816             return mem_start;
1817          }
1818 
1819          sony_buffer_size = mem_size[SONY_HWC_GET_BUF_MEM_SIZE(drive_config)];
1820          sony_buffer_sectors = sony_buffer_size / 2048;
1821 
1822          printk("Sony I/F CDROM : %8.8s %16.16s %8.8s with %s load mechanism\n",
1823                 drive_config.vendor_id,
1824                 drive_config.product_id,
1825                 drive_config.product_rev_level,
1826                 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
1827          printk("  using %d byte buffer", sony_buffer_size);
1828          if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
1829          {
1830             printk(", capable of audio playback");
1831          }
1832          printk("\n");
1833 
1834          set_drive_params();
1835 
1836          blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1837          read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
1838 
1839          sony_toc = (struct s_sony_toc *) mem_start;
1840          mem_start += sizeof(*sony_toc);
1841          last_sony_subcode = (struct s_sony_subcode *) mem_start;
1842          mem_start += sizeof(*last_sony_subcode);
1843          sony_buffer = (unsigned char *) mem_start;
1844          mem_start += sony_buffer_size;
1845       }
1846 
1847       i++;
1848    }
1849    
1850    return mem_start;
1851 }
1852 

/* [previous][next][first][last][top][bottom][index][help] */