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

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