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

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