home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / kernel-s / sony535-.5 / sony535-.000 < prev    next >
Text File  |  1995-10-10  |  61KB  |  1,873 lines

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