home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / kernel-s / v1.1 / sony535-.1 / sony535-for-1.1.38.diff
Text File  |  1994-08-03  |  57KB  |  1,773 lines

  1. diff -u --recursive --new-file linux-1.1.38/config.in linux/config.in
  2. --- linux-1.1.38/config.in    Wed Aug  3 01:37:55 1994
  3. +++ linux/config.in    Wed Aug  3 01:49:47 1994
  4. @@ -132,6 +132,7 @@
  5.  comment 'CD-ROM drivers'
  6.  
  7.  bool 'Sony CDU31A/CDU33A CDROM driver support' CONFIG_CDU31A n
  8. +bool 'Sony CDU535 CDROM driver support' CONFIG_CDU535 n
  9.  bool 'Mitsumi CDROM driver support' CONFIG_MCD n
  10.  bool 'Matsushita/Panasonic CDROM driver support' CONFIG_SBPCD n
  11.  if [ "$CONFIG_SBPCD" = "y" ]; then
  12. diff -u --recursive --new-file linux-1.1.38/drivers/block/Makefile linux/drivers/block/Makefile
  13. --- linux-1.1.38/drivers/block/Makefile    Wed Aug  3 01:35:39 1994
  14. +++ linux/drivers/block/Makefile    Wed Aug  3 01:48:34 1994
  15. @@ -29,6 +29,11 @@
  16.  SRCS := $(SRCS) cdu31a.c
  17.  endif
  18.  
  19. +ifdef CONFIG_CDU535
  20. +OBJS := $(OBJS) sonycd535.o
  21. +SRCS := $(SRCS) sonycd535.c
  22. +endif
  23. +
  24.  ifdef CONFIG_MCD
  25.  OBJS := $(OBJS) mcd.o
  26.  SRCS := $(SRCS) mcd.c
  27. diff -u --recursive --new-file linux-1.1.38/drivers/block/blk.h linux/drivers/block/blk.h
  28. --- linux-1.1.38/drivers/block/blk.h    Wed Aug  3 01:37:41 1994
  29. +++ linux/drivers/block/blk.h    Wed Aug  3 01:49:30 1994
  30. @@ -183,6 +183,14 @@
  31.  #define DEVICE_ON(device)
  32.  #define DEVICE_OFF(device)
  33.  
  34. +#elif (MAJOR_NR == CDU535_CDROM_MAJOR)
  35. +
  36. +#define DEVICE_NAME "CDU535"
  37. +#define DEVICE_REQUEST do_scd535_request
  38. +#define DEVICE_NR(device) (MINOR(device))
  39. +#define DEVICE_ON(device)
  40. +#define DEVICE_OFF(device)
  41. +
  42.  #elif (MAJOR_NR == MITSUMI_CDROM_MAJOR)
  43.  
  44.  #define DEVICE_NAME "Mitsumi CD-ROM"
  45. diff -u --recursive --new-file linux-1.1.38/drivers/block/sonycd535.c linux/drivers/block/sonycd535.c
  46. --- linux-1.1.38/drivers/block/sonycd535.c    Wed Dec 31 18:00:00 1969
  47. +++ linux/drivers/block/sonycd535.c    Wed Aug  3 01:49:12 1994
  48. @@ -0,0 +1,1537 @@
  49. +/*
  50. + * Sony CDU-535 interface device driver
  51. + *
  52. + * This is a modified version of the CDU-31A device driver (see below).
  53. + * Changes were made using documentation for the CDU-531 (which Sony
  54. + * assures me is very similar to the 535) and partial disassembly of the
  55. + * DOS driver.  I used Minyard's driver and replaced the the CDU-31A 
  56. + * commands with the CDU-531 commands.  This was complicated by a different
  57. + * interface protocol with the drive.  The driver is still polled.
  58. + *
  59. + * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
  60. + * I tried polling without the sony_sleep during the data transfers but
  61. + * it did not speed things up any.
  62. + *
  63. + *  5/23/93 (rgj) changed the major number to 21 to get rid of conflict
  64. + * with CDU-31A driver.  This is the also the number from the Linux
  65. + * Device Driver Registry for the Sony Drive.  Hope nobody else is using it.
  66. + *
  67. + *  8/29/93 (rgj) remove the configuring of the interface board address
  68. + * from the top level configuration, you have to modify it in this file.
  69. + *
  70. + * Things to do:
  71. + *    - handle errors and status better, put everything into a single word
  72. + *    - use interrupts, DMA
  73. + *
  74. + *  Known Bugs:
  75. + *    -
  76. + *
  77. + *   Ron Jeppesen (ronj.an@site007.saic.com)
  78. + *
  79. + *
  80. + *------------------------------------------------------------------------
  81. + * Sony CDROM interface device driver.
  82. + *
  83. + * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to ronj above)
  84. + *
  85. + * Colossians 3:17
  86. + *
  87. + * The Sony interface device driver handles Sony interface CDROM
  88. + * drives and provides a complete block-level interface as well as an
  89. + * ioctl() interface compatible with the Sun (as specified in
  90. + * include/linux/cdrom.h).  With this interface, CDROMs can be
  91. + * accessed and standard audio CDs can be played back normally.
  92. + *
  93. + * This interface is (unfortunatly) a polled interface.  This is
  94. + * because most Sony interfaces are set up with DMA and interrupts
  95. + * disables.  Some (like mine) do not even have the capability to
  96. + * handle interrupts or DMA.  For this reason you will see a lot of
  97. + * the following:
  98. + *
  99. + *   retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
  100. + *   while ((retry_count > jiffies) && (! <some condition to wait for))
  101. + *   {
  102. + *      while (handle_sony_cd_attention())
  103. + *         ;
  104. + *
  105. + *      sony_sleep();
  106. + *   }
  107. + *   if (the condition not met)
  108. + *   {
  109. + *      return an error;
  110. + *   }
  111. + *
  112. + * This ugly hack waits for something to happen, sleeping a little
  113. + * between every try.  it also handles attentions, which are
  114. + * asyncronous events from the drive informing the driver that a disk
  115. + * has been inserted, removed, etc.
  116. + *
  117. + * One thing about these drives: They talk in MSF (Minute Second Frame) format.
  118. + * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
  119. + * disk.  The funny thing is that these are sent to the drive in BCD, but the
  120. + * interface wants to see them in decimal.  A lot of conversion goes on.
  121. + *
  122. + *  Copyright (C) 1993  Corey Minyard
  123. + *
  124. + *  This program is free software; you can redistribute it and/or modify
  125. + *  it under the terms of the GNU General Public License as published by
  126. + *  the Free Software Foundation; either version 2 of the License, or
  127. + *  (at your option) any later version.
  128. + *
  129. + *  This program is distributed in the hope that it will be useful,
  130. + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  131. + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  132. + *  GNU General Public License for more details.
  133. + *
  134. + *  You should have received a copy of the GNU General Public License
  135. + *  along with this program; if not, write to the Free Software
  136. + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  137. + *
  138. + */
  139. +
  140. +
  141. +#include <linux/config.h>
  142. +#ifdef CONFIG_CDU535
  143. +
  144. +#include <linux/errno.h>
  145. +#include <linux/signal.h>
  146. +#include <linux/sched.h>
  147. +#include <linux/timer.h>
  148. +#include <linux/fs.h>
  149. +#include <linux/kernel.h>
  150. +#include <linux/hdreg.h>
  151. +#include <linux/genhd.h>
  152. +
  153. +#define REALLY_SLOW_IO
  154. +#include <asm/system.h>
  155. +#include <asm/io.h>
  156. +#include <asm/segment.h>
  157. +
  158. +#include <linux/cdrom.h>
  159. +#include <linux/sonycd535.h>
  160. +
  161. +#define MAJOR_NR CDU535_CDROM_MAJOR
  162. +#include "blk.h"
  163. +
  164. +/*
  165. + * this is the base address of the interface card for the Sony CDU535
  166. + * CDROM drive.  If your jumpers are set for an address other than
  167. + * this one (the default), change the following line to the
  168. + * proper address.
  169. + */
  170. +#define CDU535_ADDRESS    (0x340)
  171. +
  172. +#define DEBUG
  173. +
  174. +/*
  175. + *  SONY535_BUFFER_SIZE determines the size of internal buffer used
  176. + *  by the drive.  It must be at least 2K and the larger the buffer
  177. + *  the better the transfer rate.  It does however take system memory.
  178. + *   On my system I get the following transfer rates using dd to read
  179. + *  10 Mb off /dev/cdrom.
  180. + *
  181. + *      8K buffer         43 Kb/sec
  182. + *    16K buffer         66 Kb/sec
  183. + *    32K buffer         91 Kb/sec
  184. + *    64K buffer        111 Kb/sec
  185. + *    128K buffer        123 Kb/sec
  186. + *    512K buffer        123 Kb/sec
  187. + */
  188. +#define SONY535_BUFFER_SIZE    (64*1024)
  189. +
  190. +/*
  191. + *  if LOCK_DOORS is defined then the eject button is disabled while
  192. + * the device is open.
  193. + */
  194. +#define LOCK_DOORS
  195. +
  196. +static int read_subcode(void);
  197. +static void sony_get_toc(void);
  198. +static int scd_open( struct inode *inode, struct file *filp );
  199. +static inline unsigned int int_to_bcd(unsigned int val);
  200. +static unsigned int bcd_to_int(unsigned int bcd);
  201. +static int do_sony_cmd( Byte *cmd, int nCmd, Byte status[2], 
  202. +                 Byte *response, int nResponse, int ignoreStatusBit7 );
  203. +
  204. +/* The base I/O address of the Sony Interface.  This is a variable (not a
  205. +   #define) so it can be easily changed via some future ioctl() */
  206. +static unsigned short sony_cd_base_io = CDU535_ADDRESS;
  207. +
  208. +/*
  209. + * The following are I/O addresses of the various registers for the drive.  The
  210. + * comment for the base address also applies here.
  211. + */
  212. +static unsigned short select_unit_reg;
  213. +static unsigned short result_reg;
  214. +static unsigned short command_reg;
  215. +static unsigned short read_status_reg;
  216. +static unsigned short data_reg;
  217. +
  218. +static int initialized = 0;                /* Has the drive been initialized? */
  219. +static int sony_disc_changed = 1;          /* Has the disk been changed
  220. +                                              since the last check? */
  221. +static int sony_toc_read = 0;              /* Has the table of contents been
  222. +                                              read? */
  223. +static unsigned int sony_buffer_size;      /* Size in bytes of the read-ahead
  224. +                                              buffer. */
  225. +static unsigned int sony_buffer_sectors;   /* Size (in 2048 byte records) of
  226. +                                              the read-ahead buffer. */
  227. +static unsigned int sony_usage = 0;        /* How many processes have the
  228. +                                              drive open. */
  229. +
  230. +static int sony_first_block = -1;          /* First OS block (512 byte) in
  231. +                                              the read-ahead buffer */
  232. +static int sony_last_block = -1;           /* Last OS block (512 byte) in
  233. +                                              the read-ahead buffer */
  234. +
  235. +static struct s535_sony_toc *sony_toc;           /* Points to the table of
  236. +                                                    contents. */
  237. +static struct s535_sony_subcode *last_sony_subcode; /* Points to the last
  238. +                                                    subcode address read */
  239. +static unsigned char *sony_buffer;               /* Points to the read-ahead
  240. +                                                    buffer */
  241. +static int sony_inuse = 0;        /* is the drive in use? Only one
  242. +                       open at a time allowed */
  243. +
  244. +/*
  245. + * The audio status uses the values from read subchannel data as specified
  246. + * in include/linux/cdrom.h.
  247. + */
  248. +static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
  249. +
  250. +/*
  251. + * The following are a hack for pausing and resuming audio play.  The drive
  252. + * does not work as I would expect it, if you stop it then start it again,
  253. + * the drive seeks back to the beginning and starts over.  This holds the
  254. + * position during a pause so a resume can restart it.  It uses the
  255. + * audio status variable above to tell if it is paused.
  256. + *   I just kept the CDU-31A driver behavior rather than using the PAUSE
  257. + * command on the CDU-535.
  258. + */
  259. +static unsigned char cur_pos_msf[3] = { 0, 0, 0 };
  260. +static unsigned char final_pos_msf[3] = { 0, 0, 0 };
  261. +
  262. +
  263. +/*
  264. + * This routine returns 1 if the disk has been changed since the last
  265. + * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
  266. + */
  267. +int
  268. +sony535_check_cdrom_media_change(int full_dev, int flag)
  269. +{
  270. +   int retval, target;
  271. +
  272. +   target = MINOR(full_dev);
  273. +
  274. +   if (target > 0) {
  275. +      printk("Sony CD-ROM request error: invalid device.\n");
  276. +      return 0;
  277. +   }
  278. +
  279. +    /* if driver is not initialized, always return 0 */
  280. +   retval = ( initialized ? sony_disc_changed : 0 );
  281. +   if (!flag)
  282. +   {
  283. +      sony_disc_changed = 0;
  284. +   }
  285. +
  286. +   return retval;
  287. +}
  288. +
  289. +
  290. +/*
  291. + * Wait a little while (used for polling the drive).  If in initialization,
  292. + * setting a timeout doesn't work, so just loop for a while  (we trust
  293. + * that the sony_sleep() call is protected by a test for proper jiffies count).
  294. + */
  295. +static inline void
  296. +sony_sleep(void)
  297. +{
  298. +   current->state = TASK_INTERRUPTIBLE;
  299. +   current->timeout = jiffies;
  300. +   schedule();
  301. +}
  302. +
  303. +/*------------------start of SONY CDU535 very specific ---------------------*/
  304. +
  305. +/****************************************************************************
  306. + * void select_unit( int unit_no )
  307. + *
  308. + *  Select the specified unit (0-3) so that subsequent commands reference it
  309. + ****************************************************************************/
  310. +static void 
  311. +select_unit( int unit_no )
  312. +{
  313. +   unsigned int select_mask = ~(1 << unit_no);
  314. +   outb( select_mask, select_unit_reg );
  315. +}  /* select_unit() */
  316. +
  317. +/***************************************************************************
  318. + * int read_result_reg( unsigned char *data_ptr )
  319. + *
  320. + *  Read a result byte from the Sony CDU controller, store in location pointed
  321. + * to by data_ptr.  Return zero on success, TIME_OUT if we did not receive
  322. + * data.
  323. + ***************************************************************************/
  324. +static int 
  325. +read_result_reg( unsigned char *data_ptr )
  326. +{
  327. +   int retry_count;
  328. +   int read_status;
  329. +  
  330. +   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
  331. +   while ( retry_count > jiffies ) 
  332. +   {
  333. +      if ( ((read_status=inb(read_status_reg)) & SONY535_RESULT_NOT_READY_BIT) == 0 ) 
  334. +      {
  335. +#if 0
  336. +         printk("read_result_reg(): readStatReg = 0x%x\n", read_status );
  337. +#endif
  338. +         *data_ptr = inb(result_reg);
  339. +         return( 0 );
  340. +      }
  341. +      else 
  342. +      {
  343. +         sony_sleep();
  344. +      }
  345. +   }
  346. +   printk(" Sony CDROM read_result_reg: TIME OUT!\n");
  347. +   return( TIME_OUT );
  348. +}  /* read_result_reg() */
  349. +
  350. +/****************************************************************************
  351. + * int read_exec_status( Byte status[2] )
  352. + *
  353. + *  Read the execution status of the last command and put into status. 
  354. + * Handles reading second status word if available.  Returns 0 on success,
  355. + * TIME_OUT on failure.
  356. + ****************************************************************************/
  357. +static int 
  358. +read_exec_status( Byte status[2] )
  359. +{
  360. +   status[1] = 0;
  361. +   if ( read_result_reg( &(status[0]) ) != 0 ) return( TIME_OUT );
  362. +   if ( (status[0] & 0x80) != 0 )  /* byte two follows */
  363. +   {
  364. +      if ( read_result_reg( &(status[1]) ) != 0 ) return( TIME_OUT );
  365. +   }
  366. +#if 0
  367. +   printk("read_exec_status: read 0x%x\n", status[0] );
  368. +   if (status[0] & 0x80) printk(" and 0x%x\n", status[1] );
  369. +   printk("\n");
  370. +#endif
  371. +   return( 0 );
  372. +}  /* read_exec_status() */
  373. +
  374. +/****************************************************************************
  375. + * int check_drive_status( void )
  376. + *
  377. + *  Check the current drive status.  Using this before executing a command
  378. + * takes care of the problem of unsolicited drive status-2 messages.
  379. + * Add a check of the audio status if we think the disk is playing.
  380. + ****************************************************************************/
  381. +static int 
  382. +check_drive_status( void )
  383. +{
  384. +   Byte status, e_status[2];
  385. +   int CDD, ATN;
  386. +   unsigned char cmd;
  387. +  
  388. +   select_unit(0);
  389. +   if ( sony_audio_status == CDROM_AUDIO_PLAY )  /* check status */
  390. +   {
  391. +      outb( SONY535_REQUEST_AUDIO_STATUS, command_reg );
  392. +      if ( read_result_reg( &status ) == 0 ) 
  393. +      {
  394. +         switch( status ) 
  395. +         {
  396. +            case 0x0:  break;            /* play in progress */
  397. +            case 0x1:  break;            /* paused */
  398. +            case 0x3:                /* audio play completed */
  399. +            case 0x5:                /* play not requested */
  400. +                       sony_audio_status = CDROM_AUDIO_COMPLETED;
  401. +                       read_subcode();
  402. +                       break;
  403. +            case 0x4:                /* error during play */
  404. +                       sony_audio_status = CDROM_AUDIO_ERROR;
  405. +                       break;
  406. +         }
  407. +      }
  408. +   }
  409. +    /* now check drive status */
  410. +   outb( SONY535_REQUEST_DRIVE_STATUS_2, command_reg );
  411. +   if ( read_result_reg( &status ) != 0 ) 
  412. +      return( TIME_OUT );
  413. +
  414. +#if 0
  415. +   printk("--check_drive_status() got 0x%x\n", status );
  416. +#endif
  417. +  
  418. +   if ( status == 0 ) return( 0 );
  419. +  
  420. +   ATN = status & 0xf;
  421. +   CDD = (status >> 4) & 0xf;
  422. +  
  423. +   switch ( ATN ) 
  424. +   {
  425. +      case 0x0:
  426. +                 break;  /* go on to CDD stuff */
  427. +      case SONY535_ATN_BUSY:
  428. +                 if ( initialized )
  429. +                    printk("Sony CDROM error, drive busy\n");
  430. +                 return( CD_BUSY);
  431. +      case SONY535_ATN_EJECT_IN_PROGRESS:
  432. +                 printk("Sony CDROM error, eject in progress\n");
  433. +                 sony_audio_status = CDROM_AUDIO_INVALID;
  434. +                 return( CD_BUSY);
  435. +      case SONY535_ATN_RESET_OCCURRED:
  436. +      case SONY535_ATN_DISC_CHANGED:
  437. +      case SONY535_ATN_RESET_AND_DISC_CHANGED:
  438. +#ifdef DEBUG
  439. +                 printk("Sony CDROM, reset occurred or disc changed\n");
  440. +#endif
  441. +                 sony_disc_changed = 1;
  442. +                 sony_toc_read = 0;
  443. +                 sony_audio_status = CDROM_AUDIO_NO_STATUS;
  444. +                 sony_first_block = -1;
  445. +                 sony_last_block = -1;
  446. +                 if (initialized)
  447. +                 {
  448. +                    cmd = SONY535_SPIN_UP;
  449. +                    do_sony_cmd( &cmd,1, e_status, NULL,0, 0 );
  450. +                    sony_get_toc();
  451. +                 }
  452. +                 return( 0 );
  453. +      default:
  454. +                 printk("Sony CDROM error, drive busy (ATN=0x%x)\n", ATN );
  455. +                 return( CD_BUSY );
  456. +   }
  457. +   switch ( CDD ) 
  458. +   {  /* the 531 docs are not helpful in decoding this */
  459. +      case 0x0:       /* just use the values from the DOS driver */
  460. +      case 0x2:
  461. +      case 0xa:
  462. +                 break;  /* no error */
  463. +      case 0xc:
  464. +                 printk("check_drive_status(): CDD = 0xc! Not properly handled!\n");
  465. +                 return( CD_BUSY );  /* ? */
  466. +      default:
  467. +                 return( CD_BUSY );
  468. +   }
  469. +   return( 0 );
  470. +}  /* check_drive_status() */
  471. +
  472. +/*****************************************************************************
  473. + * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2], 
  474. + *                Byte *response, int n_response, int ignore_status_bit7 )
  475. + *
  476. + *  Generic routine for executing commands.  The command and its parameters
  477. + *  should be placed in the cmd[] array, number of bytes in the command is
  478. + *  stored in nCmd.  The response from the command will be stored in the
  479. + *  response array.  The number of bytes you expect back (excluding status)
  480. + *  should be passed in nReponse.  Finally, some
  481. + *  commands set bit 7 of the return status even when there is no second
  482. + *  status byte, on these commands set ignoreStatusBit7 TRUE.
  483. + *    If the command was sent and data recieved back, then we return 0,
  484. + *  else we return TIME_OUT.  You still have to check the status yourself.
  485. + *    You should call check_drive_status() before calling this routine
  486. + *  so that you do not lose notifications of disk changes, etc.
  487. + ****************************************************************************/
  488. +static int 
  489. +do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2], 
  490. +             Byte *response, int n_response, int ignore_status_bit7 )
  491. +{
  492. +   int i;
  493. +  
  494. +    /* write out the command */
  495. +   for ( i=0; i < n_cmd; i++ )
  496. +      outb( cmd[i], command_reg );
  497. +  
  498. +    /* read back the status */
  499. +   if ( read_result_reg( status ) != 0 )
  500. +      return( TIME_OUT );
  501. +   if ( !ignore_status_bit7 && ((status[0] & 0x80) != 0) ) /* get second status byte */
  502. +   {
  503. +      if ( read_result_reg( status+1 ) != 0 )
  504. +         return( TIME_OUT );
  505. +   }
  506. +   else
  507. +   {
  508. +      status[1] = 0;
  509. +   }
  510. +    
  511. +   /* do not know about when I should read set of data and when not to */
  512. +   if ( (status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0 )
  513. +      return( 0 );
  514. +  
  515. +    /* else, read in rest of data */
  516. +   for ( i=0; n_response > 0; n_response--, i++ )
  517. +      if ( read_result_reg( response+i ) != 0 ) return(TIME_OUT);
  518. +   return( 0 );
  519. +}  /* do_sony_cmd() */
  520. +
  521. +/**************************************************************************
  522. + * int set_drive_mode( int mode, Byte status[2] )
  523. + *
  524. + *  Set the drive mode to the specified value (mode=0 is audio, mode=e0
  525. + * is mode-1 CDROM
  526. + **************************************************************************/
  527. +static int 
  528. +set_drive_mode( int mode, Byte status[2] )
  529. +{
  530. +   Byte cmd_buff[2], ret_buff[1];
  531. +  
  532. +   cmd_buff[0] = SONY535_SET_DRIVE_MODE;
  533. +   cmd_buff[1] = mode;
  534. +   return( do_sony_cmd( cmd_buff,2, status, ret_buff,1, 1 ) );
  535. +}  /* set_drive_mode() */
  536. +
  537. +/***************************************************************************
  538. + * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2], 
  539. + *                             Byte *data_buff, int buff_size )
  540. + *
  541. + *  Read n_blocks of data from the CDROM starting at position params[0:2],
  542. + *  number of blocks in stored in params[3:5] -- both these are already
  543. + *  int bcd format.
  544. + *  Transfer the data into the buffer pointed at by data_buff.  buff_size
  545. + *  gives the number of bytes available in the buffer.
  546. + *    The routine returns number of bytes read in if successful, otherwise
  547. + *  it returns one of the standard error returns.
  548. + ***************************************************************************/
  549. +static int 
  550. +seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
  551. +                        Byte *data_buff, int buf_size )
  552. +{
  553. +   int i;
  554. +   const int block_size = 2048;
  555. +   Byte cmd_buff[7];
  556. +   int read_status;
  557. +   Byte *start_pos = data_buff;
  558. +   int retry_count;
  559. +  
  560. +   if ( ((long)block_size)*n_blocks > buf_size )
  561. +      return( NO_ROOM );
  562. +  
  563. +   set_drive_mode( SONY535_CDROM_DRIVE_MODE, status );
  564. +  
  565. +    /* send command to read the data */
  566. +   cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
  567. +   for ( i=0; i < 6; i++ )
  568. +      cmd_buff[i+1] = params[i];
  569. +   for ( i=0; i < 7; i++ )
  570. +      outb( cmd_buff[i], command_reg );
  571. +  
  572. +    /* read back the data one block at a time */
  573. +   while ( n_blocks-- > 0 ) 
  574. +   {
  575. +       /* wait for data to be ready */
  576. +      retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
  577. +      while ( retry_count > jiffies ) 
  578. +      {
  579. +         read_status = inb(read_status_reg);
  580. +         if ( (read_status & SONY535_RESULT_NOT_READY_BIT) == 0 ) 
  581. +         {
  582. +            read_exec_status( status );
  583. +            return( BAD_STATUS );
  584. +         }
  585. +         if ( (read_status & SONY535_DATA_NOT_READY_BIT) == 0 ) 
  586. +         {
  587. +             /* data is ready, read it */
  588. +            for ( i=0; i < block_size; i++ )
  589. +               *data_buff++ = inb( data_reg );  /* unrolling this loop does not seem to help */
  590. +            break;  /* exit the timeout loop */
  591. +         }
  592. +         sony_sleep();  /* data not ready, sleep a while */
  593. +      }
  594. +      if ( retry_count <= jiffies )
  595. +      return( TIME_OUT );  /* if we reach this stage */
  596. +   }
  597. +  
  598. +    /* read all the data, now read the status */
  599. +   if ( (i=read_exec_status( status )) != 0 )
  600. +      return( i );
  601. +   return( data_buff - start_pos );
  602. +}  /* seek_and_read_N_blocks() */
  603. +
  604. +/****************************************************************************
  605. + * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
  606. + *
  607. + *  Read in the table of contents data.  Converts all the bcd data
  608. + * into integers in the toc structure.
  609. + ****************************************************************************/
  610. +static int 
  611. +request_toc_data( Byte status[2], struct s535_sony_toc *toc )
  612. +{
  613. +   int to_status;
  614. +   int i, j, n_tracks, track_no;
  615. +   Byte cmd_no = 0xb2;
  616. +   Byte track_address_buffer[5];
  617. +   int first_track_num, last_track_num;
  618. +
  619. +    /* read the fixed portion of the table of contents */
  620. +   if ((to_status=do_sony_cmd( &cmd_no,1, status, (Byte *)toc,15, 1 )) != 0 )
  621. +      return( to_status );
  622. +  
  623. +    /* convert the data into integers so we can use them */
  624. +   first_track_num = bcd_to_int(toc->first_track_num);
  625. +   last_track_num = bcd_to_int(toc->last_track_num);
  626. +   n_tracks = last_track_num - first_track_num + 1;
  627. +  
  628. +    /* read each of the track address descriptors */
  629. +   for ( i=0; i < n_tracks; i++ ) 
  630. +   {
  631. +       /* read the descriptor into a temporary buffer */
  632. +      for ( j=0; j < 5; j++ ) 
  633. +      {
  634. +         if ( read_result_reg( track_address_buffer+j ) != 0 )
  635. +            return( TIME_OUT );
  636. +         if ( j == 1 )  /* need to convert from bcd */
  637. +            track_no = bcd_to_int(track_address_buffer[j]);
  638. +      }
  639. +       /* copy the descriptor to proper location - sonycd.c just fills */
  640. +      memcpy( toc->tracks+i, track_address_buffer, 5 );
  641. +   }
  642. +   return( 0 );
  643. +}  /* request_toc_data() */
  644. +
  645. +/***************************************************************************
  646. + * int spin_up_drive( Byte status[2] )
  647. + *
  648. + *  Spin up the drive (unless it is already spinning).
  649. + ***************************************************************************/
  650. +static int 
  651. +spin_up_drive( Byte status[2] )
  652. +{
  653. +   Byte cmd_buff[1];
  654. +  
  655. +    /* first see if the drive is already spinning */
  656. +   cmd_buff[0] = SONY535_REQUEST_DRIVE_STATUS_1;
  657. +   if ( do_sony_cmd( cmd_buff,1, status, NULL,0, 0 ) != 0 )
  658. +      return(TIME_OUT );
  659. +   if ( (status[0] & SONY535_STATUS1_NOT_SPINNING) == 0 )
  660. +      return( 0 );  /* its already spinning */
  661. +  
  662. +    /* else, give the spin-up command */
  663. +   cmd_buff[0] = SONY535_SPIN_UP;
  664. +   return( do_sony_cmd( cmd_buff, 1, status, NULL,0, 0 )  );
  665. +}  /* spin_up_drive() */
  666. +
  667. +/*--------------------end of SONY CDU535 very specific ---------------------*/
  668. +
  669. +/* Convert from an integer 0-99 to BCD */
  670. +static inline unsigned int
  671. +int_to_bcd(unsigned int val)
  672. +{
  673. +   int retval;
  674. +
  675. +
  676. +   retval = (val / 10) << 4;
  677. +   retval = retval | val % 10;
  678. +   return(retval);
  679. +}
  680. +
  681. +
  682. +/* Convert from BCD to an integer from 0-99 */
  683. +static unsigned int
  684. +bcd_to_int(unsigned int bcd)
  685. +{
  686. +   return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
  687. +}
  688. +
  689. +
  690. +/*
  691. + * Convert a logical sector value (like the OS would want to use for
  692. + * a block device) to an MSF format.
  693. + */
  694. +static void
  695. +log_to_msf(unsigned int log, unsigned char *msf)
  696. +{
  697. +   log = log + LOG_START_OFFSET;
  698. +   msf[0] = int_to_bcd(log / 4500);
  699. +   log = log % 4500;
  700. +   msf[1] = int_to_bcd(log / 75);
  701. +   msf[2] = int_to_bcd(log % 75);
  702. +}
  703. +
  704. +
  705. +/*
  706. + * Convert an MSF format to a logical sector.
  707. + */
  708. +static unsigned int
  709. +msf_to_log(unsigned char *msf)
  710. +{
  711. +   unsigned int log;
  712. +
  713. +
  714. +   log = bcd_to_int(msf[2]);
  715. +   log += bcd_to_int(msf[1]) * 75;
  716. +   log += bcd_to_int(msf[0]) * 4500;
  717. +   log = log - LOG_START_OFFSET;
  718. +
  719. +   return log;
  720. +}
  721. +
  722. +
  723. +/*
  724. + * Take in integer size value and put it into a buffer like
  725. + * the drive would want to see a number-of-sector value.
  726. + */
  727. +static void
  728. +size_to_buf(unsigned int size,
  729. +            unsigned char *buf)
  730. +{
  731. +   buf[0] = size / 65536;
  732. +   size = size % 65536;
  733. +   buf[1] = size / 256;
  734. +   buf[2] = size % 256;
  735. +}
  736. +
  737. +
  738. +/*
  739. + * The OS calls this to perform a read or write operation to the drive.
  740. + * Write obviously fail.  Reads to a read ahead of sony_buffer_size
  741. + * bytes to help speed operations.  This especially helps since the OS
  742. + * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
  743. + * data access on a CD is done sequentially, this saves a lot of operations.
  744. + */
  745. +static void
  746. +do_scd535_request(void)
  747. +{
  748. +   int block;
  749. +   unsigned int dev;
  750. +   int nsect;
  751. +   unsigned char params[10];
  752. +   int copyoff;
  753. +   int spin_up_retry;
  754. +   unsigned int read_size;
  755. +   unsigned char status[2], cmd[2];
  756. +
  757. +
  758. +   if ( !sony_inuse )
  759. +   {
  760. +      scd_open( NULL, NULL );
  761. +   }
  762. +   
  763. +   while (1)
  764. +   {
  765. +      /*
  766. +       * The beginning here is stolen from the hard disk driver.  I hope
  767. +       * its right.
  768. +       */
  769. +      if (!(CURRENT) || CURRENT->dev < 0)
  770. +      {
  771. +         return;
  772. +      }
  773. +
  774. +      INIT_REQUEST;
  775. +      dev = MINOR(CURRENT->dev);
  776. +      block = CURRENT->sector;
  777. +      nsect = CURRENT->nr_sectors;
  778. +      if (dev != 0)
  779. +      {
  780. +         end_request(0);
  781. +         continue;
  782. +      }
  783. +
  784. +      switch(CURRENT->cmd)
  785. +      {
  786. +      case READ:
  787. +         /*
  788. +          * If the block address is invalid or the request goes beyond the end of
  789. +          * the media, return an error.
  790. +          */
  791. +         if ((block / 4) >= sony_toc->lead_out_start_lba)
  792. +         {
  793. +            end_request(0);
  794. +            return;
  795. +         }
  796. +         if (((block + nsect) / 4) >= sony_toc->lead_out_start_lba)
  797. +         {
  798. +            end_request(0);
  799. +            return;
  800. +         }
  801. +
  802. +         while (nsect > 0)
  803. +         {
  804. +            /*
  805. +             * If the requested sector is not currently in the read-ahead buffer,
  806. +             * it must be read in.
  807. +             */
  808. +            if ((block < sony_first_block) || (block > sony_last_block))
  809. +            {
  810. +               sony_first_block = (block / 4) * 4;
  811. +               log_to_msf(block/4, params);
  812. +
  813. +               /*
  814. +                * If the full read-ahead would go beyond the end of the media, trim
  815. +                * it back to read just till the end of the media.
  816. +                */
  817. +               if (((block / 4) + sony_buffer_sectors) >= sony_toc->lead_out_start_lba)
  818. +               {
  819. +                  sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
  820. +                  read_size = sony_toc->lead_out_start_lba - (block / 4);
  821. +               }
  822. +               else
  823. +               {
  824. +                  sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
  825. +                  read_size = sony_buffer_sectors;
  826. +               }
  827. +               size_to_buf(read_size, ¶ms[3]);
  828. +
  829. +               /*
  830. +                * Read the data.  If the drive was not spinning, spin it up and try
  831. +                * once more.  I know, the goto is ugly, but I am too lazy to fix it.
  832. +                */
  833. +               spin_up_retry = 0;
  834. +try_read_again:
  835. +#if 0
  836. +               if ( check_drive_status() != 0 ) {  /* drive not ready */
  837. +                  sony_first_block = -1;
  838. +                  sony_last_block = -1;
  839. +                  end_request(0);
  840. +                  return;
  841. +                  }
  842. +#endif
  843. +               if ( seek_and_read_N_blocks( params, read_size, status, sony_buffer,
  844. +                         (read_size * 2048) ) < 0 ) {
  845. +                  if ((status[0] & SONY535_STATUS1_NOT_SPINNING) && (!spin_up_retry))
  846. +                  {
  847. +                     printk(" Sony535 Debug -- calling spin up when reading data!\n");
  848. +                     cmd[0] = SONY535_SPIN_UP;
  849. +                     do_sony_cmd( cmd,1, status, NULL,0, 0);
  850. +                     spin_up_retry = 1;
  851. +                     goto try_read_again;
  852. +                  }
  853. +
  854. +                  printk("Sony CDROM Read error: 0x%.2x\n", status[0]);
  855. +                  sony_first_block = -1;
  856. +                  sony_last_block = -1;
  857. +                  end_request(0);
  858. +                  return;
  859. +               }
  860. +            }
  861. +   
  862. +            /*
  863. +             * The data is in memory now, copy it to the buffer and advance to the
  864. +             * next block to read.
  865. +             */
  866. +            copyoff = (block - sony_first_block) * 512;
  867. +            memcpy(CURRENT->buffer, sony_buffer+copyoff, 512);
  868. +               
  869. +            block += 1;
  870. +            nsect -= 1;
  871. +            CURRENT->buffer += 512;
  872. +         }
  873. +               
  874. +         end_request(1);
  875. +         break;
  876. +            
  877. +      case WRITE:
  878. +         end_request(0);
  879. +         break;
  880. +            
  881. +      default:
  882. +         panic("Unkown SONY CD cmd");
  883. +      }
  884. +   }
  885. +}
  886. +
  887. +
  888. +/*
  889. + * Read the table of contents from the drive and set sony_toc_read if
  890. + * successful.
  891. + */
  892. +static void
  893. +sony_get_toc(void)
  894. +{
  895. +   unsigned char status[2];
  896. +  
  897. +   if ( !sony_toc_read ) 
  898. +   {
  899. +       /* do not call check_drive_status() from here since it can call this routine */
  900. +      if ( request_toc_data( status, sony_toc ) < 0 )
  901. +         return;
  902. +      sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
  903. +      sony_toc_read = 1;
  904. +   }
  905. +}
  906. +
  907. +
  908. +/*
  909. + * Search for a specific track in the table of contents.  track is
  910. + * passed in bcd format
  911. + */
  912. +static int
  913. +find_track(int track)
  914. +{
  915. +   int i;
  916. +   int num_tracks;
  917. +
  918. +
  919. +   num_tracks = bcd_to_int(sony_toc->last_track_num) - 
  920. +                   bcd_to_int(sony_toc->first_track_num) + 1;
  921. +   for (i = 0; i < num_tracks; i++)
  922. +   {
  923. +      if (sony_toc->tracks[i].track == track)
  924. +      {
  925. +         return i;
  926. +      }
  927. +   }
  928. +
  929. +   return -1;
  930. +}
  931. +
  932. +/*
  933. + * Read the subcode and put it int last_sony_subcode for future use.
  934. + */
  935. +static int
  936. +read_subcode(void)
  937. +{
  938. +   Byte cmd = SONY535_REQUEST_SUB_Q_DATA, status[2];
  939. +   int dsc_status;
  940. +   
  941. +   if ( check_drive_status() != 0 )
  942. +      return( -EIO );
  943. +     
  944. +   if ( (dsc_status=do_sony_cmd( &cmd,1, status, (Byte *)last_sony_subcode, 
  945. +                      sizeof(struct s535_sony_subcode), 1 )) != 0 ) 
  946. +   {
  947. +      printk("Sony CDROM error 0x%.2x, %d (read_subcode)\n", status[0], 
  948. +              dsc_status );
  949. +      return( -EIO );
  950. +   }
  951. +   return(0);
  952. +}
  953. +
  954. +
  955. +/*
  956. + * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
  957. + * the drive is playing, the subchannel needs to be read (since it would be
  958. + * changing).  If the drive is paused or completed, the subcode information has
  959. + * already been stored, just use that.  The ioctl call wants things in decimal
  960. + * (not BCD), so all the conversions are done.
  961. + */
  962. +static int
  963. +sony_get_subchnl_info(long arg)
  964. +{
  965. +   struct cdrom_subchnl schi;
  966. +
  967. +
  968. +   /* Get attention stuff */
  969. +   if ( check_drive_status() != 0 )
  970. +      return( -EIO );
  971. +
  972. +   sony_get_toc();
  973. +   if (!sony_toc_read)
  974. +   {
  975. +      return -EIO;
  976. +   }
  977. +
  978. +   verify_area(VERIFY_WRITE /* and read */, (char *) arg, sizeof(schi));
  979. +
  980. +   memcpy_fromfs(&schi, (char *) arg, sizeof(schi));
  981. +   
  982. +   switch (sony_audio_status)
  983. +   {
  984. +   case CDROM_AUDIO_PLAY:
  985. +      if (read_subcode() < 0)
  986. +      {
  987. +         return -EIO;
  988. +      }
  989. +      break;
  990. +
  991. +   case CDROM_AUDIO_PAUSED:
  992. +   case CDROM_AUDIO_COMPLETED:
  993. +      break;
  994. +
  995. +   case CDROM_AUDIO_NO_STATUS:
  996. +      schi.cdsc_audiostatus = sony_audio_status;
  997. +      memcpy_tofs((char *) arg, &schi, sizeof(schi));
  998. +      return 0;
  999. +      break;
  1000. +
  1001. +   case CDROM_AUDIO_INVALID:
  1002. +   case CDROM_AUDIO_ERROR:
  1003. +   default:
  1004. +      return -EIO;
  1005. +   }
  1006. +
  1007. +   schi.cdsc_audiostatus = sony_audio_status;
  1008. +   schi.cdsc_adr = last_sony_subcode->address;
  1009. +   schi.cdsc_ctrl = last_sony_subcode->control;
  1010. +   schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
  1011. +   schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
  1012. +   if (schi.cdsc_format == CDROM_MSF)
  1013. +   {
  1014. +      schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
  1015. +      schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
  1016. +      schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
  1017. +
  1018. +      schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
  1019. +      schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
  1020. +      schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
  1021. +   }
  1022. +   else if (schi.cdsc_format == CDROM_LBA)
  1023. +   {
  1024. +      schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
  1025. +      schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
  1026. +   }
  1027. +   
  1028. +   memcpy_tofs((char *) arg, &schi, sizeof(schi));
  1029. +   return 0;
  1030. +}
  1031. +
  1032. +
  1033. +/*
  1034. + * The big ugly ioctl handler.
  1035. + */
  1036. +static int
  1037. +scd_ioctl(struct inode *inode,
  1038. +          struct file  *file,
  1039. +          unsigned int cmd,
  1040. +          unsigned long arg)
  1041. +{
  1042. +   unsigned int dev;
  1043. +   unsigned char status[2];
  1044. +   unsigned char cmd_buff[10], params[10];
  1045. +   int i, dsc_status;
  1046. +
  1047. +
  1048. +   if (!inode)
  1049. +   {
  1050. +      return -EINVAL;
  1051. +   }
  1052. +   dev = MINOR(inode->i_rdev) >> 6;
  1053. +   if (dev != 0)
  1054. +   {
  1055. +      return -EINVAL;
  1056. +   }
  1057. +   
  1058. +   if ( check_drive_status() != 0 )
  1059. +      return( -EIO );
  1060. +
  1061. +   switch (cmd)
  1062. +   {
  1063. +   case CDROMSTART:     /* Spin up the drive */
  1064. +      if ( spin_up_drive( status ) < 0 )
  1065. +      {
  1066. +         printk("Sony CDROM error 0x%.2x (CDROMSTART)\n", status[0]);
  1067. +         return -EIO;
  1068. +      }
  1069. +      return 0;
  1070. +      break;
  1071. +      
  1072. +   case CDROMSTOP:      /* Spin down the drive */
  1073. +      cmd_buff[0] = SONY535_HOLD;
  1074. +      do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1075. +
  1076. +      /*
  1077. +       * Spin the drive down, ignoring the error if the disk was
  1078. +       * already not spinning.
  1079. +       */
  1080. +      sony_audio_status = CDROM_AUDIO_NO_STATUS;
  1081. +      cmd_buff[0] = SONY535_SPIN_DOWN;
  1082. +      dsc_status = do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1083. +      if ( (( dsc_status < 0 ) && (dsc_status != BAD_STATUS)) ||
  1084. +           ( (status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0) ) 
  1085. +      {
  1086. +         printk("Sony CDROM error 0x%.2x (CDROMSTOP)\n", status[0]);
  1087. +         return -EIO;
  1088. +      }
  1089. +      
  1090. +      return 0;
  1091. +      break;
  1092. +
  1093. +   case CDROMPAUSE:     /* Pause the drive */
  1094. +      cmd_buff[0] = SONY535_HOLD;  /* CDU-31 driver uses AUDIO_STOP, not pause */
  1095. +      if ( do_sony_cmd( cmd_buff,1, status, NULL,0, 0 ) != 0 ) 
  1096. +      {
  1097. +         printk("Sony CDROM error 0x%.2x (CDROMPAUSE)\n", status[0]);
  1098. +         return -EIO;
  1099. +      }
  1100. +
  1101. +      /* Get the current position and save it for resuming */
  1102. +      if (read_subcode() < 0)
  1103. +      {
  1104. +         return -EIO;
  1105. +      }
  1106. +      cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
  1107. +      cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
  1108. +      cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
  1109. +      sony_audio_status = CDROM_AUDIO_PAUSED;
  1110. +      return 0;
  1111. +      break;
  1112. +
  1113. +   case CDROMRESUME:    /* Start the drive after being paused */
  1114. +      set_drive_mode( SONY535_AUDIO_DRIVE_MODE, status );
  1115. +      
  1116. +      if (sony_audio_status != CDROM_AUDIO_PAUSED)
  1117. +      {
  1118. +         return -EINVAL;
  1119. +      }
  1120. +      
  1121. +      spin_up_drive( status );
  1122. +      
  1123. +      /* Start the drive at the saved position. */
  1124. +      cmd_buff[0] = SONY535_PLAY_AUDIO;
  1125. +      cmd_buff[1] = 0;  /* play back starting at this address */
  1126. +      cmd_buff[2] = cur_pos_msf[0];
  1127. +      cmd_buff[3] = cur_pos_msf[1];
  1128. +      cmd_buff[4] = cur_pos_msf[2];
  1129. +      cmd_buff[5] = SONY535_PLAY_AUDIO;
  1130. +      cmd_buff[6] = 2;  /* set ending address */
  1131. +      cmd_buff[7] = final_pos_msf[0];
  1132. +      cmd_buff[8] = final_pos_msf[1];
  1133. +      cmd_buff[9] = final_pos_msf[2];
  1134. +      if ( (do_sony_cmd( cmd_buff,5, status, NULL,0, 0 ) != 0 ) ||
  1135. +           (do_sony_cmd( cmd_buff+5,5, status, NULL,0, 0 ) != 0 ) )
  1136. +      {
  1137. +         printk("Sony CDROM error 0x%.2x (CDROMRESUME)\n", status[0]);
  1138. +         return -EIO;
  1139. +      }
  1140. +      sony_audio_status = CDROM_AUDIO_PLAY;
  1141. +      return 0;
  1142. +      break;
  1143. +
  1144. +   case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
  1145. +      verify_area(VERIFY_READ, (char *) arg, 6);
  1146. +      spin_up_drive( status );
  1147. +      set_drive_mode( SONY535_AUDIO_DRIVE_MODE, status );
  1148. +      memcpy_fromfs(params, (void *) arg, 6);
  1149. +      
  1150. +      /* The parameters are given in int, must be converted */
  1151. +      for (i=0; i<3; i++)
  1152. +      {
  1153. +         cmd_buff[2+i] = int_to_bcd(params[i]);
  1154. +         cmd_buff[7+i] = int_to_bcd(params[i+3]);
  1155. +      }
  1156. +      cmd_buff[0] = SONY535_PLAY_AUDIO;
  1157. +      cmd_buff[1] = 0;  /* play back starting at this address */
  1158. +       /* cmd_buff[2-4] are filled in for loop above */
  1159. +      cmd_buff[5] = SONY535_PLAY_AUDIO;
  1160. +      cmd_buff[6] = 2;  /* set ending address */
  1161. +       /* cmd_buff[7-9] are filled in for loop above */
  1162. +      if ( (do_sony_cmd( cmd_buff,5, status, NULL,0, 0 ) != 0 ) ||
  1163. +           (do_sony_cmd( cmd_buff+5,5, status, NULL,0, 0 ) != 0 ) )
  1164. +      {
  1165. +         printk("Sony CDROM error 0x%.2x (CDROMPLAYMSF)\n", status[0]);
  1166. +         return -EIO;
  1167. +      }
  1168. +      
  1169. +      /* Save the final position for pauses and resumes */
  1170. +      final_pos_msf[0] = cmd_buff[7];
  1171. +      final_pos_msf[1] = cmd_buff[8];
  1172. +      final_pos_msf[2] = cmd_buff[9];
  1173. +      sony_audio_status = CDROM_AUDIO_PLAY;
  1174. +      return 0;
  1175. +      break;
  1176. +
  1177. +   case CDROMREADTOCHDR:        /* Read the table of contents header */
  1178. +      {
  1179. +         struct cdrom_tochdr *hdr;
  1180. +         struct cdrom_tochdr loc_hdr;
  1181. +         
  1182. +         sony_get_toc();
  1183. +         if (!sony_toc_read)
  1184. +         {
  1185. +            return -EIO;
  1186. +         }
  1187. +         
  1188. +         hdr = (struct cdrom_tochdr *) arg;
  1189. +         verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
  1190. +         loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
  1191. +         loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
  1192. +         memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
  1193. +      }
  1194. +      return 0;
  1195. +      break;
  1196. +
  1197. +   case CDROMREADTOCENTRY:      /* Read a given table of contents entry */
  1198. +      {
  1199. +         struct cdrom_tocentry *entry;
  1200. +         struct cdrom_tocentry loc_entry;
  1201. +         int track_idx;
  1202. +         unsigned char *msf_val = NULL;
  1203. +         
  1204. +         sony_get_toc();
  1205. +         if (!sony_toc_read)
  1206. +         {
  1207. +            return -EIO;
  1208. +         }
  1209. +         
  1210. +         entry = (struct cdrom_tocentry *) arg;
  1211. +         verify_area(VERIFY_WRITE /* and read */, entry, sizeof(*entry));
  1212. +         
  1213. +         memcpy_fromfs(&loc_entry, entry, sizeof(loc_entry));
  1214. +         
  1215. +         /* Lead out is handled separately since it is special. */
  1216. +         if (loc_entry.cdte_track == CDROM_LEADOUT)
  1217. +         {
  1218. +            loc_entry.cdte_adr = 0 /*sony_toc->address2*/;
  1219. +            loc_entry.cdte_ctrl = sony_toc->control2;
  1220. +            msf_val = sony_toc->lead_out_start_msf;
  1221. +         }
  1222. +         else
  1223. +         {
  1224. +            track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
  1225. +            if (track_idx < 0)
  1226. +            {
  1227. +               return -EINVAL;
  1228. +            }
  1229. +            
  1230. +            loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address*/;
  1231. +            loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
  1232. +            msf_val = sony_toc->tracks[track_idx].track_start_msf;
  1233. +         }
  1234. +         
  1235. +         /* Logical buffer address or MSF format requested? */
  1236. +         if (loc_entry.cdte_format == CDROM_LBA)
  1237. +         {
  1238. +            loc_entry.cdte_addr.lba = msf_to_log(msf_val);
  1239. +         }
  1240. +         else if (loc_entry.cdte_format == CDROM_MSF)
  1241. +         {
  1242. +            loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
  1243. +            loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val+1));
  1244. +            loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val+2));
  1245. +         }
  1246. +         memcpy_tofs(entry, &loc_entry, sizeof(*entry));
  1247. +      }
  1248. +      return 0;
  1249. +      break;
  1250. +
  1251. +   case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
  1252. +      {
  1253. +         struct cdrom_ti ti;
  1254. +         int track_idx;
  1255. +         
  1256. +         sony_get_toc();
  1257. +         if (!sony_toc_read)
  1258. +         {
  1259. +            return -EIO;
  1260. +         }
  1261. +         
  1262. +         verify_area( VERIFY_READ, (char *) arg, sizeof(ti));
  1263. +         
  1264. +         memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
  1265. +         if (   (ti.cdti_trk0 < sony_toc->first_track_num)
  1266. +             || (ti.cdti_trk0 > sony_toc->last_track_num)
  1267. +             || (ti.cdti_trk1 < ti.cdti_trk0))
  1268. +         {
  1269. +            return -EINVAL;
  1270. +         }
  1271. +         
  1272. +         track_idx = find_track(int_to_bcd(ti.cdti_trk0));
  1273. +         if (track_idx < 0)
  1274. +         {
  1275. +            return -EINVAL;
  1276. +         }
  1277. +         params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
  1278. +         params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
  1279. +         params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
  1280. +         /*
  1281. +          * If we want to stop after the last track, use the lead-out
  1282. +          * MSF to do that.
  1283. +          */
  1284. +         if (ti.cdti_trk1 >= bcd_to_int(sony_toc->last_track_num))
  1285. +         {
  1286. +            log_to_msf(msf_to_log(sony_toc->lead_out_start_msf)-1,
  1287. +                       &(params[4]));
  1288. +         }
  1289. +         else
  1290. +         {
  1291. +            track_idx = find_track(int_to_bcd(ti.cdti_trk1+1));
  1292. +            if (track_idx < 0)
  1293. +            {
  1294. +               return -EINVAL;
  1295. +            }
  1296. +            log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf)-1,
  1297. +                       &(params[4]));
  1298. +         }
  1299. +         params[0] = 0x03;
  1300. +         
  1301. +         spin_up_drive( status );
  1302. +         
  1303. +         set_drive_mode( SONY535_AUDIO_DRIVE_MODE, status );
  1304. +      
  1305. +         /* Start the drive at the saved position. */
  1306. +         cmd_buff[0] = SONY535_PLAY_AUDIO;
  1307. +         cmd_buff[1] = 0;  /* play back starting at this address */
  1308. +         cmd_buff[2] = params[1];
  1309. +         cmd_buff[3] = params[2];
  1310. +         cmd_buff[4] = params[3];
  1311. +         cmd_buff[5] = SONY535_PLAY_AUDIO;
  1312. +         cmd_buff[6] = 2;  /* set ending address */
  1313. +         cmd_buff[7] = params[4];
  1314. +         cmd_buff[8] = params[5];
  1315. +         cmd_buff[9] = params[6];
  1316. +         if ( (do_sony_cmd( cmd_buff,5, status, NULL,0, 0 ) != 0 ) ||
  1317. +              (do_sony_cmd( cmd_buff+5,5, status, NULL,0, 0 ) != 0 ) )
  1318. +         {
  1319. +            printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
  1320. +                   params[2], params[3], params[4], params[5], params[6]);
  1321. +            printk("Sony CDROM error 0x%.2x (CDROMPLAYTRKIND)\n", status[0]);
  1322. +            return -EIO;
  1323. +         }
  1324. +         
  1325. +         /* Save the final position for pauses and resumes */
  1326. +         final_pos_msf[0] = params[4];
  1327. +         final_pos_msf[1] = params[5];
  1328. +         final_pos_msf[2] = params[6];
  1329. +         sony_audio_status = CDROM_AUDIO_PLAY;
  1330. +         return 0;
  1331. +      }
  1332. +     
  1333. +   case CDROMSUBCHNL:   /* Get subchannel info */
  1334. +      return sony_get_subchnl_info(arg);
  1335. +
  1336. +   case CDROMVOLCTRL:   /* Volume control.  What volume does this change, anyway? */
  1337. +      {
  1338. +         struct cdrom_volctrl volctrl;
  1339. +         
  1340. +         verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
  1341. +         
  1342. +         memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
  1343. +         cmd_buff[0] = SONY535_SET_VOLUME;
  1344. +         cmd_buff[1] = volctrl.channel0;
  1345. +         cmd_buff[2] = volctrl.channel1;
  1346. +         if ( do_sony_cmd( cmd_buff,3, status, NULL,0, 0 ) != 0 )
  1347. +         {
  1348. +            printk("Sony CDROM error 0x%.2x (CDROMVOLCTRL)\n", status[0]);
  1349. +            return -EIO;
  1350. +         }
  1351. +      }
  1352. +      return 0;
  1353. +
  1354. +   case CDROMEJECT:     /* Eject the drive */
  1355. +      cmd_buff[0] = SONY535_STOP;
  1356. +      do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1357. +      cmd_buff[0] = SONY535_SPIN_DOWN;
  1358. +      do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1359. +
  1360. +      sony_audio_status = CDROM_AUDIO_INVALID;
  1361. +      cmd_buff[0] = SONY535_EJECT_CADDY;
  1362. +      if ( do_sony_cmd( cmd_buff,1, status, NULL,0, 0 ) != 0 )
  1363. +      {
  1364. +         printk("Sony CDROM error 0x%.2x (CDROMEJECT)\n", status[0]);
  1365. +         return -EIO;
  1366. +      }
  1367. +      return 0;
  1368. +      break;
  1369. +     
  1370. +   default:
  1371. +      return -EINVAL;
  1372. +   }
  1373. +}
  1374. +
  1375. +
  1376. +/*
  1377. + * Open the drive for operations.  Spin the drive up and read the table of
  1378. + * contents if these have not already been done.
  1379. + */
  1380. +static int
  1381. +scd_open(struct inode *inode,
  1382. +         struct file *filp)
  1383. +{
  1384. +   unsigned char status[2], cmd_buff[2];
  1385. +
  1386. +
  1387. +   if ( sony_inuse )
  1388. +   {
  1389. +      return( -EBUSY );
  1390. +   }
  1391. +   
  1392. +   if ( check_drive_status() != 0 )
  1393. +   {
  1394. +      return( -EIO );
  1395. +   }
  1396. +      
  1397. +   sony_inuse = 1;
  1398. +   
  1399. +   if ( spin_up_drive( status ) != 0 )
  1400. +   {
  1401. +      printk("Sony CDROM error 0x%.2x (scd_open, spin up)\n", status[0]);
  1402. +      sony_inuse = 0;
  1403. +      return -EIO;
  1404. +   }
  1405. +      
  1406. +#if 0  /* what is this doing - CDU-535 does not have separate READ and REQ_TOC */
  1407. +   do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
  1408. +   if ((res_size < 2) || (res_reg[0] != 0))
  1409. +   {
  1410. +      /* If the drive is already playing, its ok. */
  1411. +      if (res_reg[1] == SONY_AUDIO_PLAYING_ERR)
  1412. +      {
  1413. +         goto drive_spinning;
  1414. +      }
  1415. +
  1416. +      printk("Sony CDROM error 0x%.2x (scd_open, read toc)\n", res_reg[1]);
  1417. +      do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
  1418. +      
  1419. +      sony_inuse = 0;
  1420. +      return -EIO;
  1421. +   }
  1422. +#endif
  1423. +
  1424. +   sony_get_toc();
  1425. +   if (!sony_toc_read)
  1426. +   {
  1427. +      cmd_buff[0] = SONY535_SPIN_DOWN;
  1428. +      do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1429. +      sony_inuse = 0;
  1430. +      return -EIO;
  1431. +   }
  1432. +      
  1433. +#if 0  /* not used without stuff read toc above */
  1434. +drive_spinning:
  1435. +#endif
  1436. +
  1437. +   if ( inode ) 
  1438. +   {
  1439. +      check_disk_change(inode->i_rdev);
  1440. +   }
  1441. +
  1442. +   sony_usage++;
  1443. +   
  1444. +#ifdef LOCK_DOORS
  1445. +    /* disable the eject button while mounted */
  1446. +   cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
  1447. +   do_sony_cmd( cmd_buff,1, status, NULL,0, 0 );
  1448. +#endif
  1449. +
  1450. +   return 0;
  1451. +}
  1452. +
  1453. +
  1454. +/*
  1455. + * Close the drive.  Spin it down if no task is using it.  The spin
  1456. + * down will fail if playing audio, so audio play is OK.
  1457. + */
  1458. +static void
  1459. +scd_release(struct inode *inode,
  1460. +         struct file *filp)
  1461. +{
  1462. +   unsigned char status[2], cmd_no;
  1463. +
  1464. +   sony_inuse = 0;
  1465. +
  1466. +   if (sony_usage > 0)
  1467. +   {
  1468. +      sony_usage--;
  1469. +   }
  1470. +   if (sony_usage == 0)
  1471. +   {
  1472. +      sync_dev(inode->i_rdev);
  1473. +      check_drive_status();
  1474. +
  1475. +      if ( sony_audio_status != CDROM_AUDIO_PLAY ) {
  1476. +         cmd_no = SONY535_SPIN_DOWN;
  1477. +         do_sony_cmd( &cmd_no,1, status, NULL,0, 0 );
  1478. +         }
  1479. +#ifdef LOCK_DOORS
  1480. +       /* enable the eject button after umount */
  1481. +      cmd_no = SONY535_ENABLE_EJECT_BUTTON;
  1482. +      do_sony_cmd( &cmd_no,1, status, NULL,0, 0 );
  1483. +#endif
  1484. +   }
  1485. +}
  1486. +
  1487. +
  1488. +static struct file_operations scd_fops = {
  1489. +   NULL,                   /* lseek - default */
  1490. +   block_read,             /* read - general block-dev read */
  1491. +   block_write,            /* write - general block-dev write */
  1492. +   NULL,                   /* readdir - bad */
  1493. +   NULL,                   /* select */
  1494. +   scd_ioctl,              /* ioctl */
  1495. +   NULL,                   /* mmap */
  1496. +   scd_open,               /* open */
  1497. +   scd_release             /* release */
  1498. +};
  1499. +
  1500. +
  1501. +/*
  1502. + * Initialize the driver.
  1503. + */
  1504. +unsigned long
  1505. +init_sony535(unsigned long mem_start, unsigned long mem_end)
  1506. +{
  1507. +   struct s535_sony_drive_config drive_config;
  1508. +   unsigned char cmd_buff[3], ret_buff[2];
  1509. +   unsigned char status[2];
  1510. +   int retry_count;
  1511. +
  1512. +
  1513. +   /* Set up all the register locations */
  1514. +   result_reg = sony_cd_base_io;
  1515. +   command_reg = sony_cd_base_io;
  1516. +   data_reg = sony_cd_base_io + 1;
  1517. +   read_status_reg = sony_cd_base_io + 2;
  1518. +   select_unit_reg = sony_cd_base_io + 3;
  1519. +
  1520. +    /* look for the CD-ROM, follows the procedure in the DOS driver */
  1521. +   inb( select_unit_reg );
  1522. +   retry_count = jiffies + 2*HZ;
  1523. +   while ( retry_count > jiffies )
  1524. +      sony_sleep();        /* wait for 40 18 Hz ticks (from DOS driver) */
  1525. +   inb( result_reg );
  1526. +   
  1527. +   outb( 0, read_status_reg );    /* does a reset? */
  1528. +   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
  1529. +   while ( retry_count > jiffies ) 
  1530. +   {
  1531. +      select_unit(0);
  1532. +      if ( inb( result_reg ) != 0xff )
  1533. +         break;
  1534. +      sony_sleep();  /* about 1-2 ms on my machine */
  1535. +   }
  1536. +   
  1537. +   if ( (retry_count > jiffies) && (check_drive_status() != TIME_OUT) ) 
  1538. +   {  
  1539. +       /* CD-ROM drive responded --  get the drive configuration */
  1540. +      cmd_buff[0] = SONY535_INQUIRY;
  1541. +      if ( do_sony_cmd( cmd_buff,1, status, (Byte *)&drive_config, 28, 1) == 0 ) 
  1542. +      {
  1543. +          /* was able to get the configuration, set drive mode as rest of init */
  1544. +         if ( (status[0] & 0x7f) != 0 )
  1545. +            printk("Inquiry command returned status = 0x%x\n",status[0]);
  1546. +         cmd_buff[0] = SONY535_SET_DRIVE_MODE;
  1547. +         cmd_buff[1] = 0x0;  /* default audio */
  1548. +         if (do_sony_cmd( cmd_buff,2, status, ret_buff,1, 1 ) == 0 ) 
  1549. +         {
  1550. +             /* set the drive mode successful, we are set! */
  1551. +            sony_buffer_size = SONY535_BUFFER_SIZE;
  1552. +            sony_buffer_sectors = sony_buffer_size / 2048;
  1553. +
  1554. +            printk("Sony I/F CDROM : %8.8s %16.16s %4.4s",
  1555. +                   drive_config.vendor_id,
  1556. +                   drive_config.product_id,
  1557. +                   drive_config.product_rev_level );
  1558. +            printk("  using %d byte buffer\n", sony_buffer_size);
  1559. +
  1560. +        if (register_blkdev(MAJOR_NR,"scd",&scd_fops)) {
  1561. +        printk("Unable to get major %d for sony CDU-535 cd\n",MAJOR_NR);
  1562. +        return( mem_start );
  1563. +        }
  1564. +            blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  1565. +            read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
  1566. +
  1567. +            sony_toc = (struct s535_sony_toc *) mem_start;
  1568. +            mem_start += sizeof(*sony_toc);
  1569. +            last_sony_subcode = (struct s535_sony_subcode *) mem_start;
  1570. +            mem_start += sizeof(*last_sony_subcode);
  1571. +            sony_buffer = (unsigned char *) mem_start;
  1572. +            mem_start += sony_buffer_size;
  1573. +
  1574. +            initialized = 1;
  1575. +         }
  1576. +      }
  1577. +   }
  1578. +
  1579. +   if ( !initialized )
  1580. +      printk( "Did not find a Sony CDU-535 drive\n");
  1581. +
  1582. +   return mem_start;
  1583. +}
  1584. +
  1585. +#endif  /* CONFIG_CDU535 */
  1586. diff -u --recursive --new-file linux-1.1.38/include/linux/sonycd535.h linux/include/linux/sonycd535.h
  1587. --- linux-1.1.38/include/linux/sonycd535.h    Wed Dec 31 18:00:00 1969
  1588. +++ linux/include/linux/sonycd535.h    Wed Aug  3 01:48:04 1994
  1589. @@ -0,0 +1,183 @@
  1590. +#ifndef SONYCD535_H
  1591. +#define SONYCD535_H
  1592. +
  1593. +/*
  1594. + * define all the commands recognized by the CDU-531/5
  1595. + */
  1596. +#define SONY535_REQUEST_DRIVE_STATUS_1        (0x80)
  1597. +#define SONY535_REQUEST_SENSE            (0x82)
  1598. +#define SONY535_REQUEST_DRIVE_STATUS_2        (0x84)
  1599. +#define SONY535_REQUEST_ERROR_STATUS        (0x86)
  1600. +#define SONY535_REQUEST_AUDIO_STATUS        (0x88)
  1601. +#define SONY535_INQUIRY                (0x8a)
  1602. +
  1603. +#define SONY535_SET_INACTIVITY_TIME        (0x90)
  1604. +
  1605. +#define SONY535_SEEK_AND_READ_N_BLOCKS_1    (0xa0)
  1606. +#define SONY535_SEEK_AND_READ_N_BLOCKS_2    (0xa4)
  1607. +#define SONY535_PLAY_AUDIO            (0xa6)
  1608. +
  1609. +#define SONY535_REQUEST_DISC_CAPACITY        (0xb0)
  1610. +#define SONY535_REQUEST_TOC_DATA        (0xb2)
  1611. +#define SONY535_REQUEST_SUB_Q_DATA        (0xb4)
  1612. +#define SONY535_REQUEST_ISRC            (0xb6)
  1613. +#define SONY535_REQUEST_UPC_EAN            (0xb8)
  1614. +
  1615. +#define SONY535_SET_DRIVE_MODE            (0xc0)
  1616. +#define SONY535_REQUEST_DRIVE_MODE        (0xc2)
  1617. +#define SONY535_SET_RETRY_COUNT            (0xc4)
  1618. +
  1619. +#define SONY535_DIAGNOSTIC_1            (0xc6)
  1620. +#define SONY535_DIAGNOSTIC_4            (0xcc)
  1621. +#define SONY535_DIAGNOSTIC_5            (0xce)
  1622. +
  1623. +#define SONY535_EJECT_CADDY            (0xd0)
  1624. +#define SONY535_DISABLE_EJECT_BUTTON        (0xd2)
  1625. +#define SONY535_ENABLE_EJECT_BUTTON        (0xd4)
  1626. +
  1627. +#define SONY535_HOLD                (0xe0)
  1628. +#define SONY535_AUDIO_PAUSE_ON_OFF        (0xe2)
  1629. +#define SONY535_SET_VOLUME            (0xe8)
  1630. +
  1631. +#define SONY535_STOP                (0xf0)
  1632. +#define SONY535_SPIN_UP                (0xf2)
  1633. +#define SONY535_SPIN_DOWN            (0xf4)
  1634. +
  1635. +#define SONY535_CLEAR_PARAMETERS        (0xf6)
  1636. +#define SONY535_CLEAR_ENDING_ADDRESS        (0xf8)
  1637. +
  1638. +/*
  1639. + * define some masks
  1640. + */
  1641. +#define SONY535_DATA_NOT_READY_BIT        (0x1)
  1642. +#define SONY535_RESULT_NOT_READY_BIT        (0x2)
  1643. +
  1644. +/*
  1645. + *  drive status 1
  1646. + */
  1647. +#define SONY535_STATUS1_COMMAND_ERROR        (0x1)
  1648. +#define SONY535_STATUS1_DATA_ERROR        (0x2)
  1649. +#define SONY535_STATUS1_SEEK_ERROR        (0x4)
  1650. +#define SONY535_STATUS1_DISC_TYPE_ERROR        (0x8)
  1651. +#define SONY535_STATUS1_NOT_SPINNING        (0x10)
  1652. +#define SONY535_STATUS1_EJECT_BUTTON_PRESSED    (0x20)
  1653. +#define SONY535_STATUS1_CADDY_NOT_INSERTED    (0x40)
  1654. +#define SONY535_STATUS1_BYTE_TWO_FOLLOWS    (0x80)
  1655. +
  1656. +/*
  1657. + * drive status 2
  1658. + */
  1659. +#define SONY535_CDD_LOADING_ERROR        (0x7)
  1660. +#define SONY535_CDD_NO_DISC            (0x8)
  1661. +#define SONY535_CDD_UNLOADING_ERROR        (0x9)
  1662. +#define SONY535_CDD_CADDY_NOT_INSERTED        (0xd)
  1663. +#define SONY535_ATN_RESET_OCCURRED        (0x2)
  1664. +#define SONY535_ATN_DISC_CHANGED        (0x4)
  1665. +#define SONY535_ATN_RESET_AND_DISC_CHANGED    (0x6)
  1666. +#define SONY535_ATN_EJECT_IN_PROGRESS        (0xe)
  1667. +#define SONY535_ATN_BUSY            (0xf)
  1668. +
  1669. +/*
  1670. + * define some parameters
  1671. + */
  1672. +#define SONY535_AUDIO_DRIVE_MODE        (0)
  1673. +#define SONY535_CDROM_DRIVE_MODE        (0xe0)
  1674. +
  1675. +#define SONY535_PLAY_OP_PLAYBACK        (0)
  1676. +#define SONY535_PLAY_OP_ENTER_HOLD        (1)
  1677. +#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR    (2)
  1678. +#define SONY535_PLAY_OP_SCAN_FORWARD        (3)
  1679. +#define SONY535_PLAY_OP_SCAN_BACKWARD        (4)
  1680. +
  1681. +/*
  1682. + *  convert from msf format to block number 
  1683. + */
  1684. +#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f))
  1685. +#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2])
  1686. +
  1687. +/*
  1688. + *  error return values from the doSonyCmd() routines
  1689. + */
  1690. +#define TIME_OUT            (-1)
  1691. +#define NO_CDROM            (-2)
  1692. +#define BAD_STATUS            (-3)
  1693. +#define CD_BUSY                (-4)
  1694. +#define NOT_DATA_CD            (-5)
  1695. +#define NO_ROOM                (-6)
  1696. +
  1697. +#define LOG_START_OFFSET        150     /* Offset of first logical sector */
  1698. +
  1699. +#define SONY_JIFFIES_TIMEOUT            500  /* Maximum number of jiffies (10ms)
  1700. +                                                  the drive will wait/try for an
  1701. +                                                  operation */
  1702. +#define SONY_READY_RETRIES      (50000)  /* How many times to retry a
  1703. +                                                  spin waiting for a register
  1704. +                                                  to come ready */
  1705. +#define SONY535_FAST_POLLS    (10000)   /* how many times recheck 
  1706. +                                                  status waiting for a data
  1707. +                                                  to become ready */
  1708. +
  1709. +typedef unsigned char Byte;
  1710. +
  1711. +/*
  1712. + * This is the complete status returned from the drive configuration request
  1713. + * command.
  1714. + */
  1715. +struct s535_sony_drive_config
  1716. +{
  1717. +   char vendor_id[8];
  1718. +   char product_id[16];
  1719. +   char product_rev_level[4];
  1720. +};
  1721. +
  1722. +/* The following is returned from the request sub-q data command */
  1723. +struct s535_sony_subcode
  1724. +{
  1725. +   unsigned char address        :4;
  1726. +   unsigned char control        :4;
  1727. +   unsigned char track_num;
  1728. +   unsigned char index_num;
  1729. +   unsigned char rel_msf[3];
  1730. +   unsigned char abs_msf[3];
  1731. +};
  1732. +
  1733. +struct s535_sony_disc_capacity
  1734. +{
  1735. +   Byte mFirstTrack, sFirstTrack, fFirstTrack;
  1736. +   Byte mLeadOut, sLeadOut, fLeadOut;
  1737. +};
  1738. +
  1739. +/*
  1740. + * The following is returned from the request TOC (Table Of Contents) command.
  1741. + * (last_track_num-first_track_num+1) values are valid in tracks.
  1742. + */
  1743. +struct s535_sony_toc
  1744. +{
  1745. +   unsigned char reserved0      :4;
  1746. +   unsigned char control0       :4;
  1747. +   unsigned char point0;
  1748. +   unsigned char first_track_num;
  1749. +   unsigned char reserved0a;
  1750. +   unsigned char reserved0b;
  1751. +   unsigned char reserved1      :4;
  1752. +   unsigned char control1       :4;
  1753. +   unsigned char point1;
  1754. +   unsigned char last_track_num;
  1755. +   unsigned char dummy1;
  1756. +   unsigned char dummy2;
  1757. +   unsigned char reserved2      :4;
  1758. +   unsigned char control2       :4;
  1759. +   unsigned char point2;
  1760. +   unsigned char lead_out_start_msf[3];
  1761. +   struct
  1762. +   {
  1763. +      unsigned char reserved    :4;
  1764. +      unsigned char control     :4;
  1765. +      unsigned char track;
  1766. +      unsigned char track_start_msf[3];
  1767. +   } tracks[100];
  1768. +
  1769. +   unsigned int lead_out_start_lba;
  1770. +};
  1771. +
  1772. +#endif /* SONYCD535_H */
  1773.