dvd-2.2.13-5.diff
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:291k
源码类别:

DVD

开发平台:

Unix_Linux

  1.    IDE_COMMAND_REG);
  2.   case ide_dma_begin:
  3. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
  4. --- linux-2.2.13/drivers/block/ide-tape.c Thu Sep  9 12:27:35 1999
  5. +++ linux/drivers/block/ide-tape.c Sun Nov  7 15:18:54 1999
  6. @@ -1829,7 +1829,7 @@
  7.   if (temp > pc->buffer_size) {
  8.   printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding datan");
  9.   idetape_discard_data (drive,bcount.all);
  10. - ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD);
  11. + ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);
  12.   return;
  13.   }
  14.  #if IDETAPE_DEBUG_LOG
  15. @@ -1851,7 +1851,7 @@
  16.   pc->actually_transferred+=bcount.all; /* Update the current position */
  17.   pc->current_position+=bcount.all;
  18.  
  19. - ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD); /* And set the interrupt handler again */
  20. + ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL); /* And set the interrupt handler again */
  21.  }
  22.  
  23.  /*
  24. @@ -1924,7 +1924,7 @@
  25.   ide_do_reset (drive);
  26.   return;
  27.   }
  28. - ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD); /* Set the interrupt routine */
  29. + ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
  30.   atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */
  31.  }
  32.  
  33. @@ -1990,7 +1990,7 @@
  34.   }
  35.  #endif /* CONFIG_BLK_DEV_IDEDMA */
  36.   if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
  37. - ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD);
  38. + ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
  39.   OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
  40.   } else {
  41.   OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
  42. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/ide.c linux/drivers/block/ide.c
  43. --- linux-2.2.13/drivers/block/ide.c Fri Nov  5 15:15:33 1999
  44. +++ linux/drivers/block/ide.c Sun Nov  7 15:28:05 1999
  45. @@ -466,7 +466,8 @@
  46.   * timer is started to prevent us from waiting forever in case
  47.   * something goes wrong (see the ide_timer_expiry() handler later on).
  48.   */
  49. -void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout)
  50. +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
  51. +       unsigned int timeout, ide_expiry_t *expiry)
  52.  {
  53.   unsigned long flags;
  54.   ide_hwgroup_t *hwgroup = HWGROUP(drive);
  55. @@ -478,8 +479,9 @@
  56.   drive->name, hwgroup->handler, handler);
  57.   }
  58.  #endif
  59. - hwgroup->handler       = handler;
  60. - hwgroup->timer.expires = jiffies + timeout;
  61. + hwgroup->handler = handler;
  62. + hwgroup->expiry = expiry;
  63. + hwgroup->timer.expires = jiffies + timeout;
  64.   add_timer(&(hwgroup->timer));
  65.   spin_unlock_irqrestore(&hwgroup->spinlock, flags);
  66.  }
  67. @@ -536,7 +538,7 @@
  68.   printk("%s: ATAPI reset completen", drive->name);
  69.   } else {
  70.   if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
  71. - ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
  72. + ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
  73.   return; /* continue polling */
  74.   }
  75.   hwgroup->poll_timeout = 0; /* end of polling */
  76. @@ -561,7 +563,7 @@
  77.  
  78.   if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
  79.   if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
  80. - ide_set_handler (drive, &reset_pollfunc, HZ/20);
  81. + ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
  82.   return; /* continue polling */
  83.   }
  84.   printk("%s: reset timed-out, status=0x%02xn", hwif->name, tmp);
  85. @@ -640,7 +642,7 @@
  86.   udelay (20);
  87.   OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
  88.   hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
  89. - ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
  90. + ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
  91.   __restore_flags (flags); /* local CPU only */
  92.   return;
  93.   }
  94. @@ -666,7 +668,7 @@
  95.   OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
  96.   udelay(10); /* more than enough time */
  97.   hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
  98. - ide_set_handler (drive, &reset_pollfunc, HZ/20);
  99. + ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
  100.  #endif /* OK_TO_RESET_CONTROLLER */
  101.  
  102.   __restore_flags (flags); /* local CPU only */
  103. @@ -857,7 +859,7 @@
  104.   */
  105.  void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
  106.  {
  107. - ide_set_handler (drive, handler, WAIT_CMD);
  108. + ide_set_handler (drive, handler, WAIT_CMD, NULL);
  109.   OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
  110.   OUT_BYTE(nsect,IDE_NSECTOR_REG);
  111.   OUT_BYTE(cmd,IDE_COMMAND_REG);
  112. @@ -1286,7 +1288,9 @@
  113.   ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
  114.   ide_drive_t   *drive;
  115.   ide_handler_t *handler;
  116. + ide_expiry_t  *expiry;
  117.   unsigned long flags;
  118. + unsigned long wait;
  119.  
  120.   spin_lock_irqsave(&hwgroup->spinlock, flags);
  121.   drive = hwgroup->drive;
  122. @@ -1295,10 +1299,23 @@
  123.   do_hwgroup_request(hwgroup);
  124.   return;
  125.   }
  126. +
  127.   hwgroup->busy = 1; /* should already be "1" */
  128. +
  129. + if ((expiry = hwgroup->expiry) != NULL) {
  130. + /* continue */
  131. + if ((wait = expiry(drive)) != 0) {
  132. + /* reset timer */
  133. + hwgroup->timer.expires = jiffies + wait;
  134. + add_timer(&(hwgroup->timer));
  135. + spin_unlock_irqrestore(&hwgroup->spinlock, flags);
  136. + return;
  137. + }
  138. + }
  139. +
  140.   hwgroup->handler = NULL;
  141. - del_timer(&hwgroup->timer); /* Is this needed?? */
  142. - if (hwgroup->poll_timeout != 0) { /* polling in progress? */
  143. + /* polling in progress or just don't timeout */
  144. + if (hwgroup->poll_timeout != 0) {
  145.   spin_unlock_irqrestore(&hwgroup->spinlock, flags);
  146.   handler(drive);
  147.   } else if (drive_is_ready(drive)) {
  148. @@ -1539,13 +1556,10 @@
  149.   }
  150.   spin_unlock_irqrestore(&io_request_lock, flags);
  151.   do_hwgroup_request(hwgroup);
  152. - save_flags(flags); /* all CPUs; overkill? */
  153. - cli(); /* all CPUs; overkill? */
  154.   if (action == ide_wait)
  155.   {
  156.   down(&sem); /* wait for it to be serviced */
  157.   }
  158. - restore_flags(flags); /* all CPUs; overkill? */
  159.   return rq->errors ? -EIO : 0; /* return -EIO if errors */
  160.  }
  161.  
  162. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/ide.h linux/drivers/block/ide.h
  163. --- linux-2.2.13/drivers/block/ide.h Sun Mar 28 20:03:35 1999
  164. +++ linux/drivers/block/ide.h Sun Nov  7 15:26:07 1999
  165. @@ -357,6 +357,12 @@
  166.   */
  167.  typedef void (ide_handler_t)(ide_drive_t *);
  168.  
  169. +/*
  170. + * when ide_timer_expiry fires, invoke a handler of this type
  171. + * to decide what to do.
  172. + */
  173. +typedef int (ide_expiry_t)(ide_drive_t *);
  174. +
  175.  typedef struct hwgroup_s {
  176.   spinlock_t spinlock; /* protects "busy" and "handler" */
  177.   ide_handler_t *handler;/* irq handler, if active */
  178. @@ -367,6 +373,7 @@
  179.   struct timer_list timer; /* failsafe timer */
  180.   struct request wrq; /* local copy of current write rq */
  181.   unsigned long poll_timeout; /* timeout value during long polls */
  182. + ide_expiry_t *expiry; /* queried upon timeouts */
  183.   } ide_hwgroup_t;
  184.  
  185.  /*
  186. @@ -536,7 +543,7 @@
  187.   * This is used on exit from the driver, to designate the next irq handler
  188.   * and also to start the safety timer.
  189.   */
  190. -void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout);
  191. +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
  192.  
  193.  /*
  194.   * Error reporting, in human readable form (luxurious, but a memory hog).
  195. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
  196. --- linux-2.2.13/drivers/block/paride/pcd.c Wed Nov  4 19:03:01 1998
  197. +++ linux/drivers/block/paride/pcd.c Sun Oct 31 13:23:55 1999
  198. @@ -143,8 +143,8 @@
  199.  #include <linux/delay.h>
  200.  #include <linux/cdrom.h>
  201.  
  202. -#include <asm/uaccess.h>
  203.  #include <asm/spinlock.h>
  204. +#include <asm/uaccess.h>
  205.  
  206.  #ifndef MODULE
  207.  
  208. @@ -214,8 +214,11 @@
  209.  static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
  210.  static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
  211.   unsigned int cmd, void *arg);
  212. +static int pcd_packet(struct cdrom_device_info *cdi,
  213. + struct cdrom_generic_command *cgc);
  214.  
  215.  static int  pcd_detect(void);
  216. +static void  pcd_probe_capabilities(void);
  217.  static void     do_pcd_read_drq(void);
  218.  static void  do_pcd_request(void);
  219.  static void  do_pcd_read(void);
  220. @@ -276,14 +279,18 @@
  221.   pcd_drive_reset,
  222.   pcd_audio_ioctl,
  223.   0, /* dev_ioctl */
  224. - CDC_CLOSE_TRAY    |
  225. - CDC_OPEN_TRAY     |
  226. - CDC_LOCK          |
  227. - CDC_MCN   |
  228. - CDC_MEDIA_CHANGED |
  229. - CDC_RESET   |
  230. - CDC_PLAY_AUDIO,
  231. - 0
  232. + CDC_CLOSE_TRAY    |
  233. + CDC_OPEN_TRAY    |
  234. + CDC_LOCK    |
  235. + CDC_MCN    |
  236. + CDC_MEDIA_CHANGED  |
  237. + CDC_RESET    |
  238. + CDC_PLAY_AUDIO    |
  239. + CDC_GENERIC_PACKET |
  240. + CDC_CD_R    |
  241. + CDC_CD_RW,
  242. + 0,
  243. + pcd_packet,
  244.  };
  245.  
  246.  static void pcd_init_units( void )
  247. @@ -325,6 +332,9 @@
  248.  
  249.   if (pcd_detect()) return -1;
  250.  
  251. + /* get the atapi capabilities page */
  252. + pcd_probe_capabilities();
  253. +
  254.   if (register_blkdev(MAJOR_NR,name,&cdrom_fops)) {
  255.   printk("pcd: unable to get major number %dn",MAJOR_NR);
  256.   return -1;
  257. @@ -525,6 +535,16 @@
  258.   return r;
  259.  }
  260.  
  261. +static int pcd_packet(struct cdrom_device_info *cdi,
  262. + struct cdrom_generic_command *cgc)
  263. +{
  264. + char *un_cmd;
  265. + int unit = DEVICE_NR(cdi->dev);
  266. +
  267. + un_cmd = cgc->cmd;
  268. + return pcd_atapi(unit,un_cmd,cgc->buflen,cgc->buffer, "generic packet");
  269. +}
  270. +
  271.  #define DBMSG(msg) ((verbose>1)?(msg):NULL)
  272.  
  273.  static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
  274. @@ -667,6 +687,32 @@
  275.   return -1;
  276.  }
  277.  
  278. +static void pcd_probe_capabilities( void )
  279. +
  280. +{ int unit, r;
  281. + char buffer[32];
  282. + char  cmd[12]={0x5a,1<<3,0x2a,0,0,0,0,18,0,0,0,0};
  283. +
  284. + for (unit=0;unit<PCD_UNITS;unit++) {
  285. + if (!PCD.present) continue;
  286. + r = pcd_atapi(unit,cmd,18, buffer,"mode sense capabilities");
  287. + if (r) continue;
  288. + /* we should now have the cap page */
  289. + if ((buffer[11] & 1) == 0)
  290. + PCD.info.mask |= CDC_CD_R;
  291. + if ((buffer[11] & 2) == 0)
  292. + PCD.info.mask |= CDC_CD_RW;
  293. + if ((buffer[12] & 1) == 0)
  294. + PCD.info.mask |= CDC_PLAY_AUDIO;
  295. + if ((buffer[14] & 1) == 0)
  296. + PCD.info.mask |= CDC_LOCK;
  297. + if ((buffer[14] & 8) == 0)
  298. + PCD.info.mask |= CDC_OPEN_TRAY;
  299. + if ((buffer[14] >> 6) == 0)
  300. + PCD.info.mask |= CDC_CLOSE_TRAY;
  301. + }
  302. +}
  303. +
  304.  static int pcd_detect( void )
  305.  
  306.  { char    id[18];
  307. @@ -836,66 +882,9 @@
  308.   
  309.       switch (cmd) { 
  310.      
  311. - case CDROMPAUSE: 
  312. -
  313. - {       char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,0,0,0,0};
  314. -
  315. - return (pcd_atapi(unit,cmd,0,NULL,"pause")) * EIO;
  316. - }
  317. -
  318. - case CDROMRESUME:
  319. -
  320. - {       char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,1,0,0,0};
  321. -
  322. - return (pcd_atapi(unit,cmd,0,NULL,"resume")) * EIO;
  323. - }
  324. -
  325. - case CDROMPLAYMSF:
  326. -
  327. - { char cmd[12]={SCMD_PLAYAUDIO_MSF,0,0,0,0,0,0,0,0,0,0,0};
  328. - struct cdrom_msf* msf = (struct cdrom_msf*)arg;
  329. -
  330. - cmd[3] = msf->cdmsf_min0;
  331. - cmd[4] = msf->cdmsf_sec0;
  332. - cmd[5] = msf->cdmsf_frame0;
  333. - cmd[6] = msf->cdmsf_min1;
  334. - cmd[7] = msf->cdmsf_sec1;
  335. - cmd[8] = msf->cdmsf_frame1;
  336. -
  337. - return (pcd_atapi(unit,cmd,0,NULL,"play msf")) * EIO;
  338. -     }
  339. -
  340. -     case CDROMPLAYBLK:
  341. -
  342. -     { char cmd[12]={SCMD_PLAYAUDIO10,0,0,0,0,0,0,0,0,0,0,0};
  343. - struct cdrom_blk* blk = (struct cdrom_blk*)arg;
  344. -
  345. - cmd[2] = blk->from >> 24;
  346. - cmd[3] = blk->from >> 16;
  347. - cmd[4] = blk->from >> 8;
  348. - cmd[5] = blk->from;
  349. - cmd[7] = blk->len >> 8;
  350. - cmd[8] = blk->len;
  351. -
  352. - return (pcd_atapi(unit,cmd,0,NULL,"play block")) * EIO;
  353. -     }
  354. -
  355. -     case CDROMPLAYTRKIND:
  356. -
  357. -     { char cmd[12]={SCMD_PLAYAUDIO_TI,0,0,0,0,0,0,0,0,0,0,0};
  358. - struct cdrom_ti* ti = (struct cdrom_ti*)arg;
  359. -
  360. - cmd[4] = ti->cdti_trk0;
  361. - cmd[5] = ti->cdti_ind0;
  362. - cmd[7] = ti->cdti_trk1;
  363. - cmd[8] = ti->cdti_ind1;
  364. -
  365. - return (pcd_atapi(unit,cmd,0,NULL,"play track")) * EIO;
  366. -     }
  367. -
  368.       case CDROMREADTOCHDR:
  369.      
  370. - { char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
  371. + { char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
  372.   struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
  373.   char buffer[32];
  374.   int r;
  375. @@ -910,7 +899,7 @@
  376.  
  377.       case CDROMREADTOCENTRY:
  378.  
  379. -     { char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
  380. +     { char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
  381.  
  382.   struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
  383.   unsigned char buffer[32];
  384. @@ -936,97 +925,6 @@
  385.                  return r * EIO;
  386.          }
  387.  
  388. -     case CDROMSTOP:
  389. -
  390. - { char cmd[12]={0x1b,1,0,0,0,0,0,0,0,0,0,0};
  391. -
  392. -                return (pcd_atapi(unit,cmd,0,NULL,"stop")) * EIO;
  393. -        }                                                         
  394. -
  395. -     case CDROMSTART:
  396. -
  397. -        {       char cmd[12]={0x1b,1,0,0,1,0,0,0,0,0,0,0};
  398. -
  399. -                return (pcd_atapi(unit,cmd,0,NULL,"start")) * EIO;
  400. -        } 
  401. -
  402. -     case CDROMVOLCTRL:
  403. -
  404. - { char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
  405. - char buffer[32];
  406. - char mask[32];
  407. - struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
  408. -
  409. - cmd[2] = 0xe;
  410. - cmd[4] = 28;
  411. -
  412. -                if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol")) 
  413. - return -EIO;
  414. -
  415. - cmd[2] = 0x4e;
  416. -
  417. - if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol mask"))
  418. - return -EIO;
  419. -
  420. - buffer[0] = 0;
  421. -
  422. - buffer[21] = volctrl->channel0 & mask[21];
  423. - buffer[23] = volctrl->channel1 & mask[23];
  424. - buffer[25] = volctrl->channel2 & mask[25];
  425. - buffer[27] = volctrl->channel3 & mask[27];
  426. -
  427. - cmd[0] = 0x55;
  428. - cmd[1] = 0x10;
  429. -
  430. - return pcd_atapi(unit,cmd,28,buffer,"mode select vol") * EIO;
  431. -     }
  432. -
  433. -     case CDROMVOLREAD:
  434. -
  435. -        {       char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
  436. -                char buffer[32];
  437. -                struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
  438. -                int     r;
  439. -
  440. -                cmd[2] = 0xe;
  441. -                cmd[4] = 28;
  442. -
  443. -                r = pcd_atapi(unit,cmd,28,buffer,"mode sense vol read");
  444. -
  445. - volctrl->channel0 = buffer[21];
  446. - volctrl->channel1 = buffer[23];
  447. - volctrl->channel2 = buffer[25];
  448. - volctrl->channel3 = buffer[27];
  449. -
  450. -                return r * EIO;
  451. -        }
  452. -  
  453. -
  454. -     case CDROMSUBCHNL:
  455. -
  456. - { char cmd[12]={SCMD_READ_SUBCHANNEL,2,0x40,1,0,0,0,0,16,0,0,0};
  457. - struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
  458. - char buffer[32];
  459. -
  460. -                if (pcd_atapi(unit,cmd,16,buffer,"read subchannel"))
  461. -                        return -EIO;
  462. -   
  463. - subchnl->cdsc_audiostatus = buffer[1];
  464. - subchnl->cdsc_format = CDROM_MSF;
  465. - subchnl->cdsc_ctrl = buffer[5] & 0xf;
  466. - subchnl->cdsc_trk = buffer[6];
  467. - subchnl->cdsc_ind = buffer[7];
  468. -
  469. - subchnl->cdsc_reladdr.msf.minute = buffer[13];
  470. - subchnl->cdsc_reladdr.msf.second = buffer[14];
  471. - subchnl->cdsc_reladdr.msf.frame = buffer[15];
  472. - subchnl->cdsc_absaddr.msf.minute = buffer[9];
  473. - subchnl->cdsc_absaddr.msf.second = buffer[10];
  474. - subchnl->cdsc_absaddr.msf.frame = buffer[11];
  475. -
  476. - return 0;
  477. -     }
  478. -
  479.       default:
  480.  
  481.           return -ENOSYS;
  482. @@ -1035,7 +933,7 @@
  483.  
  484.  static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
  485.  
  486. -{ char  cmd[12]={SCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
  487. +{ char  cmd[12]={GPCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
  488.          char  buffer[32];
  489.   int k;
  490.   int unit = DEVICE_NR(cdi->dev);
  491. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/pdc4030.c linux/drivers/block/pdc4030.c
  492. --- linux-2.2.13/drivers/block/pdc4030.c Tue Dec 29 20:24:57 1998
  493. +++ linux/drivers/block/pdc4030.c Sun Nov  7 15:22:28 1999
  494. @@ -239,7 +239,7 @@
  495.   if(stat & DRQ_STAT)
  496.       goto read_again;
  497.   if(stat & BUSY_STAT) {
  498. -     ide_set_handler (drive, &promise_read_intr, WAIT_CMD);
  499. +     ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL);
  500.       return;
  501.   }
  502.   printk("Ah! promise read intr: sectors left !DRQ !BUSYn");
  503. @@ -258,7 +258,7 @@
  504.  
  505.          if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
  506.              if (time_before(jiffies, hwgroup->poll_timeout)) {
  507. -                ide_set_handler (drive, &promise_write_pollfunc, 1);
  508. +                ide_set_handler (drive, &promise_write_pollfunc, 1, NULL);
  509.                  return; /* continue polling... */
  510.              }
  511.              printk("%s: write timed-out!n",drive->name);
  512. @@ -292,7 +292,7 @@
  513.      if (rq->nr_sectors > 4) {
  514.          ide_multwrite(drive, rq->nr_sectors - 4);
  515.          hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
  516. -        ide_set_handler (drive, &promise_write_pollfunc, 1);
  517. +        ide_set_handler (drive, &promise_write_pollfunc, 1, NULL);
  518.          return;
  519.      } else {
  520.          ide_multwrite(drive, rq->nr_sectors);
  521. @@ -315,7 +315,7 @@
  522.   byte stat;
  523.  
  524.   if (rq->cmd == READ) {
  525. -     ide_set_handler(drive, &promise_read_intr, WAIT_CMD);
  526. +     ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
  527.       OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
  528.  /* The card's behaviour is odd at this point. If the data is
  529.     available, DRQ will be true, and no interrupt will be
  530. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/block/trm290.c linux/drivers/block/trm290.c
  531. --- linux-2.2.13/drivers/block/trm290.c Sat Aug  8 02:56:09 1998
  532. +++ linux/drivers/block/trm290.c Sun Nov  7 15:22:45 1999
  533. @@ -193,7 +193,7 @@
  534.   outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
  535.   if (drive->media != ide_disk)
  536.   return 0;
  537. - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
  538. + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
  539.   OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
  540.   return 0;
  541.   case ide_dma_begin:
  542. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
  543. --- linux-2.2.13/drivers/cdrom/cdrom.c Fri Nov  5 15:15:34 1999
  544. +++ linux/drivers/cdrom/cdrom.c Thu Nov  4 13:20:03 1999
  545. @@ -1,7 +1,7 @@
  546.  /* linux/drivers/cdrom/cdrom.c. 
  547.     Copyright (c) 1996, 1997 David A. van Leeuwen.
  548.     Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
  549. -   Copyright (c) 1998, 1999 Jens Axboe
  550. +   Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
  551.  
  552.     May be copied or modified under the terms of the GNU General Public
  553.     License.  See linux/COPYING for more information.
  554. @@ -22,12 +22,6 @@
  555.   based tunable parameters such as whether the tray should auto-close for
  556.   that drive. Suggestions (or patches) for this welcome!
  557.  
  558. - -- Change the CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, and 
  559. - CDROMREADRAW ioctls so they go through the Uniform CD-ROM driver.
  560. - -- Sync options and capability flags.
  561. -
  562.  
  563.   Revision History
  564.   ----------------------------------
  565. @@ -126,14 +120,77 @@
  566.    CDC_CLOSE_TRAY.
  567.    -- proc info didn't mask against capabilities mask.
  568.    
  569. -  2.56 Sep 9, 1999 - Jens Axboe <axboe@image.dk>
  570. -  -- Define CDROM_CAN() for checking capabilities.
  571. -  -- Fix up capability reporting, for proc and ioctl.
  572. -
  573. +  3.00 Aug 5, 1999 - Jens Axboe <axboe@image.dk>
  574. +  -- Unified audio ioctl handling across CD-ROM drivers. A lot of the
  575. +  code was duplicated before. Drives that support the generic packet
  576. +  interface are now being fed packets from here instead.
  577. +  -- First attempt at adding support for MMC2 commands - for DVD and
  578. +  CD-R(W) drives. Only the DVD parts are in now - the interface used is
  579. +  the same as for the audio ioctls.
  580. +  -- ioctl cleanups. if a drive couldn't play audio, it didn't get
  581. +  a change to perform device specific ioctls as well.
  582. +  -- Defined CDROM_CAN(CDC_XXX) for checking the capabilities.
  583. +  -- Put in sysctl files for autoclose, autoeject, check_media, debug,
  584. +  and lock.
  585. +  -- /proc/sys/dev/cdrom/info has been updated to also contain info about
  586. +  CD-Rx and DVD capabilities.
  587. +  -- Now default to checking media type.
  588. +  -- CDROM_SEND_PACKET ioctl added. The infrastructure was in place for
  589. +  doing this anyway, with the generic_packet addition.
  590. +  
  591. +  3.01 Aug 6, 1999 - Jens Axboe <axboe@image.dk>
  592. +  -- Fix up the sysctl handling so that the option flags get set
  593. +  correctly.
  594. +  -- Fix up ioctl handling so the device specific ones actually get
  595. +  called :).
  596. +  
  597. +  3.02 Aug 8, 1999 - Jens Axboe <axboe@image.dk>
  598. +  -- Fixed volume control on SCSI drives (or others with longer audio
  599. +  page).
  600. +  -- Fixed a couple of DVD minors. Thanks to Andrew T. Veliath
  601. +  <andrewtv@usa.net> for telling me and for having defined the various
  602. +  DVD structures and ioctls in the first place! He designed the original
  603. +  DVD patches for ide-cd and while I rearranged and unified them, the
  604. +  interface is still the same.
  605. +  
  606. +  3.03 Sep 1, 1999 - Jens Axboe <axboe@image.dk>
  607. +  -- Moved the rest of the audio ioctls from the CD-ROM drivers here. Only
  608. +  CDROMREADTOCENTRY and CDROMREADTOCHDR are left.
  609. +  -- Moved the CDROMREADxxx ioctls in here.
  610. +  -- Defined the cdrom_get_last_written and cdrom_get_next_block as ioctls
  611. +  and exported functions.
  612. +  -- Erik Andersen <andersen@xmission.com> modified all SCMD_ commands
  613. +  to now read GPCMD_ for the new generic packet interface. All low level
  614. +  drivers are updated as well.
  615. +  -- Various other cleanups.
  616. +
  617. +  3.04 Sep 12, 1999 - Jens Axboe <axboe@image.dk>
  618. +  -- Fixed a couple of possible memory leaks (if an operation failed and
  619. +  we didn't free the buffer before returning the error).
  620. +  -- Integrated Uniform CD Changer handling from Richard Sharman
  621. +  <rsharman@pobox.com>.
  622. +  -- Defined CD_DVD and CD_CHANGER log levels.
  623. +  -- Fixed the CDROMREADxxx ioctls.
  624. +  -- CDROMPLAYTRKIND uses the GPCMD_PLAY_AUDIO_MSF command - too few
  625. +  drives supported it. We loose the index part, however.
  626. +  -- Small modifications to accomodate opens of /dev/hdc1, required
  627. +  for ide-cd to handle multisession discs.
  628. +  -- Export cdrom_mode_sense and cdrom_mode_select.
  629. +  -- init_cdrom_command() for setting up a cgc command.
  630. +  
  631. +  3.05 Oct 24, 1999 - Jens Axboe <axboe@image.dk>
  632. +  -- Changed the interface for CDROM_SEND_PACKET. Before it was virtually
  633. +  impossible to send the drive data in a sensible way.
  634. +  -- Lowered stack usage in mmc_ioctl(), dvd_read_disckey(), and
  635. +  dvd_read_manufact.
  636. +  -- Added setup of write mode for packet writing.
  637. +  -- Fixed CDDA ripping with cdda2wav - accept much larger requests of
  638. +  number of frames and split the reads in blocks of 8.
  639. +  
  640.  -------------------------------------------------------------------------*/
  641.  
  642. -#define REVISION "Revision: 2.56"
  643. -#define VERSION "Id: cdrom.c 2.56 1999/09/09"
  644. +#define REVISION "Revision: 3.05"
  645. +#define VERSION "Id: cdrom.c 3.05 1999/10/24"
  646.  
  647.  /* I use an error-log mask to give fine grain control over the type of
  648.     messages dumped to the system logs.  The available masks include: */
  649. @@ -144,6 +201,8 @@
  650.  #define CD_OPEN 0x8
  651.  #define CD_CLOSE 0x10
  652.  #define CD_COUNT_TRACKS 0x20
  653. +#define CD_CHANGER 0x40
  654. +#define CD_DVD 0x80
  655.  
  656.  /* Define this to remove _all_ the debugging messages */
  657.  /* #define ERRLOGMASK CD_NOTHING */
  658. @@ -151,7 +210,6 @@
  659.  /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
  660.  /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
  661.  
  662. -
  663.  #include <linux/config.h>
  664.  #include <linux/module.h>
  665.  #include <linux/fs.h>
  666. @@ -164,6 +222,7 @@
  667.  #include <linux/cdrom.h>
  668.  #include <linux/sysctl.h>
  669.  #include <linux/proc_fs.h>
  670. +#include <linux/init.h>
  671.  #include <asm/fcntl.h>
  672.  #include <asm/segment.h>
  673.  #include <asm/uaccess.h>
  674. @@ -176,6 +235,7 @@
  675.  static int autoclose=1;
  676.  static int autoeject=0;
  677.  static int lockdoor = 1;
  678. +/* will we ever get to use this... sigh. */
  679.  static int check_media_type = 0;
  680.  MODULE_PARM(debug, "i");
  681.  MODULE_PARM(autoclose, "i");
  682. @@ -202,7 +262,8 @@
  683.     a lot of places. This macro makes the code more clear. */
  684.  #define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & type)
  685.  
  686. -#define FM_WRITE 0x2                 /* file mode write bit */
  687. +/* used in the audio ioctls */
  688. +#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
  689.  
  690.  /* Not-exported routines. */
  691.  static int cdrom_open(struct inode *ip, struct file *fp);
  692. @@ -215,6 +276,12 @@
  693.    struct cdrom_device_ops * cdo);
  694.  static void sanitize_format(union cdrom_addr *addr, 
  695.   u_char * curr, u_char requested);
  696. +static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
  697. +      unsigned long arg);
  698. +
  699. +int cdrom_get_last_written(kdev_t dev, long *last_written);
  700. +int cdrom_get_next_writable(kdev_t dev, long *next_writable);
  701. +
  702.  #ifdef CONFIG_SYSCTL
  703.  static void cdrom_sysctl_register(void);
  704.  #endif /* CONFIG_SYSCTL */ 
  705. @@ -248,7 +315,7 @@
  706.  int register_cdrom(struct cdrom_device_info *cdi)
  707.  {
  708.   static char banner_printed = 0;
  709. - int major = MAJOR (cdi->dev);
  710. + int major = MAJOR(cdi->dev);
  711.          struct cdrom_device_ops *cdo = cdi->ops;
  712.          int *change_capability = (int *)&cdo->capability; /* hack */
  713.  
  714. @@ -259,7 +326,7 @@
  715.   if (cdo->open == NULL || cdo->release == NULL)
  716.   return -2;
  717.   if ( !banner_printed ) {
  718. - printk(KERN_INFO "Uniform CDROM driver " REVISION "n");
  719. + printk(KERN_INFO "Uniform CD-ROM driver " REVISION "n");
  720.   banner_printed = 1;
  721.  #ifdef CONFIG_SYSCTL
  722.   cdrom_sysctl_register();
  723. @@ -270,12 +337,12 @@
  724.   ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
  725.   ENSURE(lock_door, CDC_LOCK);
  726.   ENSURE(select_speed, CDC_SELECT_SPEED);
  727. - ENSURE(select_disc, CDC_SELECT_DISC);
  728.   ENSURE(get_last_session, CDC_MULTI_SESSION);
  729.   ENSURE(get_mcn, CDC_MCN);
  730.   ENSURE(reset, CDC_RESET);
  731.   ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
  732.   ENSURE(dev_ioctl, CDC_IOCTLS);
  733. + ENSURE(generic_packet, CDC_GENERIC_PACKET);
  734.   cdi->mc_flags = 0;
  735.   cdo->n_minors = 0;
  736.          cdi->options = CDO_USE_FFLAGS;
  737. @@ -299,7 +366,7 @@
  738.  int unregister_cdrom(struct cdrom_device_info *unreg)
  739.  {
  740.   struct cdrom_device_info *cdi, *prev;
  741. - int major = MAJOR (unreg->dev);
  742. + int major = MAJOR(unreg->dev);
  743.  
  744.   cdinfo(CD_OPEN, "entering unregister_cdromn"); 
  745.  
  746. @@ -325,16 +392,30 @@
  747.  }
  748.  
  749.  static
  750. -struct cdrom_device_info *cdrom_find_device (kdev_t dev)
  751. +struct cdrom_device_info *cdrom_find_device(kdev_t dev)
  752.  {
  753.   struct cdrom_device_info *cdi;
  754.  
  755.   cdi = topCdromPtr;
  756.   while (cdi != NULL && cdi->dev != dev)
  757.   cdi = cdi->next;
  758. +
  759. + /* we need to find the device this way when IDE devices such
  760. +  * as /dev/hdc2 are opened. SCSI drives will be found above and
  761. +  * so will /dev/hdc, for instance.
  762. +  */
  763. + if (cdi == NULL) {
  764. + kdev_t cd_dev = MKDEV(MAJOR(dev), MINOR(dev) | CD_PART_MASK);
  765. + cdi = topCdromPtr;
  766. + while (cdi != NULL && cdi->dev != cd_dev)
  767. + cdi = cdi->next;
  768. + }
  769. +
  770.   return cdi;
  771.  }
  772.  
  773. +static int cdrom_setup_writemode(struct cdrom_device_info *cdi);
  774. +
  775.  /* We use the open-option O_NONBLOCK to indicate that the
  776.   * purpose of opening is only for subsequent ioctl() calls; no device
  777.   * integrity checks are performed.
  778. @@ -346,22 +427,31 @@
  779.  static
  780.  int cdrom_open(struct inode *ip, struct file *fp)
  781.  {
  782. + struct cdrom_device_info *cdi;
  783.   kdev_t dev = ip->i_rdev;
  784. - struct cdrom_device_info *cdi = cdrom_find_device(dev);
  785. - int purpose = !!(fp->f_flags & O_NONBLOCK);
  786. - int ret=0;
  787. + int ret;
  788.  
  789.   cdinfo(CD_OPEN, "entering cdrom_openn"); 
  790. - if (cdi == NULL)
  791. + if ((cdi = cdrom_find_device(dev)) == NULL)
  792.   return -ENODEV;
  793. - if (fp->f_mode & FM_WRITE)
  794. - return -EROFS;
  795. - purpose = purpose || !(cdi->options & CDO_USE_FFLAGS);
  796. - if (purpose)
  797. - ret = cdi->ops->open(cdi, purpose);
  798. +
  799. + /* just CD-RW for now. DVD-RW will come soon, CD-R and DVD-R
  800. +  * need to be handled differently. */
  801. + if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_CD_RW))
  802. + return -EROFS;
  803. +
  804. + /* if this was a O_NONBLOCK open and we should honor the flags,
  805. +  * do a quick open without drive/disc integrity checks. */
  806. + if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS))
  807. + ret = cdi->ops->open(cdi, 1);
  808.   else
  809.   ret = open_for_data(cdi);
  810. +
  811.   if (!ret) cdi->use_count++;
  812. +
  813. + if (fp->f_mode & FMODE_WRITE && !cdi->write.writeable)
  814. + cdi->write.writeable = !cdrom_setup_writemode(cdi);
  815. +
  816.   cdinfo(CD_OPEN, "Use count for "/dev/%s" now %dn", cdi->name, cdi->use_count);
  817.   /* Do this on open.  Don't wait for mount, because they might
  818.       not be mounting, but opening with O_NONBLOCK */
  819. @@ -428,7 +518,11 @@
  820.    * for example, need bit CDO_CHECK_TYPE cleared! */
  821.   if (tracks.data==0) {
  822.   if (cdi->options & CDO_CHECK_TYPE) {
  823. +     /* give people a warning shot, now that CDO_CHECK_TYPE
  824. +        is the default case! */
  825.       cdinfo(CD_OPEN, "bummer. wrong media type.n"); 
  826. +     cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!n",
  827. + (unsigned int)current->pid); 
  828.       ret=-EMEDIUMTYPE;
  829.       goto clean_up_and_return;
  830.   }
  831. @@ -452,7 +546,7 @@
  832.   if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
  833.   cdo->lock_door(cdi, 1);
  834.   cdinfo(CD_OPEN, "door locked.n");
  835. - }
  836. + }
  837.   cdinfo(CD_OPEN, "device opened successfully.n"); 
  838.   return ret;
  839.  
  840. @@ -533,7 +627,7 @@
  841.  int cdrom_release(struct inode *ip, struct file *fp)
  842.  {
  843.   kdev_t dev = ip->i_rdev;
  844. - struct cdrom_device_info *cdi = cdrom_find_device (dev);
  845. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  846.   struct cdrom_device_ops *cdo = cdi->ops;
  847.   int opened_for_data;
  848.  
  849. @@ -543,7 +637,7 @@
  850.   if (cdi->use_count > 0) cdi->use_count--;
  851.   if (cdi->use_count == 0)
  852.   cdinfo(CD_CLOSE, "Use count for "/dev/%s" now zeron", cdi->name);
  853. - if (cdi->use_count == 0 &&      /* last process that closes dev*/
  854. + if (cdi->use_count == 0 &&
  855.       cdo->capability & CDC_LOCK && !keeplocked) {
  856.   cdinfo(CD_CLOSE, "Unlocking door!n");
  857.   cdo->lock_door(cdi, 0);
  858. @@ -557,13 +651,140 @@
  859.   sb = get_super(dev);
  860.   if (sb) invalidate_inodes(sb);
  861.   invalidate_buffers(dev);
  862. - if (opened_for_data && (cdi->options & CDO_AUTO_EJECT) &&
  863. -     CDROM_CAN(CDC_OPEN_TRAY))
  864. + if (opened_for_data &&
  865. +     cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
  866.   cdo->tray_move(cdi, 1);
  867.   }
  868.   return 0;
  869.  }
  870.  
  871. +static int cdrom_read_mech_status(struct cdrom_device_info *cdi, 
  872. +   struct cdrom_changer_info *buf)
  873. +{
  874. + struct cdrom_generic_command cgc;
  875. + struct cdrom_device_ops *cdo = cdi->ops;
  876. + int length;
  877. +
  878. + length = sizeof(struct cdrom_mechstat_header) +
  879. +  cdi->capacity * sizeof(struct cdrom_slot);
  880. +
  881. + init_cdrom_command(&cgc, buf, length);
  882. + cgc.cmd[0] = GPCMD_MECHANISM_STATUS;
  883. + cgc.cmd[8] = (length >> 8) & 0xff;
  884. + cgc.cmd[9] = length & 0xff;
  885. + return cdo->generic_packet(cdi, &cgc);
  886. +}
  887. +
  888. +static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
  889. +{
  890. + struct cdrom_changer_info info;
  891. + int ret;
  892. +
  893. + cdinfo(CD_CHANGER, "entering cdrom_slot_status()n"); 
  894. + if (cdi->sanyo_slot)
  895. + return CDS_NO_INFO;
  896. +
  897. + if ((ret = cdrom_read_mech_status(cdi, &info)))
  898. + return ret;
  899. +
  900. + if (info.slots[slot].disc_present)
  901. + return CDS_DISC_OK;
  902. + else
  903. + return CDS_NO_DISC;
  904. +
  905. +}
  906. +
  907. +/* Return the number of slots for an ATAPI/SCSI cdrom, 
  908. + * return 1 if not a changer. 
  909. + */
  910. +int cdrom_number_of_slots(struct cdrom_device_info *cdi) 
  911. +{
  912. + int status;
  913. + int nslots = 1;
  914. + struct cdrom_changer_info info;
  915. +
  916. + cdinfo(CD_CHANGER, "entering cdrom_number_of_slots()n"); 
  917. + /* cdrom_read_mech_status requires a valid value for capacity: */
  918. + cdi->capacity = 0; 
  919. +
  920. + if ((status = cdrom_read_mech_status(cdi, &info)) == 0)
  921. + nslots = info.hdr.nslots;
  922. +
  923. + return nslots;
  924. +}
  925. +
  926. +
  927. +/* If SLOT < 0, unload the current slot.  Otherwise, try to load SLOT. */
  928. +static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot) 
  929. +{
  930. + struct cdrom_generic_command cgc;
  931. +
  932. + cdinfo(CD_CHANGER, "entering cdrom_load_unload()n"); 
  933. + if (cdi->sanyo_slot && slot < 0)
  934. + return 0;
  935. +
  936. + init_cdrom_command(&cgc, NULL, 0);
  937. + cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
  938. + cgc.cmd[4] = 2 + (slot >= 0);
  939. + cgc.cmd[8] = slot;
  940. +
  941. + /* The Sanyo 3 CD changer uses byte 7 of the 
  942. + GPCMD_TEST_UNIT_READY to command to switch CDs instead of
  943. + using the GPCMD_LOAD_UNLOAD opcode. */
  944. + if (cdi->sanyo_slot && slot) {
  945. + cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
  946. + cgc.cmd[7] = slot;
  947. + cdi->sanyo_slot = slot ? slot : 3;
  948. + }
  949. +
  950. + return cdi->ops->generic_packet(cdi, &cgc);
  951. +}
  952. +
  953. +int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
  954. +{
  955. + struct cdrom_changer_info info;
  956. + int curslot;
  957. + int ret;
  958. +
  959. + cdinfo(CD_CHANGER, "entering cdrom_select_disc()n"); 
  960. + if (!CDROM_CAN(CDC_SELECT_DISC))
  961. + return -EDRIVE_CANT_DO_THIS;
  962. +
  963. + if (slot == CDSL_NONE) {
  964. + /* set media changed bits, on both queues */
  965. + cdi->mc_flags = 0x3;
  966. + return cdrom_load_unload(cdi, -1);
  967. + }
  968. +
  969. + if ((ret = cdrom_read_mech_status(cdi, &info)))
  970. + return ret;
  971. +
  972. + curslot = info.hdr.curslot;
  973. +
  974. + if (cdi->use_count > 1 || keeplocked) {
  975. + if (slot == CDSL_CURRENT) {
  976. +      return curslot;
  977. + } else {
  978. + return -EBUSY;
  979. + }
  980. + }
  981. +
  982. + /* Specifying CDSL_CURRENT will attempt to load the currnet slot,
  983. + which is useful if it had been previously unloaded.
  984. + Whether it can or not, it returns the current slot. 
  985. + Similarly,  if slot happens to be the current one, we still
  986. + try and load it. */
  987. + if (slot == CDSL_CURRENT)
  988. + slot = curslot;
  989. +
  990. + /* set media changed bits on both queues */
  991. + cdi->mc_flags = 0x3;
  992. + if ((ret = cdrom_load_unload(cdi, slot)))
  993. + return ret;
  994. +
  995. + return slot;
  996. +}
  997. +
  998.  /* We want to make media_changed accessible to the user through an
  999.   * ioctl. The main problem now is that we must double-buffer the
  1000.   * low-level implementation, to assure that the VFS and the user both
  1001. @@ -590,7 +811,7 @@
  1002.  static
  1003.  int cdrom_media_changed(kdev_t dev)
  1004.  {
  1005. - struct cdrom_device_info *cdi = cdrom_find_device (dev);
  1006. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  1007.   /* This talks to the VFS, which doesn't like errors - just 1 or 0.  
  1008.    * Returning "0" is always safe (media hasn't been changed). Do that 
  1009.    * if the low-level cdrom driver dosn't support media changed. */ 
  1010. @@ -614,7 +835,7 @@
  1011.   tracks->xa=0;
  1012.   tracks->error=0;
  1013.   cdinfo(CD_COUNT_TRACKS, "entering cdrom_count_tracksn"); 
  1014. -        if (!(cdi->ops->capability & ~cdi->mask & CDC_PLAY_AUDIO)) { 
  1015. +        if (!CDROM_CAN(CDC_PLAY_AUDIO)) { 
  1016.                  tracks->error=CDS_NO_INFO;
  1017.                  return;
  1018.          }        
  1019. @@ -688,6 +909,450 @@
  1020.   *curr = requested;
  1021.  }
  1022.  
  1023. +void init_cdrom_command(struct cdrom_generic_command *cgc,
  1024. + void *buffer, int len)
  1025. +{
  1026. + memset(cgc, 0, sizeof(struct cdrom_generic_command));
  1027. + memset(buffer, 0, len);
  1028. + cgc->buffer = (char *) buffer;
  1029. + cgc->buflen = len;
  1030. +}
  1031. +
  1032. +/* DVD handling */
  1033. +
  1034. +#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
  1035. +#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
  1036. +
  1037. +static void setup_report_key(struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
  1038. +{
  1039. + cgc->cmd[0] = GPCMD_REPORT_KEY;
  1040. + cgc->cmd[10] = type | (agid << 6);
  1041. + switch (type) {
  1042. + case 0: case 8: case 5: {
  1043. + cgc->buflen = 8;
  1044. + break;
  1045. + }
  1046. + case 1: {
  1047. + cgc->buflen = 16;
  1048. + break;
  1049. + }
  1050. + case 2: case 4: {
  1051. + cgc->buflen = 12;
  1052. + break;
  1053. + }
  1054. + }
  1055. + cgc->cmd[9] = cgc->buflen;
  1056. +}
  1057. +
  1058. +static void setup_send_key(struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
  1059. +{
  1060. + cgc->cmd[0] = GPCMD_SEND_KEY;
  1061. + cgc->cmd[10] = type | (agid << 6);
  1062. + switch (type) {
  1063. + case 1: {
  1064. + cgc->buflen = 16;
  1065. + break;
  1066. + }
  1067. + case 3: {
  1068. + cgc->buflen = 12;
  1069. + break;
  1070. + }
  1071. + case 6: {
  1072. + cgc->buflen = 8;
  1073. + break;
  1074. + }
  1075. + }
  1076. + cgc->cmd[9] = cgc->buflen;
  1077. +}
  1078. +
  1079. +static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
  1080. +{
  1081. + int ret;
  1082. + u_char buf[20];
  1083. + struct cdrom_generic_command cgc;
  1084. + struct cdrom_device_ops *cdo = cdi->ops;
  1085. +
  1086. + init_cdrom_command(&cgc, buf, 0);
  1087. +
  1088. + switch (ai->type) {
  1089. + /* LU data send */
  1090. + case DVD_LU_SEND_AGID:
  1091. + cdinfo(CD_DVD, "entering DVD_LU_SEND_AGIDn"); 
  1092. + setup_report_key(&cgc, ai->lsa.agid, 0);
  1093. +
  1094. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1095. + return ret;
  1096. +
  1097. + ai->lsa.agid = buf[7] >> 6;
  1098. + /* Returning data, let host change state */
  1099. + break;
  1100. +
  1101. + case DVD_LU_SEND_KEY1:
  1102. + cdinfo(CD_DVD, "entering DVD_LU_SEND_KEY1n"); 
  1103. + setup_report_key(&cgc, ai->lsk.agid, 2);
  1104. +
  1105. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1106. + return ret;
  1107. +
  1108. + copy_key(ai->lsk.key, &buf[4]);
  1109. + /* Returning data, let host change state */
  1110. + break;
  1111. +
  1112. + case DVD_LU_SEND_CHALLENGE:
  1113. + cdinfo(CD_DVD, "entering DVD_LU_SEND_CHALLENGEn"); 
  1114. + setup_report_key(&cgc, ai->lsc.agid, 1);
  1115. +
  1116. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1117. + return ret;
  1118. +
  1119. + copy_chal(ai->lsc.chal, &buf[4]);
  1120. + /* Returning data, let host change state */
  1121. + break;
  1122. +
  1123. + /* Post-auth key */
  1124. + case DVD_LU_SEND_TITLE_KEY:
  1125. + cdinfo(CD_DVD, "entering DVD_LU_SEND_TITLE_KEYn"); 
  1126. + setup_report_key(&cgc, ai->lstk.agid, 4);
  1127. + cgc.cmd[5] = ai->lstk.lba;
  1128. + cgc.cmd[4] = ai->lstk.lba >> 8;
  1129. + cgc.cmd[3] = ai->lstk.lba >> 16;
  1130. + cgc.cmd[2] = ai->lstk.lba >> 24;
  1131. +
  1132. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1133. + return ret;
  1134. +
  1135. + ai->lstk.cpm = (buf[4] >> 7) & 1;
  1136. + ai->lstk.cp_sec = (buf[4] >> 6) & 1;
  1137. + ai->lstk.cgms = (buf[4] >> 4) & 3;
  1138. + copy_key(ai->lstk.title_key, &buf[5]);
  1139. + /* Returning data, let host change state */
  1140. + break;
  1141. +
  1142. + case DVD_LU_SEND_ASF:
  1143. + cdinfo(CD_DVD, "entering DVD_LU_SEND_ASFn"); 
  1144. + setup_report_key(&cgc, ai->lsasf.asf, 5);
  1145. +
  1146. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1147. + return ret;
  1148. +
  1149. + ai->lsasf.asf = buf[7] & 1;
  1150. + break;
  1151. +
  1152. + /* LU data receive (LU changes state) */
  1153. + case DVD_HOST_SEND_CHALLENGE:
  1154. + cdinfo(CD_DVD, "entering DVD_HOST_SEND_CHALLENGEn"); 
  1155. + setup_send_key(&cgc, ai->hsc.agid, 1);
  1156. + buf[1] = 0xe;
  1157. + copy_chal(&buf[4], ai->hsc.chal);
  1158. +
  1159. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1160. + return ret;
  1161. +
  1162. + ai->type = DVD_LU_SEND_KEY1;
  1163. + break;
  1164. +
  1165. + case DVD_HOST_SEND_KEY2:
  1166. + cdinfo(CD_DVD, "entering DVD_HOST_SEND_KEY2n"); 
  1167. + setup_send_key(&cgc, ai->hsk.agid, 3);
  1168. + buf[1] = 0xa;
  1169. + copy_key(&buf[4], ai->hsk.key);
  1170. +
  1171. + if ((ret = cdo->generic_packet(cdi, &cgc))) {
  1172. + ai->type = DVD_AUTH_FAILURE;
  1173. + return ret;
  1174. + }
  1175. + ai->type = DVD_AUTH_ESTABLISHED;
  1176. + break;
  1177. +
  1178. + /* Misc */
  1179. + case DVD_INVALIDATE_AGID:
  1180. + cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGIDn"); 
  1181. + setup_report_key(&cgc, ai->lsa.agid, 0x3f);
  1182. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1183. + return ret;
  1184. + break;
  1185. +
  1186. + default:
  1187. + cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)n", ai->type);
  1188. + return -ENOTTY;
  1189. + }
  1190. +
  1191. + return 0;
  1192. +}
  1193. +
  1194. +static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
  1195. +{
  1196. + int ret, i;
  1197. + u_char buf[4 + 4 * 20], *base;
  1198. + struct dvd_layer *layer;
  1199. + struct cdrom_generic_command cgc;
  1200. + struct cdrom_device_ops *cdo = cdi->ops;
  1201. +
  1202. + init_cdrom_command(&cgc, buf, sizeof(buf));
  1203. + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
  1204. + cgc.cmd[6] = s->physical.layer_num;
  1205. + cgc.cmd[7] = s->type;
  1206. + cgc.cmd[9] = cgc.buflen & 0xff;
  1207. +
  1208. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1209. + return ret;
  1210. +
  1211. + base = &buf[4];
  1212. + layer = &s->physical.layer[0];
  1213. +
  1214. + /* place the data... really ugly, but at least we won't have to
  1215. +    worry about endianess in userspace or here. */
  1216. + for (i = 0; i < 4; ++i, base += 20, ++layer) {
  1217. + memset(layer, 0, sizeof(*layer));
  1218. + layer->book_version = base[0] & 0xf;
  1219. + layer->book_type = base[0] >> 4;
  1220. + layer->min_rate = base[1] & 0xf;
  1221. + layer->disc_size = base[1] >> 4;
  1222. + layer->layer_type = base[2] & 0xf;
  1223. + layer->track_path = (base[2] >> 4) & 1;
  1224. + layer->nlayers = (base[2] >> 5) & 3;
  1225. + layer->track_density = base[3] & 0xf;
  1226. + layer->linear_density = base[3] >> 4;
  1227. + layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
  1228. + layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
  1229. + layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
  1230. + layer->bca = base[16] >> 7;
  1231. + }
  1232. +
  1233. + return 0;
  1234. +}
  1235. +
  1236. +static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
  1237. +{
  1238. + int ret;
  1239. + u_char buf[8];
  1240. + struct cdrom_generic_command cgc;
  1241. + struct cdrom_device_ops *cdo = cdi->ops;
  1242. +
  1243. + init_cdrom_command(&cgc, buf, sizeof(buf));
  1244. + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
  1245. + cgc.cmd[6] = s->copyright.layer_num;
  1246. + cgc.cmd[7] = s->type;
  1247. + cgc.cmd[8] = cgc.buflen >> 8;
  1248. + cgc.cmd[9] = cgc.buflen & 0xff;
  1249. +
  1250. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1251. + return ret;
  1252. +
  1253. + s->copyright.cpst = buf[4];
  1254. + s->copyright.rmi = buf[5];
  1255. +
  1256. + return 0;
  1257. +}
  1258. +
  1259. +static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
  1260. +{
  1261. + int ret, size;
  1262. + u_char *buf;
  1263. + struct cdrom_generic_command cgc;
  1264. + struct cdrom_device_ops *cdo = cdi->ops;
  1265. +
  1266. + size = sizeof(s->disckey.value) + 4;
  1267. +
  1268. + if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
  1269. + return -ENOMEM;
  1270. +
  1271. + init_cdrom_command(&cgc, buf, size);
  1272. + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
  1273. + cgc.cmd[7] = s->type;
  1274. + cgc.cmd[8] = size >> 8;
  1275. + cgc.cmd[9] = size & 0xff;
  1276. + cgc.cmd[10] = s->disckey.agid << 6;
  1277. +
  1278. + if (!(ret = cdo->generic_packet(cdi, &cgc)))
  1279. + memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
  1280. +
  1281. + kfree(buf);
  1282. + return ret;
  1283. +}
  1284. +
  1285. +static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
  1286. +{
  1287. + int ret;
  1288. + u_char buf[4 + 188];
  1289. + struct cdrom_generic_command cgc;
  1290. + struct cdrom_device_ops *cdo = cdi->ops;
  1291. +
  1292. + init_cdrom_command(&cgc, buf, sizeof(buf));
  1293. + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
  1294. + cgc.cmd[7] = s->type;
  1295. + cgc.cmd[9] = cgc.buflen = 0xff;
  1296. +
  1297. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1298. + return ret;
  1299. +
  1300. + s->bca.len = buf[0] << 8 | buf[1];
  1301. + if (s->bca.len < 12 || s->bca.len > 188) {
  1302. + cdinfo(CD_WARNING, "Received invalid BCA length (%d)n", s->bca.len);
  1303. + return -EIO;
  1304. + }
  1305. + memcpy(s->bca.value, &buf[4], s->bca.len);
  1306. +
  1307. + return 0;
  1308. +}
  1309. +
  1310. +static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
  1311. +{
  1312. + int ret = 0, size;
  1313. + u_char *buf;
  1314. + struct cdrom_generic_command cgc;
  1315. + struct cdrom_device_ops *cdo = cdi->ops;
  1316. +
  1317. + size = sizeof(s->manufact.value) + 4;
  1318. +
  1319. + if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
  1320. + return -ENOMEM;
  1321. +
  1322. + init_cdrom_command(&cgc, buf, size);
  1323. + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
  1324. + cgc.cmd[7] = s->type;
  1325. + cgc.cmd[8] = size >> 8;
  1326. + cgc.cmd[9] = size & 0xff;
  1327. +
  1328. + if ((ret = cdo->generic_packet(cdi, &cgc))) {
  1329. + kfree(buf);
  1330. + return ret;
  1331. + }
  1332. +
  1333. + s->manufact.len = buf[0] << 8 | buf[1];
  1334. + if (s->manufact.len < 0 || s->manufact.len > 2048) {
  1335. + cdinfo(CD_WARNING, "Received invalid manufacture info length"
  1336. +    " (%d)n", s->bca.len);
  1337. + ret = -EIO;
  1338. + } else {
  1339. + memcpy(s->manufact.value, &buf[4], s->manufact.len);
  1340. + }
  1341. +
  1342. + kfree(buf);
  1343. + return ret;
  1344. +}
  1345. +
  1346. +static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s)
  1347. +{
  1348. + switch (s->type) {
  1349. + case DVD_STRUCT_PHYSICAL:
  1350. + return dvd_read_physical(cdi, s);
  1351. +
  1352. + case DVD_STRUCT_COPYRIGHT:
  1353. + return dvd_read_copyright(cdi, s);
  1354. +
  1355. + case DVD_STRUCT_DISCKEY:
  1356. + return dvd_read_disckey(cdi, s);
  1357. +
  1358. + case DVD_STRUCT_BCA:
  1359. + return dvd_read_bca(cdi, s);
  1360. +
  1361. + case DVD_STRUCT_MANUFACT:
  1362. + return dvd_read_manufact(cdi, s);
  1363. +
  1364. + default:
  1365. + cdinfo(CD_WARNING, ": Invalid DVD structure read requested (%d)n",
  1366. + s->type);
  1367. + return -EINVAL;
  1368. + }
  1369. +}
  1370. +
  1371. +int cdrom_mode_sense(struct cdrom_device_info *cdi,
  1372. +      struct cdrom_generic_command *cgc,
  1373. +      int page_code, int page_control)
  1374. +{
  1375. + struct cdrom_device_ops *cdo = cdi->ops;
  1376. +
  1377. + memset(cgc->cmd, 0, sizeof(cgc->cmd));
  1378. +
  1379. + cgc->cmd[0] = GPCMD_MODE_SENSE_10;
  1380. + cgc->cmd[2] = page_code | (page_control << 6);
  1381. + cgc->cmd[7] = cgc->buflen >> 8;
  1382. + cgc->cmd[8] = cgc->buflen & 0xff;
  1383. + return cdo->generic_packet(cdi, cgc);
  1384. +}
  1385. +
  1386. +int cdrom_mode_select(struct cdrom_device_info *cdi,
  1387. +       struct cdrom_generic_command *cgc)
  1388. +{
  1389. + struct cdrom_device_ops *cdo = cdi->ops;
  1390. +
  1391. + memset(cgc->cmd, 0, sizeof(cgc->cmd));
  1392. +
  1393. + cgc->cmd[0] = GPCMD_MODE_SELECT_10;
  1394. + cgc->cmd[1] = 0x10; /* PF */
  1395. + cgc->cmd[7] = cgc->buflen >> 8;
  1396. + cgc->cmd[8] = cgc->buflen & 0xff;
  1397. + return cdo->generic_packet(cdi, cgc);
  1398. +}
  1399. +
  1400. +static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
  1401. +  struct cdrom_subchnl *subchnl, int mcn)
  1402. +{
  1403. + struct cdrom_device_ops *cdo = cdi->ops;
  1404. + struct cdrom_generic_command cgc;
  1405. + char buffer[32];
  1406. + int ret;
  1407. +
  1408. + init_cdrom_command(&cgc, buffer, 16);
  1409. + cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
  1410. + cgc.cmd[1] = 2;     /* MSF addressing */
  1411. + cgc.cmd[2] = 0x40;  /* request subQ data */
  1412. + cgc.cmd[3] = mcn ? 2 : 1;
  1413. + cgc.cmd[8] = 16;
  1414. +
  1415. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  1416. + return ret;
  1417. +
  1418. + subchnl->cdsc_audiostatus = cgc.buffer[1];
  1419. + subchnl->cdsc_format = CDROM_MSF;
  1420. + subchnl->cdsc_ctrl = cgc.buffer[5] & 0xf;
  1421. + subchnl->cdsc_trk = cgc.buffer[6];
  1422. + subchnl->cdsc_ind = cgc.buffer[7];
  1423. +
  1424. + subchnl->cdsc_reladdr.msf.minute = cgc.buffer[13];
  1425. + subchnl->cdsc_reladdr.msf.second = cgc.buffer[14];
  1426. + subchnl->cdsc_reladdr.msf.frame = cgc.buffer[15];
  1427. + subchnl->cdsc_absaddr.msf.minute = cgc.buffer[9];
  1428. + subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
  1429. + subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
  1430. +
  1431. + return 0;
  1432. +}
  1433. +
  1434. +/* very generic interface for reading the various types of blocks */
  1435. +static int cdrom_read_block(struct cdrom_device_info *cdi,
  1436. +     struct cdrom_generic_command *cgc,
  1437. +     int lba, int nblocks, int format, int blksize)
  1438. +{
  1439. + struct cdrom_device_ops *cdo = cdi->ops;
  1440. +
  1441. + memset(&cgc->cmd, 0, sizeof(cgc->cmd));
  1442. + cgc->cmd[0] = GPCMD_READ_CD;
  1443. + /* expected sector size - cdda,mode1,etc. */
  1444. + cgc->cmd[1] = format << 2;
  1445. + /* starting address */
  1446. + cgc->cmd[2] = (lba >> 24) & 0xff;
  1447. + cgc->cmd[3] = (lba >> 16) & 0xff;
  1448. + cgc->cmd[4] = (lba >>  8) & 0xff;
  1449. + cgc->cmd[5] = lba & 0xff;
  1450. + /* number of blocks */
  1451. + cgc->cmd[6] = (nblocks >> 16) & 0xff;
  1452. + cgc->cmd[7] = (nblocks >>  8) & 0xff;
  1453. + cgc->cmd[8] = nblocks & 0xff;
  1454. + cgc->buflen = blksize * nblocks;
  1455. +
  1456. + /* set the header info returned */
  1457. + switch (blksize) {
  1458. + case CD_FRAMESIZE_RAW0 : cgc->cmd[9] = 0x58; break;
  1459. + case CD_FRAMESIZE_RAW1 : cgc->cmd[9] = 0x78; break;
  1460. + case CD_FRAMESIZE_RAW : cgc->cmd[9] = 0xf8; break;
  1461. + default : cgc->cmd[9] = 0x10;
  1462. + }
  1463. +
  1464. + return cdo->generic_packet(cdi, cgc);
  1465. +}
  1466. +
  1467.  /* Some of the cdrom ioctls are not implemented here, because these
  1468.   * appear to be either too device-specific, or it is not clear to me
  1469.   * what use they are. These are (number of drivers that support them
  1470. @@ -706,8 +1371,9 @@
  1471.   unsigned int cmd, unsigned long arg)
  1472.  {
  1473.   kdev_t dev = ip->i_rdev;
  1474. - struct cdrom_device_info *cdi = cdrom_find_device (dev);
  1475. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  1476.   struct cdrom_device_ops *cdo;
  1477. + int ret;
  1478.  
  1479.   if (cdi == NULL)
  1480.   return -ENODEV;
  1481. @@ -719,7 +1385,6 @@
  1482.   /* maybe we should order cases after statistics of use? */
  1483.  
  1484.   case CDROMMULTISESSION: {
  1485. - int ret;
  1486.   struct cdrom_multisession ms_info;
  1487.   u_char requested_format;
  1488.   cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSIONn"); 
  1489. @@ -741,7 +1406,6 @@
  1490.   }
  1491.  
  1492.   case CDROMEJECT: {
  1493. - int ret;
  1494.   cdinfo(CD_DO_IOCTL, "entering CDROMEJECTn"); 
  1495.   if (!CDROM_CAN(CDC_OPEN_TRAY))
  1496.   return -ENOSYS;
  1497. @@ -774,16 +1438,22 @@
  1498.   }
  1499.  
  1500.   case CDROM_MEDIA_CHANGED: {
  1501. + struct cdrom_changer_info info;
  1502. +
  1503.   cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGEDn"); 
  1504.   if (!CDROM_CAN(CDC_MEDIA_CHANGED))
  1505.   return -ENOSYS;
  1506. - if (!CDROM_CAN(CDC_SELECT_DISC)
  1507. -     || arg == CDSL_CURRENT)
  1508. + if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
  1509.   /* cannot select disc or select current disc */
  1510.   return media_changed(cdi, 1);
  1511. - if ((unsigned int)arg >= cdi->capacity)
  1512. + if ((unsigned int)arg >= cdi->capacity) {
  1513.   return -EINVAL;
  1514. - return cdo->media_changed (cdi, arg);
  1515. + }
  1516. +
  1517. + if ((ret = cdrom_read_mech_status(cdi, &info)))
  1518. + return ret;
  1519. +
  1520. + return info.slots[arg].change;
  1521.   }
  1522.  
  1523.   case CDROM_SET_OPTIONS: {
  1524. @@ -824,16 +1494,29 @@
  1525.  
  1526.   case CDROM_SELECT_DISC: {
  1527.   cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISCn"); 
  1528. - if (!(cdo->capability & ~cdi->mask & CDC_SELECT_DISC))
  1529. + if (!CDROM_CAN(CDC_SELECT_DISC))
  1530.   return -ENOSYS;
  1531. -                if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE)) 
  1532. +
  1533. +                if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE)) {
  1534. +     if ((int)arg >= cdi->capacity)
  1535. + return -EINVAL;
  1536. + }
  1537. + /* cdo->select_disc is a hook to allow a driver-specific
  1538. +  * way of seleting disc.  However, since there is no
  1539. +  * equiv hook for cdrom_slot_status this may not 
  1540. +  * actually be useful...
  1541. +  */
  1542. + if (cdo->select_disc != NULL)
  1543.   return cdo->select_disc(cdi, arg);
  1544. - if ((int)arg >= cdi->capacity)
  1545. - return -EDRIVE_CANT_DO_THIS;
  1546. - return cdo->select_disc(cdi, arg);
  1547. +
  1548. + /* no driver specific select_disc(), call our own */
  1549. + cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()n"); 
  1550. + return cdrom_select_disc(cdi, arg);
  1551.   }
  1552.  
  1553.   case CDROMRESET: {
  1554. + if (!capable(CAP_SYS_ADMIN))
  1555. + return -EACCES;
  1556.   cdinfo(CD_DO_IOCTL, "entering CDROM_RESETn");
  1557.   if (!CDROM_CAN(CDC_RESET))
  1558.   return -ENOSYS;
  1559. @@ -841,19 +1524,17 @@
  1560.   }
  1561.  
  1562.   case CDROM_LOCKDOOR: {
  1563. - cdinfo(CD_DO_IOCTL, "%socking door.n",arg?"L":"Unl");
  1564. - if (!CDROM_CAN(CDC_LOCK)) {
  1565. + cdinfo(CD_DO_IOCTL, "%socking door.n", arg ? "L" : "Unl");
  1566. + if (!CDROM_CAN(CDC_LOCK))
  1567.   return -EDRIVE_CANT_DO_THIS;
  1568. - } else {
  1569. - keeplocked = arg ? 1 : 0;
  1570. - return cdo->lock_door(cdi, arg);
  1571. - }
  1572. + keeplocked = arg ? 1 : 0;
  1573. + return cdo->lock_door(cdi, arg);
  1574.   }
  1575.  
  1576.   case CDROM_DEBUG: {
  1577.   if (!capable(CAP_SYS_ADMIN))
  1578.   return -EACCES;
  1579. - cdinfo(CD_DO_IOCTL, "%sabling debug.n",arg?"En":"Dis");
  1580. + cdinfo(CD_DO_IOCTL, "%sabling debug.n", arg ? "En" : "Dis");
  1581.   debug = arg ? 1 : 0;
  1582.   return debug;
  1583.   }
  1584. @@ -869,10 +1550,9 @@
  1585.   * is written on the CD is /not/ uniform across all discs!
  1586.   */
  1587.   case CDROM_GET_MCN: {
  1588. - int ret;
  1589.   struct cdrom_mcn mcn;
  1590.   cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCNn"); 
  1591. - if (!CDROM_CAN(CDC_MCN))
  1592. + if (!(cdo->capability & CDC_MCN))
  1593.   return -ENOSYS;
  1594.   if ((ret=cdo->get_mcn(cdi, &mcn)))
  1595.   return ret;
  1596. @@ -883,13 +1563,15 @@
  1597.  
  1598.   case CDROM_DRIVE_STATUS: {
  1599.   cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUSn"); 
  1600. - if (!CDROM_CAN(CDC_DRIVE_STATUS))
  1601. + if (!(cdo->capability & CDC_DRIVE_STATUS))
  1602.   return -ENOSYS;
  1603. + if (!CDROM_CAN(CDC_SELECT_DISC))
  1604. + return cdo->drive_status(cdi, CDSL_CURRENT);
  1605.                  if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE)) 
  1606. - return cdo->drive_status(cdi, arg);
  1607. -                if (((int)arg > cdi->capacity))
  1608. + return cdo->drive_status(cdi, CDSL_CURRENT);
  1609. + if (((int)arg >= cdi->capacity))
  1610.   return -EINVAL;
  1611. - return cdo->drive_status(cdi, arg);
  1612. + return cdrom_slot_status(cdi, arg);
  1613.   }
  1614.  
  1615.   /* Ok, this is where problems start.  The current interface for the
  1616. @@ -920,7 +1602,8 @@
  1617.   if (tracks.audio > 0) {
  1618.   if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0) 
  1619.   return CDS_AUDIO;
  1620. - else return CDS_MIXED;
  1621. + else
  1622. + return CDS_MIXED;
  1623.   }
  1624.   if (tracks.cdi > 0) return CDS_XA_2_2;
  1625.   if (tracks.xa > 0) return CDS_XA_2_1;
  1626. @@ -931,231 +1614,907 @@
  1627.   return CDS_NO_INFO;
  1628.   }
  1629.  
  1630. - case CDROM_CHANGER_NSLOTS:
  1631. + case CDROM_CHANGER_NSLOTS: {
  1632.   cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTSn"); 
  1633. - return cdi->capacity;
  1634. + return cdi->capacity;
  1635. + }
  1636. + }
  1637.  
  1638. -/* The following is not implemented, because there are too many
  1639. - * different data types. We could support /1/ raw mode, that is large
  1640. - * enough to hold everything.
  1641. - */
  1642. + /* use the ioctls that are implemented through the generic_packet()
  1643. +    interface. this may look at bit funny, but if -ENOTTY is
  1644. +    returned that particular ioctl is not implemented and we
  1645. +    let it go through the device specific ones. */
  1646. + if (CDROM_CAN(CDC_GENERIC_PACKET)) {
  1647. + ret = mmc_ioctl(cdi, cmd, arg);
  1648. + if (ret != -ENOTTY) {
  1649. + return ret;
  1650. + }
  1651. + }
  1652.  
  1653. -#if 0
  1654. - case CDROMREADMODE1: {
  1655. - int ret;
  1656. + /* note: most of the cdinfo() calls are commented out here,
  1657. +    because they fill up the sys log when CD players poll
  1658. +    the drive. */
  1659. + switch (cmd) {
  1660. + case CDROMSUBCHNL: {
  1661. + struct cdrom_subchnl q;
  1662. + u_char requested, back;
  1663. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1664. + return -ENOSYS;
  1665. + /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNLn");*/ 
  1666. + IOCTL_IN(arg, struct cdrom_subchnl, q);
  1667. + requested = q.cdsc_format;
  1668. + if (!((requested == CDROM_MSF) ||
  1669. +       (requested == CDROM_LBA)))
  1670. + return -EINVAL;
  1671. + q.cdsc_format = CDROM_MSF;
  1672. + if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))
  1673. + return ret;
  1674. + back = q.cdsc_format; /* local copy */
  1675. + sanitize_format(&q.cdsc_absaddr, &back, requested);
  1676. + sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
  1677. + IOCTL_OUT(arg, struct cdrom_subchnl, q);
  1678. + /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successfuln"); */ 
  1679. + return 0;
  1680. + }
  1681. + case CDROMREADTOCHDR: {
  1682. + struct cdrom_tochdr header;
  1683. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1684. + return -ENOSYS;
  1685. + /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDRn"); */ 
  1686. + IOCTL_IN(arg, struct cdrom_tochdr, header);
  1687. + if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
  1688. + return ret;
  1689. + IOCTL_OUT(arg, struct cdrom_tochdr, header);
  1690. + /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successfuln"); */ 
  1691. + return 0;
  1692. + }
  1693. + case CDROMREADTOCENTRY: {
  1694. + struct cdrom_tocentry entry;
  1695. + u_char requested_format;
  1696. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1697. + return -ENOSYS;
  1698. + /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRYn"); */ 
  1699. + IOCTL_IN(arg, struct cdrom_tocentry, entry);
  1700. + requested_format = entry.cdte_format;
  1701. + if (!((requested_format == CDROM_MSF) || 
  1702. + (requested_format == CDROM_LBA)))
  1703. + return -EINVAL;
  1704. + /* make interface to low-level uniform */
  1705. + entry.cdte_format = CDROM_MSF;
  1706. + if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
  1707. + return ret;
  1708. + sanitize_format(&entry.cdte_addr,
  1709. + &entry.cdte_format, requested_format);
  1710. + IOCTL_OUT(arg, struct cdrom_tocentry, entry);
  1711. + /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successfuln"); */ 
  1712. + return 0;
  1713. + }
  1714. + case CDROMPLAYMSF: {
  1715.   struct cdrom_msf msf;
  1716. - char buf[CD_FRAMESIZE];
  1717. - cdinfo(CD_DO_IOCTL, "entering CDROMREADMODE1n"); 
  1718. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1719. + return -ENOSYS;
  1720. + cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSFn"); 
  1721.   IOCTL_IN(arg, struct cdrom_msf, msf);
  1722. - if (ret=cdo->read_audio(dev, cmd, &msf, &buf, cdi))
  1723. + return cdo->audio_ioctl(cdi, cmd, &msf);
  1724. + }
  1725. + case CDROMPLAYTRKIND: {
  1726. + struct cdrom_ti ti;
  1727. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1728. + return -ENOSYS;
  1729. + cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKINDn"); 
  1730. + IOCTL_IN(arg, struct cdrom_ti, ti);
  1731. + CHECKAUDIO;
  1732. + return cdo->audio_ioctl(cdi, cmd, &ti);
  1733. + }
  1734. + case CDROMVOLCTRL: {
  1735. + struct cdrom_volctrl volume;
  1736. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1737. + return -ENOSYS;
  1738. + cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRLn"); 
  1739. + IOCTL_IN(arg, struct cdrom_volctrl, volume);
  1740. + return cdo->audio_ioctl(cdi, cmd, &volume);
  1741. + }
  1742. + case CDROMVOLREAD: {
  1743. + struct cdrom_volctrl volume;
  1744. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1745. + return -ENOSYS;
  1746. + cdinfo(CD_DO_IOCTL, "entering CDROMVOLREADn"); 
  1747. + if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
  1748.   return ret;
  1749. - IOCTL_OUT(arg, __typeof__(buf), buf);
  1750. + IOCTL_OUT(arg, struct cdrom_volctrl, volume);
  1751.   return 0;
  1752.   }
  1753. -#endif
  1754. + case CDROMSTART:
  1755. + case CDROMSTOP:
  1756. + case CDROMPAUSE:
  1757. + case CDROMRESUME: {
  1758. + if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1759. + return -ENOSYS;
  1760. + cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)n"); 
  1761. + CHECKAUDIO;
  1762. + return cdo->audio_ioctl(cdi, cmd, NULL);
  1763. + }
  1764.   } /* switch */
  1765.  
  1766. -/* Now all the audio-ioctls follow, they are all routed through the
  1767. -   same call audio_ioctl(). */
  1768. + /* do the device specific ioctls */
  1769. + if (CDROM_CAN(CDC_IOCTLS))
  1770. + return cdo->dev_ioctl(cdi, cmd, arg);
  1771. +
  1772. + return -ENOSYS;
  1773. +}
  1774. +
  1775. +static inline
  1776. +int msf_to_lba(char m, char s, char f)
  1777. +{
  1778. + return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
  1779. +}
  1780.  
  1781. -#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
  1782. +static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
  1783. +      unsigned long arg)
  1784. +{
  1785. + struct cdrom_device_ops *cdo = cdi->ops;
  1786. + struct cdrom_generic_command cgc;
  1787. + kdev_t dev = cdi->dev;
  1788. + char buffer[32];
  1789. + int ret = 0;
  1790. +
  1791. + memset(&cgc, 0, sizeof(cgc));
  1792.  
  1793. - if (!CDROM_CAN(CDC_PLAY_AUDIO))
  1794. - return -ENOSYS;
  1795. - else {
  1796. + /* build a unified command and queue it through
  1797. +    cdo->generic_packet() */
  1798. + switch (cmd) {
  1799. + case CDROMREADRAW:
  1800. + case CDROMREADMODE1:
  1801. + case CDROMREADMODE2: {
  1802. + struct cdrom_msf msf;
  1803. + int blocksize = 0, format = 0, lba;
  1804. +
  1805.   switch (cmd) {
  1806. - case CDROMSUBCHNL: {
  1807. - int ret;
  1808. - struct cdrom_subchnl q;
  1809. - u_char requested, back;
  1810. - /* comment out the cdinfo calls here because they
  1811. -    fill up the sys logs when CD players poll the drive*/
  1812. - /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNLn");*/ 
  1813. - IOCTL_IN(arg, struct cdrom_subchnl, q);
  1814. - requested = q.cdsc_format;
  1815. -                        if (!((requested == CDROM_MSF) ||
  1816. -                                (requested == CDROM_LBA)))
  1817. -                                        return -EINVAL;
  1818. - q.cdsc_format = CDROM_MSF;
  1819. - if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))
  1820. - return ret;
  1821. - back = q.cdsc_format; /* local copy */
  1822. - sanitize_format(&q.cdsc_absaddr, &back, requested);
  1823. - sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
  1824. - IOCTL_OUT(arg, struct cdrom_subchnl, q);
  1825. - /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successfuln"); */ 
  1826. - return 0;
  1827. - }
  1828. - case CDROMREADTOCHDR: {
  1829. - int ret;
  1830. - struct cdrom_tochdr header;
  1831. - /* comment out the cdinfo calls here because they
  1832. -    fill up the sys logs when CD players poll the drive*/
  1833. - /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDRn"); */ 
  1834. - IOCTL_IN(arg, struct cdrom_tochdr, header);
  1835. - if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
  1836. - return ret;
  1837. - IOCTL_OUT(arg, struct cdrom_tochdr, header);
  1838. - /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successfuln"); */ 
  1839. - return 0;
  1840. - }
  1841. - case CDROMREADTOCENTRY: {
  1842. - int ret;
  1843. - struct cdrom_tocentry entry;
  1844. - u_char requested_format;
  1845. - /* comment out the cdinfo calls here because they
  1846. -    fill up the sys logs when CD players poll the drive*/
  1847. - /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRYn"); */ 
  1848. - IOCTL_IN(arg, struct cdrom_tocentry, entry);
  1849. - requested_format = entry.cdte_format;
  1850. - if (!((requested_format == CDROM_MSF) || 
  1851. - (requested_format == CDROM_LBA)))
  1852. - return -EINVAL;
  1853. - /* make interface to low-level uniform */
  1854. - entry.cdte_format = CDROM_MSF;
  1855. - if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
  1856. - return ret;
  1857. - sanitize_format(&entry.cdte_addr,
  1858. - &entry.cdte_format, requested_format);
  1859. - IOCTL_OUT(arg, struct cdrom_tocentry, entry);
  1860. - /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successfuln"); */ 
  1861. - return 0;
  1862. - }
  1863. - case CDROMPLAYMSF: {
  1864. - int ret;
  1865. - struct cdrom_msf msf;
  1866. - cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSFn"); 
  1867. - IOCTL_IN(arg, struct cdrom_msf, msf);
  1868. - CHECKAUDIO;
  1869. - return cdo->audio_ioctl(cdi, cmd, &msf);
  1870. - }
  1871. - case CDROMPLAYTRKIND: {
  1872. - int ret;
  1873. - struct cdrom_ti ti;
  1874. - cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKINDn"); 
  1875. - IOCTL_IN(arg, struct cdrom_ti, ti);
  1876. - CHECKAUDIO;
  1877. - return cdo->audio_ioctl(cdi, cmd, &ti);
  1878. - }
  1879. - case CDROMVOLCTRL: {
  1880. - struct cdrom_volctrl volume;
  1881. - cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRLn"); 
  1882. - IOCTL_IN(arg, struct cdrom_volctrl, volume);
  1883. - return cdo->audio_ioctl(cdi, cmd, &volume);
  1884. - }
  1885. - case CDROMVOLREAD: {
  1886. - int ret;
  1887. - struct cdrom_volctrl volume;
  1888. - cdinfo(CD_DO_IOCTL, "entering CDROMVOLREADn"); 
  1889. - if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
  1890. - return ret;
  1891. - IOCTL_OUT(arg, struct cdrom_volctrl, volume);
  1892. + case CDROMREADRAW:
  1893. + blocksize = CD_FRAMESIZE_RAW;
  1894. + break;
  1895. + case CDROMREADMODE1:
  1896. + blocksize = CD_FRAMESIZE;
  1897. + format = 2;
  1898. + break;
  1899. + case CDROMREADMODE2:
  1900. + blocksize = CD_FRAMESIZE_RAW0;
  1901. + break;
  1902. + }
  1903. + IOCTL_IN(arg, struct cdrom_msf, msf);
  1904. + lba = msf_to_lba(msf.cdmsf_min0,msf.cdmsf_sec0,msf.cdmsf_frame0);
  1905. + /* FIXME: we need upper bound checking, too!! */
  1906. + if (lba < 0)
  1907. + return -EINVAL;
  1908. + cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
  1909. + if (cgc.buffer == NULL)
  1910. + return -ENOMEM;
  1911. + ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
  1912. + if (!ret)
  1913. + if (copy_to_user((char *)arg, cgc.buffer, blocksize))
  1914. + ret = -EFAULT;
  1915. + kfree(cgc.buffer);
  1916. + return ret;
  1917. + }
  1918. + case CDROMREADAUDIO: {
  1919. + struct cdrom_read_audio ra;
  1920. + int lba, frames;
  1921. +
  1922. + IOCTL_IN(arg, struct cdrom_read_audio, ra);
  1923. +
  1924. + if (ra.addr_format == CDROM_MSF)
  1925. + lba = msf_to_lba(ra.addr.msf.minute,
  1926. +  ra.addr.msf.second,
  1927. +  ra.addr.msf.frame);
  1928. + else if (ra.addr_format == CDROM_LBA)
  1929. + lba = ra.addr.lba;
  1930. + else
  1931. + return -EINVAL;
  1932. +
  1933. + /* FIXME: we need upper bound checking, too!! */
  1934. + if (lba < 0)
  1935. + return -EINVAL;
  1936. +
  1937. + /* do max 8 frames at the time */
  1938. + frames = ra.nframes > 8 ? 8 : ra.nframes;
  1939. +
  1940. + if ((cgc.buffer = (char *) kmalloc(CD_FRAMESIZE_RAW * frames,
  1941. +    GFP_KERNEL)) == NULL)
  1942. + return -ENOMEM;
  1943. +
  1944. + if (!access_ok(VERIFY_WRITE, ra.buf, ra.nframes*CD_FRAMESIZE_RAW)) {
  1945. + kfree(cgc.buffer);
  1946. + return -EFAULT;
  1947. + }
  1948. +
  1949. + while (ra.nframes > 0) {
  1950. + ret = cdrom_read_block(cdi, &cgc, lba, frames, 1,
  1951. +        CD_FRAMESIZE_RAW);
  1952. + if (ret) break;
  1953. + __copy_to_user(ra.buf, cgc.buffer,
  1954. +        CD_FRAMESIZE_RAW * frames);
  1955. + ra.buf += (CD_FRAMESIZE_RAW * frames);
  1956. + ra.nframes -= frames;
  1957. + lba += frames;
  1958. + }
  1959. + kfree(cgc.buffer);
  1960. + return ret;
  1961. + }
  1962. + case CDROMSUBCHNL: {
  1963. + struct cdrom_subchnl q;
  1964. + u_char requested, back;
  1965. + IOCTL_IN(arg, struct cdrom_subchnl, q);
  1966. + requested = q.cdsc_format;
  1967. + if (!((requested == CDROM_MSF) ||
  1968. +       (requested == CDROM_LBA)))
  1969. + return -EINVAL;
  1970. + q.cdsc_format = CDROM_MSF;
  1971. + if ((ret = cdrom_read_subchannel(cdi, &q, 0)))
  1972. + return ret;
  1973. + back = q.cdsc_format; /* local copy */
  1974. + sanitize_format(&q.cdsc_absaddr, &back, requested);
  1975. + sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
  1976. + IOCTL_OUT(arg, struct cdrom_subchnl, q);
  1977. + /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successfuln"); */ 
  1978. + return 0;
  1979. + }
  1980. + case CDROMPLAYTRKIND: {
  1981. + struct cdrom_ti ti;
  1982. + struct cdrom_tocentry entry;
  1983. +
  1984. + cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKINDn");
  1985. + IOCTL_IN(arg, struct cdrom_ti, ti);
  1986. + entry.cdte_format = CDROM_MSF;
  1987. +
  1988. + /* get toc entry for start and end track */
  1989. + entry.cdte_track = ti.cdti_trk0;
  1990. + if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
  1991. + return -EINVAL;
  1992. +
  1993. + cgc.cmd[3] = entry.cdte_addr.msf.minute;
  1994. + cgc.cmd[4] = entry.cdte_addr.msf.second;
  1995. + cgc.cmd[5] = entry.cdte_addr.msf.frame;
  1996. +
  1997. + entry.cdte_track = ti.cdti_trk1;
  1998. + if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
  1999. + return -EINVAL;
  2000. +
  2001. + cgc.cmd[6] = entry.cdte_addr.msf.minute;
  2002. + cgc.cmd[7] = entry.cdte_addr.msf.second;
  2003. + cgc.cmd[8] = entry.cdte_addr.msf.frame;
  2004. + cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
  2005. + return cdo->generic_packet(cdi, &cgc);
  2006. + }
  2007. + case CDROMPLAYMSF: {
  2008. + struct cdrom_msf msf;
  2009. + cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSFn");
  2010. + IOCTL_IN(arg, struct cdrom_msf, msf);
  2011. + cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
  2012. + cgc.cmd[3] = msf.cdmsf_min0;
  2013. + cgc.cmd[4] = msf.cdmsf_sec0;
  2014. + cgc.cmd[5] = msf.cdmsf_frame0;
  2015. + cgc.cmd[6] = msf.cdmsf_min1;
  2016. + cgc.cmd[7] = msf.cdmsf_sec1;
  2017. + cgc.cmd[8] = msf.cdmsf_frame1;
  2018. + return cdo->generic_packet(cdi, &cgc);
  2019. + }
  2020. + case CDROMPLAYBLK: {
  2021. + struct cdrom_blk blk;
  2022. + cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLKn");
  2023. + IOCTL_IN(arg, struct cdrom_blk, blk);
  2024. + cgc.cmd[0] = GPCMD_PLAY_AUDIO_10;
  2025. + cgc.cmd[2] = (blk.from >> 24) & 0xff;
  2026. + cgc.cmd[3] = (blk.from >> 16) & 0xff;
  2027. + cgc.cmd[4] = (blk.from >>  8) & 0xff;
  2028. + cgc.cmd[5] = blk.from & 0xff;
  2029. + cgc.cmd[7] = (blk.len >> 8) & 0xff;
  2030. + cgc.cmd[8] = blk.len & 0xff;
  2031. + return cdo->generic_packet(cdi, &cgc);
  2032. + }
  2033. + case CDROMVOLCTRL:
  2034. + case CDROMVOLREAD: {
  2035. + struct cdrom_volctrl volctrl;
  2036. + char mask[32];
  2037. + unsigned short offset;
  2038. + cdinfo(CD_DO_IOCTL, "entering CDROMVOLUMEn");
  2039. +
  2040. + IOCTL_IN(arg, struct cdrom_volctrl, volctrl);
  2041. +
  2042. + cgc.buffer = buffer;
  2043. + cgc.buflen = 24;
  2044. + if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0)))
  2045. +     return ret;
  2046. +
  2047. + /* some drives have longer pages, adjust and reread. */
  2048. + if (buffer[1] > cgc.buflen) {
  2049. + cgc.buflen = buffer[1] + 2;
  2050. + if ((ret = cdrom_mode_sense(cdi, &cgc, 
  2051. + GPMODE_AUDIO_CTL_PAGE, 0))) 
  2052. +     return ret;
  2053. + }
  2054. +
  2055. + /* get the offset from the length of the page. length
  2056. +    is measure from byte 2 an on, thus the 14. */
  2057. + offset = buffer[1] - 14;
  2058. +
  2059. + /* now we have the current volume settings. if it was only
  2060. +    a CDROMVOLREAD, return these values */
  2061. + if (cmd == CDROMVOLREAD) {
  2062. + volctrl.channel0 = buffer[offset+9];
  2063. + volctrl.channel1 = buffer[offset+11];
  2064. + volctrl.channel2 = buffer[offset+13];
  2065. + volctrl.channel3 = buffer[offset+15];
  2066. + IOCTL_OUT(arg, struct cdrom_volctrl, volctrl);
  2067.   return 0;
  2068. + }
  2069. +
  2070. + /* get the volume mask */
  2071. + cgc.buffer = mask;
  2072. + if ((ret = cdrom_mode_sense(cdi, &cgc, 
  2073. + GPMODE_AUDIO_CTL_PAGE, 1)))
  2074. +     return ret;
  2075. +
  2076. + buffer[offset+9] = volctrl.channel0 & mask[offset+9];
  2077. + buffer[offset+11] = volctrl.channel1 & mask[offset+11];
  2078. + buffer[offset+13] = volctrl.channel2 & mask[offset+13];
  2079. + buffer[offset+15] = volctrl.channel3 & mask[offset+15];
  2080. +
  2081. + /* clear the first three */
  2082. + memset(buffer, 0, 3);
  2083. +
  2084. + /* set volume */
  2085. + cgc.buffer = buffer;
  2086. + return cdrom_mode_select(cdi, &cgc);
  2087. + }
  2088. +
  2089. + case CDROMSTART:
  2090. + case CDROMSTOP: {
  2091. + cdinfo(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOPn"); 
  2092. + cgc.cmd[0] = GPCMD_START_STOP_UNIT;
  2093. + cgc.cmd[1] = 1;
  2094. + cgc.cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
  2095. + return cdo->generic_packet(cdi, &cgc);
  2096. + }
  2097. +
  2098. + case CDROMPAUSE:
  2099. + case CDROMRESUME: {
  2100. + cdinfo(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUMEn"); 
  2101. + cgc.cmd[0] = GPCMD_PAUSE_RESUME;
  2102. + cgc.cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
  2103. + return cdo->generic_packet(cdi, &cgc);
  2104. + }
  2105. +
  2106. + case DVD_READ_STRUCT: {
  2107. + dvd_struct *s;
  2108. + int size = sizeof(dvd_struct);
  2109. + if (!CDROM_CAN(CDC_DVD))
  2110. + return -ENOSYS;
  2111. + if ((s = (dvd_struct *) kmalloc(size, GFP_KERNEL)) == NULL)
  2112. + return -ENOMEM;
  2113. + cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCTn"); 
  2114. + if (copy_from_user(s, (dvd_struct *)arg, size)) {
  2115. + kfree(s);
  2116. + return -EFAULT;
  2117. + }
  2118. + if ((ret = dvd_read_struct(cdi, s))) {
  2119. + kfree(s);
  2120. + return ret;
  2121. + }
  2122. + if (copy_to_user((dvd_struct *)arg, s, size))
  2123. + ret = -EFAULT;
  2124. + kfree(s);
  2125. + return ret;
  2126. + }
  2127. +
  2128. + case DVD_AUTH: {
  2129. + dvd_authinfo ai;
  2130. + if (!CDROM_CAN(CDC_DVD))
  2131. + return -ENOSYS;
  2132. + cdinfo(CD_DO_IOCTL, "entering DVD_AUTHn"); 
  2133. + IOCTL_IN(arg, dvd_authinfo, ai);
  2134. + if ((ret = dvd_do_auth (cdi, &ai)))
  2135. + return ret;
  2136. + IOCTL_OUT(arg, dvd_authinfo, ai);
  2137. + return 0;
  2138. + }
  2139. +
  2140. + case CDROM_SEND_PACKET: {
  2141. + __u8 *userbuf, copy = 0;
  2142. + if (!CDROM_CAN(CDC_GENERIC_PACKET))
  2143. + return -ENOSYS;
  2144. + cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKETn"); 
  2145. + IOCTL_IN(arg, struct cdrom_generic_command, cgc);
  2146. + copy = !!cgc.buflen;
  2147. + userbuf = cgc.buffer;
  2148. + cgc.buffer = NULL;
  2149. + if (userbuf != NULL && copy) {
  2150. + /* usually commands just copy data one way, i.e.
  2151. +  * we send a buffer to the drive and the command
  2152. +  * specifies whether the drive will read or
  2153. +  * write to that buffer. usually the buffers
  2154. +  * are very small, so we don't loose that much
  2155. +  * by doing a redundant copy each time. */
  2156. + if (!access_ok(VERIFY_WRITE, userbuf, cgc.buflen)) {
  2157. + printk("can't get write permsn");
  2158. + return -EFAULT;
  2159.   }
  2160. - case CDROMSTART:
  2161. - case CDROMSTOP:
  2162. - case CDROMPAUSE:
  2163. - case CDROMRESUME: {
  2164. - int ret;
  2165. - cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)n"); 
  2166. - CHECKAUDIO;
  2167. - return cdo->audio_ioctl(cdi, cmd, NULL);
  2168. + if (!access_ok(VERIFY_READ, userbuf, cgc.buflen)) {
  2169. + printk("can't get read permsn");
  2170. + return -EFAULT;
  2171.   }
  2172. - } /* switch */
  2173. + }
  2174. + /* reasonable limits */
  2175. + if (cgc.buflen < 0 || cgc.buflen > 131072) {
  2176. + printk("invalid size givenn");
  2177. + return -EINVAL;
  2178. + }
  2179. + if (copy) {
  2180. + cgc.buffer = kmalloc(cgc.buflen, GFP_KERNEL);
  2181. + if (cgc.buffer == NULL)
  2182. + return -ENOMEM;
  2183. + __copy_from_user(cgc.buffer, userbuf, cgc.buflen);
  2184. + }
  2185. + ret = cdo->generic_packet(cdi, &cgc);
  2186. + if (copy && !ret)
  2187. + __copy_to_user(userbuf, cgc.buffer, cgc.buflen);
  2188. + kfree(cgc.buffer);
  2189. + return ret;
  2190. + }
  2191. + case CDROM_NEXT_WRITABLE: {
  2192. + long next = 0;
  2193. + cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLEn"); 
  2194. + if ((ret = cdrom_get_next_writable(dev, &next)))
  2195. + return ret;
  2196. + IOCTL_OUT(arg, long, next);
  2197. + return 0;
  2198. + }
  2199. + case CDROM_LAST_WRITTEN: {
  2200. + long last = 0;
  2201. + cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTENn"); 
  2202. + if ((ret = cdrom_get_last_written(dev, &last)))
  2203. + return ret;
  2204. + IOCTL_OUT(arg, long, last);
  2205. + return 0;
  2206. + }
  2207. + } /* switch */
  2208. +
  2209. + return -ENOTTY;
  2210. +}
  2211. +
  2212. +static int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
  2213. + track_information *ti)
  2214. +{
  2215. +        struct cdrom_device_info *cdi = cdrom_find_device(dev);
  2216. + struct cdrom_device_ops *cdo = cdi->ops;
  2217. + struct cdrom_generic_command cgc;
  2218. + int ret;
  2219. +
  2220. + init_cdrom_command(&cgc, ti, 8);
  2221. + cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO;
  2222. + cgc.cmd[1] = type & 3;
  2223. + cgc.cmd[4] = (track & 0xff00) >> 8;
  2224. + cgc.cmd[5] = track & 0xff;
  2225. + cgc.cmd[8] = 8;
  2226. +
  2227. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  2228. + return ret;
  2229. +
  2230. + cgc.cmd[8] = cgc.buflen = be16_to_cpu(ti->track_information_length) +
  2231. +      sizeof(ti->track_information_length);
  2232. + return cdo->generic_packet(cdi, &cgc);
  2233. +}
  2234. +
  2235. +static int cdrom_get_disc_info(kdev_t dev, disc_information *di)
  2236. +{
  2237. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  2238. + struct cdrom_device_ops *cdo = cdi->ops;
  2239. + struct cdrom_generic_command cgc;
  2240. +
  2241. + /* set up command and get the disc info */
  2242. + init_cdrom_command(&cgc, di, sizeof(*di));
  2243. + cgc.cmd[0] = GPCMD_READ_DISC_INFO;
  2244. + cgc.cmd[8] = cgc.buflen;
  2245. +
  2246. + return cdo->generic_packet(cdi, &cgc);
  2247. +}
  2248. +
  2249. +
  2250. +/* return the last written block on the CD-R media. this is for the udf
  2251. +   file system. */
  2252. +int cdrom_get_last_written(kdev_t dev, long *last_written)
  2253. +{
  2254. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  2255. + struct cdrom_tocentry toc;
  2256. + disc_information di;
  2257. + track_information ti;
  2258. + __u32 last_track;
  2259. + int ret = -1;
  2260. +
  2261. + if (!CDROM_CAN(CDC_GENERIC_PACKET))
  2262. + goto use_toc;
  2263. +
  2264. + if ((ret = cdrom_get_disc_info(dev, &di)))
  2265. + goto use_toc;
  2266. +
  2267. + last_track = (di.last_track_msb << 8) | di.last_track_lsb;
  2268. + if ((ret = cdrom_get_track_info(dev, last_track, 1, &ti)))
  2269. + goto use_toc;
  2270. +
  2271. + /* if this track is blank, try the previous. */
  2272. + if (ti.blank) {
  2273. + last_track--;
  2274. + if ((ret = cdrom_get_track_info(dev, last_track, 1, &ti)))
  2275. + goto use_toc;
  2276.   }
  2277.  
  2278. - /* device specific ioctls? */
  2279. - if (!(cdo->capability & CDC_IOCTLS))
  2280. - return -ENOSYS;
  2281. - else 
  2282. - return cdo->dev_ioctl(cdi, cmd, arg);
  2283. + /* if last recorded field is valid, return it. */
  2284. + if (ti.lra_v) {
  2285. + *last_written = be32_to_cpu(ti.last_rec_address);
  2286. + } else {
  2287. + /* make it up instead */
  2288. + *last_written = be32_to_cpu(ti.track_start) +
  2289. + be32_to_cpu(ti.track_size);
  2290. + if (ti.free_blocks)
  2291. + *last_written -= (be32_to_cpu(ti.free_blocks) + 7);
  2292. + }
  2293. + return 0;
  2294. +
  2295. + /* this is where we end up if the drive either can't do a
  2296. +    GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if
  2297. +    it fails. then we return the toc contents. */
  2298. +use_toc:
  2299. + toc.cdte_format = CDROM_MSF;
  2300. + toc.cdte_track = CDROM_LEADOUT;
  2301. + if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc))
  2302. + return ret;
  2303. + sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA);
  2304. + *last_written = toc.cdte_addr.lba;
  2305. + return 0;
  2306. +}
  2307. +
  2308. +/* return the next writable block. also for udf file system. */
  2309. +int cdrom_get_next_writable(kdev_t dev, long *next_writable)
  2310. +{
  2311. + struct cdrom_device_info *cdi = cdrom_find_device(dev);
  2312. + disc_information di;
  2313. + track_information ti;
  2314. + __u16 last_track;
  2315. + int ret = -1;
  2316. +
  2317. + if (!CDROM_CAN(CDC_GENERIC_PACKET))
  2318. + goto use_last_written;
  2319. +
  2320. + if ((ret = cdrom_get_disc_info(dev, &di)))
  2321. + goto use_last_written;
  2322. +
  2323. + last_track = (di.last_track_msb << 8) | di.last_track_lsb;
  2324. + if ((ret = cdrom_get_track_info(dev, last_track, 1, &ti)))
  2325. + goto use_last_written;
  2326. +
  2327. +        /* if this track is blank, try the previous. */
  2328. + if (ti.blank) {
  2329. + last_track--;
  2330. + if ((ret = cdrom_get_track_info(dev, last_track, 1, &ti)))
  2331. + goto use_last_written;
  2332. + }
  2333. +
  2334. + /* if next recordable address field is valid, use it. */
  2335. + if (ti.nwa_v)
  2336. + *next_writable = be32_to_cpu(ti.next_writable);
  2337. + else
  2338. + goto use_last_written;
  2339. +
  2340. + return 0;
  2341. +
  2342. +use_last_written:
  2343. + if ((ret = cdrom_get_last_written(dev, next_writable))) {
  2344. + *next_writable = 0;
  2345. + return ret;
  2346. + } else {
  2347. + *next_writable += 7;
  2348. + return 0;
  2349. + }
  2350. +}
  2351. +
  2352. +/* return the buffer size of writeable drives */
  2353. +static int cdrom_read_buffer_capacity(struct cdrom_device_info *cdi)
  2354. +{
  2355. + struct cdrom_device_ops *cdo = cdi->ops;
  2356. + struct cdrom_generic_command cgc;
  2357. + struct {
  2358. + unsigned int pad;
  2359. + unsigned int buffer_size;
  2360. + unsigned int buffer_free;
  2361. + } buf;
  2362. + int ret;
  2363. +
  2364. + init_cdrom_command(&cgc, &buf, 12);
  2365. + cgc.cmd[0] = 0x5c;
  2366. + cgc.cmd[8] = 12;
  2367. +
  2368. + if ((ret = cdo->generic_packet(cdi, &cgc)))
  2369. + return ret;
  2370. +
  2371. + return be32_to_cpu(buf.buffer_size);
  2372. +}
  2373. +
  2374. +/* return 0 if succesful and the disc can be considered writeable. */
  2375. +static int cdrom_setup_writemode(struct cdrom_device_info *cdi)
  2376. +{
  2377. + struct cdrom_generic_command cgc;
  2378. + write_param_page wp;
  2379. + disc_information di;
  2380. + track_information ti;
  2381. + int ret, last_track;
  2382. +
  2383. + memset(&di, 0, sizeof(disc_information));
  2384. + memset(&ti, 0, sizeof(track_information));
  2385. + memset(&cdi->write, 0, sizeof(struct cdrom_write_settings));
  2386. +
  2387. + if ((ret = cdrom_get_disc_info(cdi->dev, &di)))
  2388. + return ret;
  2389. +
  2390. + last_track = (di.last_track_msb << 8) | di.last_track_lsb;
  2391. + if ((ret = cdrom_get_track_info(cdi->dev, last_track, 1, &ti)))
  2392. + return ret;
  2393. +
  2394. + /* if the media is erasable, then it is either CD-RW or
  2395. +  * DVD-RW - use fixed packets for those. non-erasable media
  2396. +  * indicated CD-R or DVD-R media, use varible sized packets for
  2397. +  * those (where the packet size is a bit less than the buffer
  2398. +  * capacity of the drive. */
  2399. + if (di.erasable) {
  2400. + cdi->write.fpacket = 1;
  2401. + /* FIXME: DVD-RW is 16, should get the packet size instead */
  2402. + cdi->write.packet_size = 32;
  2403. + } else {
  2404. + int buf_size;
  2405. + cdi->write.fpacket = 0;
  2406. + buf_size = cdrom_read_buffer_capacity(cdi);
  2407. + buf_size -= 100*1024;
  2408. + cdi->write.packet_size = buf_size / CD_FRAMESIZE;
  2409. + }
  2410. +
  2411. + init_cdrom_command(&cgc, &wp, 0x3c);
  2412. + if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_WRITE_PARMS_PAGE, 0)))
  2413. + return ret;
  2414. +
  2415. + /* sanity checks */
  2416. + if ((ti.damage && !ti.nwa_v) || ti.blank) {
  2417. + cdinfo(CD_WARNING, "can't write to this discn"); 
  2418. + return 1;
  2419. + }
  2420. +
  2421. + /* NWA is only for CD-R and DVD-R. -RW media is randomly
  2422. +  * writeable once it has been formatted. */
  2423. + cdi->write.nwa = ti.nwa_v ? be32_to_cpu(ti.next_writable) : 0;
  2424. +
  2425. + wp.fp = cdi->write.fpacket ? 1 : 0;
  2426. + wp.track_mode = 0;
  2427. + wp.write_type = 0;
  2428. + wp.data_block_type  = 8;
  2429. + wp.session_format  = 0;
  2430. + wp.multi_session = 3;
  2431. + wp.audio_pause = cpu_to_be16(0x96);
  2432. + wp.packet_size = cdi->write.fpacket ? cpu_to_be32(cdi->write.packet_size) : 0;
  2433. + wp.track_mode = 5; /* should be ok with both CD and DVD */
  2434. +
  2435. + if ((ret = cdrom_mode_select(cdi, &cgc)))
  2436. + return ret;
  2437. +
  2438. + cdinfo(CD_WARNING, "%s: writeable with %lu block %s packetsn",
  2439. + cdi->name, cdi->write.packet_size,
  2440. + cdi->write.fpacket ? "fixed" : "variable");
  2441. + return 0;
  2442.  }
  2443.  
  2444. +EXPORT_SYMBOL(cdrom_get_next_writable);
  2445. +EXPORT_SYMBOL(cdrom_get_last_written);
  2446.  EXPORT_SYMBOL(cdrom_count_tracks);
  2447.  EXPORT_SYMBOL(register_cdrom);
  2448.  EXPORT_SYMBOL(unregister_cdrom);
  2449.  EXPORT_SYMBOL(cdrom_fops);
  2450. +EXPORT_SYMBOL(cdrom_number_of_slots);
  2451. +EXPORT_SYMBOL(cdrom_select_disc);
  2452. +EXPORT_SYMBOL(cdrom_mode_select);
  2453. +EXPORT_SYMBOL(cdrom_mode_sense);
  2454. +EXPORT_SYMBOL(init_cdrom_command);
  2455.  
  2456.  #ifdef CONFIG_SYSCTL
  2457.  
  2458.  #define CDROM_STR_SIZE 1000
  2459.  
  2460. -static char cdrom_drive_info[CDROM_STR_SIZE]="infon";
  2461. +struct cdrom_sysctl_settings {
  2462. + char info[CDROM_STR_SIZE]; /* general info */
  2463. + int autoclose; /* close tray upon mount, etc */
  2464. + int autoeject; /* eject on umount */
  2465. + int debug; /* turn on debugging messages */
  2466. + int lock; /* lock the door on device open */
  2467. + int check; /* check media type */
  2468. +} cdrom_sysctl_settings;
  2469.  
  2470.  int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
  2471.                             void *buffer, size_t *lenp)
  2472.  {
  2473.          int pos;
  2474.   struct cdrom_device_info *cdi;
  2475. - char *info = cdrom_drive_info;
  2476. + char *info = cdrom_sysctl_settings.info;
  2477.  
  2478.   if (!*lenp || (filp->f_pos && !write)) {
  2479.   *lenp = 0;
  2480.   return 0;
  2481.   }
  2482.  
  2483. - pos = sprintf(cdrom_drive_info, "CD-ROM information, " VERSION "n");
  2484. + pos = sprintf(info, "CD-ROM information, " VERSION "n");
  2485.  
  2486. - pos += sprintf(cdrom_drive_info+pos, "ndrive name:t");
  2487. + pos += sprintf(info+pos, "ndrive name:t");
  2488.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2489.       pos += sprintf(info+pos, "t%s", cdi->name);
  2490.  
  2491. - pos += sprintf(cdrom_drive_info+pos, "ndrive speed:t");
  2492. + pos += sprintf(info+pos, "ndrive speed:t");
  2493.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2494.       pos += sprintf(info+pos, "t%d", cdi->speed);
  2495.  
  2496. - pos += sprintf(cdrom_drive_info+pos, "ndrive # of slots:");
  2497. + pos += sprintf(info+pos, "ndrive # of slots:");
  2498.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2499.       pos += sprintf(info+pos, "t%d", cdi->capacity);
  2500.  
  2501. - pos += sprintf(cdrom_drive_info+pos, "nCan close tray:t");
  2502. + pos += sprintf(info+pos, "nCan close tray:t");
  2503. + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2504. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0);
  2505. +
  2506. + pos += sprintf(info+pos, "nCan open tray:t");
  2507. + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2508. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0);
  2509. +
  2510. + pos += sprintf(info+pos, "nCan lock tray:t");
  2511. + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2512. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_LOCK) != 0);
  2513. +
  2514. + pos += sprintf(info+pos, "nCan change speed:");
  2515.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2516. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_CLOSE_TRAY)!=0);
  2517. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0);
  2518.  
  2519. - pos += sprintf(cdrom_drive_info+pos, "nCan open tray:t");
  2520. + pos += sprintf(info+pos, "nCan select disk:");
  2521.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2522. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_OPEN_TRAY)!=0);
  2523. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_SELECT_DISC) != 0);
  2524.  
  2525. - pos += sprintf(cdrom_drive_info+pos, "nCan lock tray:t");
  2526. + pos += sprintf(info+pos, "nCan read multisession:");
  2527.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2528. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_LOCK)!=0);
  2529. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0);
  2530.  
  2531. - pos += sprintf(cdrom_drive_info+pos, "nCan change speed:");
  2532. + pos += sprintf(info+pos, "nCan read MCN:t");
  2533.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2534. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_SELECT_SPEED)!=0);
  2535. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MCN) != 0);
  2536.  
  2537. - pos += sprintf(cdrom_drive_info+pos, "nCan select disk:");
  2538. + pos += sprintf(info+pos, "nReports media changed:");
  2539.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2540. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_SELECT_DISC)!=0);
  2541. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0);
  2542.  
  2543. - pos += sprintf(cdrom_drive_info+pos, "nCan read multisession:");
  2544. + pos += sprintf(info+pos, "nCan play audio:t");
  2545.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2546. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MULTI_SESSION)!=0);
  2547. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0);
  2548.  
  2549. - pos += sprintf(cdrom_drive_info+pos, "nCan read MCN:t");
  2550. + pos += sprintf(info+pos, "nCan write CD-R:t");
  2551.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2552. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MCN)!=0);
  2553. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_CD_R) != 0);
  2554.  
  2555. - pos += sprintf(cdrom_drive_info+pos, "nReports media changed:");
  2556. + pos += sprintf(info+pos, "nCan write CD-RW:");
  2557.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2558. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_MEDIA_CHANGED)!=0);
  2559. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_CD_RW) != 0);
  2560.  
  2561. - pos += sprintf(cdrom_drive_info+pos, "nCan play audio:t");
  2562. + pos += sprintf(info+pos, "nCan read DVD:t");
  2563.   for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2564. -     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_PLAY_AUDIO)!=0);
  2565. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_DVD) != 0);
  2566.  
  2567. -        strcpy(info+pos,"nn");
  2568. - pos += 3;
  2569. - if (*lenp > pos)
  2570. - *lenp = pos;
  2571. + pos += sprintf(info+pos, "nCan write DVD-R:");
  2572. + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2573. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_DVD_R) != 0);
  2574. +
  2575. + pos += sprintf(info+pos, "nCan write DVD-RAM:");
  2576. + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
  2577. +     pos += sprintf(info+pos, "t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
  2578. +
  2579. + strcpy(info+pos,"nn");
  2580.  
  2581.          return proc_dostring(ctl, write, filp, buffer, lenp);
  2582.  }
  2583.  
  2584. +/* Unfortunately, per device settings are not implemented through
  2585. +   procfs/sysctl yet. When they are, this will naturally disappear. For now
  2586. +   just update all drives. Later this will become the template on which
  2587. +   new registered drives will be based. */
  2588. +void cdrom_update_settings(void)
  2589. +{
  2590. + struct cdrom_device_info *cdi;
  2591. +
  2592. + for (cdi = topCdromPtr; cdi != NULL; cdi = cdi->next) {
  2593. + if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY))
  2594. + cdi->options |= CDO_AUTO_CLOSE;
  2595. + else if (!autoclose)
  2596. + cdi->options &= ~CDO_AUTO_CLOSE;
  2597. + if (autoeject && CDROM_CAN(CDC_OPEN_TRAY))
  2598. + cdi->options |= CDO_AUTO_EJECT;
  2599. + else if (!autoeject)
  2600. + cdi->options &= ~CDO_AUTO_EJECT;
  2601. + if (lockdoor && CDROM_CAN(CDC_LOCK))
  2602. + cdi->options |= CDO_LOCK;
  2603. + else if (!lockdoor)
  2604. + cdi->options &= ~CDO_LOCK;
  2605. + if (check_media_type)
  2606. + cdi->options |= CDO_CHECK_TYPE;
  2607. + else
  2608. + cdi->options &= ~CDO_CHECK_TYPE;
  2609. + }
  2610. +}
  2611. +
  2612. +static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
  2613. + void *buffer, size_t *lenp)
  2614. +{
  2615. + int *valp = ctl->data;
  2616. + int val = *valp;
  2617. + int ret;
  2618. +
  2619. + ret = proc_dointvec(ctl, write, filp, buffer, lenp);
  2620. +
  2621. + if (write && *valp != val) {
  2622. +
  2623. + /* we only care for 1 or 0. */
  2624. + if (*valp)
  2625. + *valp = 1;
  2626. + else
  2627. + *valp = 0;
  2628. +
  2629. + switch (ctl->ctl_name) {
  2630. + case DEV_CDROM_AUTOCLOSE: {
  2631. + if (valp == &cdrom_sysctl_settings.autoclose)
  2632. + autoclose = cdrom_sysctl_settings.autoclose;
  2633. + break;
  2634. + }
  2635. + case DEV_CDROM_AUTOEJECT: {
  2636. + if (valp == &cdrom_sysctl_settings.autoeject)
  2637. + autoeject = cdrom_sysctl_settings.autoeject;
  2638. + break;
  2639. + }
  2640. + case DEV_CDROM_DEBUG: {
  2641. + if (valp == &cdrom_sysctl_settings.debug)
  2642. + debug = cdrom_sysctl_settings.debug;
  2643. + break;
  2644. + }
  2645. + case DEV_CDROM_LOCK: {
  2646. + if (valp == &cdrom_sysctl_settings.lock)
  2647. + lockdoor = cdrom_sysctl_settings.lock;
  2648. + break;
  2649. + }
  2650. + case DEV_CDROM_CHECK_MEDIA: {
  2651. + if (valp == &cdrom_sysctl_settings.check)
  2652. + check_media_type = cdrom_sysctl_settings.check;
  2653. + break;
  2654. + }
  2655. + }
  2656. + /* update the option flags according to the changes. we
  2657. +    don't have per device options through sysctl yet,
  2658. +    but we will have and then this will disappear. */
  2659. + cdrom_update_settings();
  2660. + }
  2661. +
  2662. +        return ret;
  2663. +}
  2664. +
  2665.  /* Place files in /proc/sys/dev/cdrom */
  2666.  ctl_table cdrom_table[] = {
  2667. - {DEV_CDROM_INFO, "info", &cdrom_drive_info, 
  2668. + {DEV_CDROM_INFO, "info", &cdrom_sysctl_settings.info, 
  2669.   CDROM_STR_SIZE, 0444, NULL, &cdrom_sysctl_info},
  2670. + {DEV_CDROM_AUTOCLOSE, "autoclose", &cdrom_sysctl_settings.autoclose,
  2671. + sizeof(int), 0644, NULL, &cdrom_sysctl_handler },
  2672. + {DEV_CDROM_AUTOEJECT, "autoeject", &cdrom_sysctl_settings.autoeject,
  2673. + sizeof(int), 0644, NULL, &cdrom_sysctl_handler },
  2674. + {DEV_CDROM_DEBUG, "debug", &cdrom_sysctl_settings.debug,
  2675. + sizeof(int), 0644, NULL, &cdrom_sysctl_handler },
  2676. + {DEV_CDROM_LOCK, "lock", &cdrom_sysctl_settings.lock,
  2677. + sizeof(int), 0644, NULL, &cdrom_sysctl_handler },
  2678. + {DEV_CDROM_CHECK_MEDIA, "check_media", &cdrom_sysctl_settings.check,
  2679. + sizeof(int), 0644, NULL, &cdrom_sysctl_handler },
  2680.   {0}
  2681.   };
  2682.  
  2683. @@ -1199,24 +2558,31 @@
  2684.   cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);
  2685.   cdrom_root_table->child->de->fill_inode = &cdrom_procfs_modcount;
  2686.  
  2687. + /* set the defaults */
  2688. + cdrom_sysctl_settings.autoclose = autoclose;
  2689. + cdrom_sysctl_settings.autoeject = autoeject;
  2690. + cdrom_sysctl_settings.debug = debug;
  2691. + cdrom_sysctl_settings.lock = lockdoor;
  2692. + cdrom_sysctl_settings.check = check_media_type;
  2693. +
  2694.   initialized = 1;
  2695.  }
  2696. +#endif /* endif CONFIG_SYSCTL */
  2697. +
  2698.  
  2699.  #ifdef MODULE
  2700.  static void cdrom_sysctl_unregister(void)
  2701.  {
  2702. +#ifdef CONFIG_SYSCTL
  2703.   unregister_sysctl_table(cdrom_sysctl_header);
  2704. +#endif
  2705.  }
  2706. -#endif /* endif MODULE */
  2707. -#endif /* endif CONFIG_SYSCTL */
  2708. -
  2709. -#ifdef MODULE
  2710.  
  2711.  int init_module(void)
  2712.  {
  2713.  #ifdef CONFIG_SYSCTL
  2714.   cdrom_sysctl_register();
  2715. -#endif /* CONFIG_SYSCTL */ 
  2716. +#endif
  2717.   return 0;
  2718.  }
  2719.  
  2720. @@ -1227,14 +2593,5 @@
  2721.   cdrom_sysctl_unregister();
  2722.  #endif /* CONFIG_SYSCTL */ 
  2723.  }
  2724. -
  2725.  #endif /* endif MODULE */
  2726.  
  2727. -
  2728. -
  2729. -/*
  2730. - * Local variables:
  2731. - * comment-column: 40
  2732. - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DCPU=486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h  -c -o cdrom.o cdrom.c"
  2733. - * End:
  2734. - */
  2735. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
  2736. --- linux-2.2.13/drivers/scsi/ide-scsi.c Thu Sep  9 12:27:37 1999
  2737. +++ linux/drivers/scsi/ide-scsi.c Sun Nov  7 15:23:25 1999
  2738. @@ -365,7 +365,7 @@
  2739.   pc->actually_transferred += temp;
  2740.   pc->current_position += temp;
  2741.   idescsi_discard_data (drive,bcount - temp);
  2742. - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc));
  2743. + ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);
  2744.   return;
  2745.   }
  2746.  #if IDESCSI_DEBUG_LOG
  2747. @@ -389,7 +389,7 @@
  2748.   pc->actually_transferred+=bcount; /* Update the current position */
  2749.   pc->current_position+=bcount;
  2750.  
  2751. - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc)); /* And set the interrupt handler again */
  2752. + ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL); /* And set the interrupt handler again */
  2753.  }
  2754.  
  2755.  static void idescsi_transfer_pc (ide_drive_t *drive)
  2756. @@ -408,7 +408,7 @@
  2757.   ide_do_reset (drive);
  2758.   return;
  2759.   }
  2760. - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc)); /* Set the interrupt routine */
  2761. + ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL); /* Set the interrupt routine */
  2762.   atapi_output_bytes (drive, scsi->pc->c, 12); /* Send the actual packet */
  2763.  }
  2764.  
  2765. @@ -441,7 +441,7 @@
  2766.   (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
  2767.   }
  2768.   if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
  2769. - ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc));
  2770. + ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc), NULL);
  2771.   OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
  2772.   } else {
  2773.   OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
  2774. diff -ur --exclude-from /home/axboe/cdrom/exclude-from linux-2.2.13/drivers/scsi/sr.c linux/drivers/scsi/sr.c
  2775. --- linux-2.2.13/drivers/scsi/sr.c Fri Jan 15 23:41:04 1999
  2776. +++ linux/drivers/scsi/sr.c Sun Oct 31 13:37:07 1999
  2777. @@ -1,25 +1,28 @@
  2778.  /*
  2779.   *  sr.c Copyright (C) 1992 David Giller
  2780. - *      Copyright (C) 1993, 1994, 1995 Eric Youngdale
  2781. + *           Copyright (C) 1993, 1994, 1995 Eric Youngdale
  2782.   *
  2783.   *  adapted from:
  2784. - * sd.c Copyright (C) 1992 Drew Eckhardt
  2785. - * Linux scsi disk driver by
  2786. - * Drew Eckhardt <drew@colorado.edu>
  2787. + *      sd.c Copyright (C) 1992 Drew Eckhardt
  2788. + *      Linux scsi disk driver by
  2789. + *              Drew Eckhardt <drew@colorado.edu>
  2790.   *
  2791.   *      Modified by Eric Youngdale ericy@cais.com to
  2792.   *      add scatter-gather, multiple outstanding request, and other
  2793.   *      enhancements.
  2794.   *
  2795. - *     Modified by Eric Youngdale eric@aib.com to support loadable
  2796. - *     low-level scsi drivers.
  2797. + *          Modified by Eric Youngdale eric@aib.com to support loadable
  2798. + *          low-level scsi drivers.
  2799.   *
  2800. - *  Modified by Thomas Quinot thomas@melchior.cuivre.fdn.fr to
  2801. - *  provide auto-eject.
  2802. + *       Modified by Thomas Quinot thomas@melchior.cuivre.fdn.fr to
  2803. + *       provide auto-eject.
  2804.   *
  2805.   *          Modified by Gerd Knorr <kraxel@cs.tu-berlin.de> to support the
  2806.   *          generic cdrom interface
  2807.   *
  2808. + *       Modified by Jens Axboe <axboe@image.dk> - Uniform sr_packet()
  2809. + *       interface, capabilities probe additions, ioctl cleanups, etc.
  2810. + *
  2811.   */
  2812.  
  2813.  #include <linux/module.h>
  2814. @@ -34,19 +37,22 @@
  2815.  #include <linux/interrupt.h>
  2816.  #include <asm/system.h>
  2817.  #include <asm/io.h>
  2818. +#include <asm/uaccess.h>
  2819.  
  2820.  #define MAJOR_NR SCSI_CDROM_MAJOR
  2821.  #include <linux/blk.h>
  2822.  #include "scsi.h"
  2823.  #include "hosts.h"
  2824.  #include "sr.h"
  2825. -#include <scsi/scsi_ioctl.h>   /* For the door lock/unlock commands */
  2826. +#include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */
  2827.  #include "constants.h"
  2828.  
  2829. -MODULE_PARM(xa_test,"i"); /* see sr_ioctl.c */
  2830. +#ifdef MODULE
  2831. +MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */
  2832. +#endif
  2833.  
  2834. -#define MAX_RETRIES 3
  2835. -#define SR_TIMEOUT (30 * HZ)
  2836. +#define MAX_RETRIES 3
  2837. +#define SR_TIMEOUT (30 * HZ)
  2838.  
  2839.  static int sr_init(void);
  2840.  static void sr_finish(void);
  2841. @@ -54,53 +60,60 @@
  2842.  static int sr_detect(Scsi_Device *);
  2843.  static void sr_detach(Scsi_Device *);
  2844.  
  2845. -struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", NULL, TYPE_ROM,
  2846. -                                           SCSI_CDROM_MAJOR, 0, 0, 0, 1,
  2847. -                                           sr_detect, sr_init,
  2848. -                                           sr_finish, sr_attach, sr_detach};
  2849. +struct Scsi_Device_Template sr_template = {
  2850. + NULL, "cdrom", "sr", NULL, TYPE_ROM,
  2851. + SCSI_CDROM_MAJOR, 0, 0, 0, 1,
  2852. + sr_detect, sr_init,
  2853. + sr_finish, sr_attach, sr_detach
  2854. +};
  2855.  
  2856. -Scsi_CD * scsi_CDs = NULL;
  2857. -static int * sr_sizes = NULL;
  2858. +Scsi_CD *scsi_CDs = NULL;
  2859. +static int *sr_sizes = NULL;
  2860.  
  2861. -static int * sr_blocksizes = NULL;
  2862. +static int *sr_blocksizes = NULL;
  2863.  
  2864. -static int sr_open(struct cdrom_device_info*, int);
  2865. +static int sr_open(struct cdrom_device_info *, int);
  2866.  void get_sectorsize(int);
  2867.  void get_capabilities(int);
  2868.  
  2869. -void requeue_sr_request (Scsi_Cmnd * SCpnt);
  2870. -static int sr_media_change(struct cdrom_device_info*, int);
  2871. +void requeue_sr_request(Scsi_Cmnd * SCpnt);
  2872. +static int sr_media_change(struct cdrom_device_info *, int);
  2873. +static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
  2874.  
  2875.  static void sr_release(struct cdrom_device_info *cdi)
  2876.  {
  2877.   if (scsi_CDs[MINOR(cdi->dev)].sector_size > 2048)
  2878. - sr_set_blocklength(MINOR(cdi->dev),2048);
  2879. + sr_set_blocklength(MINOR(cdi->dev), 2048);
  2880.   sync_dev(cdi->dev);
  2881.   scsi_CDs[MINOR(cdi->dev)].device->access_count--;
  2882.   if (scsi_CDs[MINOR(cdi->dev)].device->host->hostt->module)
  2883.   __MOD_DEC_USE_COUNT(scsi_CDs[MINOR(cdi->dev)].device->host->hostt->module);
  2884. - if(sr_template.module)
  2885. -         __MOD_DEC_USE_COUNT(sr_template.module);
  2886. + if (sr_template.module)
  2887. + __MOD_DEC_USE_COUNT(sr_template.module);
  2888.  }
  2889.  
  2890. -static struct cdrom_device_ops sr_dops = {
  2891. -        sr_open,                      /* open */
  2892. -        sr_release,                   /* release */
  2893. -        sr_drive_status,              /* drive status */
  2894. -        sr_media_change,              /* media changed */
  2895. -        sr_tray_move,                 /* tray move */
  2896. -        sr_lock_door,                 /* lock door */
  2897. -        sr_select_speed,              /* select speed */
  2898. -        NULL,                         /* select disc */
  2899. -        sr_get_last_session,          /* get last session */
  2900. -        sr_get_mcn,                   /* get universal product code */
  2901. -        sr_reset,                     /* hard reset */
  2902. -        sr_audio_ioctl,               /* audio ioctl */
  2903. -        sr_dev_ioctl,                 /* device-specific ioctl */
  2904. -        CDC_CLOSE_TRAY | CDC_OPEN_TRAY| CDC_LOCK | CDC_SELECT_SPEED |
  2905. -        CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
  2906. -        CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
  2907. -        0
  2908. +static struct cdrom_device_ops sr_dops =
  2909. +{
  2910. + sr_open, /* open */
  2911. + sr_release, /* release */
  2912. + sr_drive_status, /* drive status */
  2913. + sr_media_change, /* media changed */
  2914. + sr_tray_move, /* tray move */
  2915. + sr_lock_door, /* lock door */
  2916. + sr_select_speed, /* select speed */
  2917. + NULL, /* select disc */
  2918. + sr_get_last_session, /* get last session */
  2919. + sr_get_mcn, /* get universal product code */
  2920. + sr_reset, /* hard reset */
  2921. + sr_audio_ioctl, /* audio ioctl */
  2922. + sr_dev_ioctl, /* device-specific ioctl */
  2923. + CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED |
  2924. + CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED |
  2925. + CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS |
  2926. + CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM |
  2927. + CDC_GENERIC_PACKET,
  2928. + 0,
  2929. + sr_packet
  2930.  };
  2931.  
  2932.  /*
  2933. @@ -113,48 +126,47 @@
  2934.   * an inode for that to work, and we do not always have one.
  2935.   */
  2936.  
  2937. -int sr_media_change(struct cdrom_device_info *cdi, int slot){
  2938. +int sr_media_change(struct cdrom_device_info *cdi, int slot)
  2939. +{
  2940.   int retval;
  2941.  
  2942. -        if (CDSL_CURRENT != slot) {
  2943. -                /* no changer support */
  2944. -                return -EINVAL;
  2945. -        }
  2946. -
  2947. + if (CDSL_CURRENT != slot) {
  2948. + /* no changer support */
  2949. + return -EINVAL;
  2950. + }
  2951.   retval = scsi_ioctl(scsi_CDs[MINOR(cdi->dev)].device,
  2952. -                            SCSI_IOCTL_TEST_UNIT_READY, 0);
  2953. +     SCSI_IOCTL_TEST_UNIT_READY, 0);
  2954.  
  2955. - if(retval)
  2956. -        {
  2957. -                /* Unable to test, unit probably not ready.  This usually
  2958. + if (retval) {
  2959. + /* Unable to test, unit probably not ready.  This usually
  2960.    * means there is no disc in the drive.  Mark as changed,
  2961.    * and we will figure it out later once the drive is
  2962.    * available again.  */
  2963.  
  2964. -                scsi_CDs[MINOR(cdi->dev)].device->changed = 1;
  2965. -                return 1; /* This will force a flush, if called from
  2966. -                           * check_disk_change */
  2967. + scsi_CDs[MINOR(cdi->dev)].device->changed = 1;
  2968. + return 1; /* This will force a flush, if called from
  2969. +  * check_disk_change */
  2970.   };
  2971.  
  2972.   retval = scsi_CDs[MINOR(cdi->dev)].device->changed;
  2973. -        scsi_CDs[MINOR(cdi->dev)].device->changed = 0;
  2974. -        /* If the disk changed, the capacity will now be different,
  2975. -         * so we force a re-read of this information */
  2976. -        if (retval) {
  2977. + scsi_CDs[MINOR(cdi->dev)].device->changed = 0;
  2978. + /* If the disk changed, the capacity will now be different,
  2979. +  * so we force a re-read of this information */
  2980. + if (retval) {
  2981.   /* check multisession offset etc */
  2982. -                sr_cd_check(cdi);
  2983. -
  2984. -                 /* 
  2985. -                  * If the disk changed, the capacity will now be different,
  2986. -                  * so we force a re-read of this information 
  2987. -                  * Force 2048 for the sector size so that filesystems won't
  2988. -                  * be trying to use something that is too small if the disc
  2989. -                  * has changed.
  2990. -                  */
  2991. -                scsi_CDs[MINOR(cdi->dev)].needs_sector_size = 1;
  2992. + sr_cd_check(cdi);
  2993. +
  2994. + /* 
  2995. +  * If the disk changed, the capacity will now be different,
  2996. +  * so we force a re-read of this information 
  2997. +  * Force 2048 for the sector size so that filesystems won't
  2998. +  * be trying to use something that is too small if the disc
  2999. +  * has changed.
  3000. +  */
  3001. + scsi_CDs[MINOR(cdi->dev)].needs_sector_size = 1;
  3002.  
  3003. -                scsi_CDs[MINOR(cdi->dev)].sector_size = 2048;
  3004. -        }
  3005. + scsi_CDs[MINOR(cdi->dev)].sector_size = 2048;
  3006. + }
  3007.   return retval;
  3008.  }
  3009.  
  3010. @@ -163,7 +175,7 @@
  3011.   * end of a SCSI read / write, and will take on of several actions based on success or failure.
  3012.   */
  3013.  
  3014. -static void rw_intr (Scsi_Cmnd * SCpnt)
  3015. +static void rw_intr(Scsi_Cmnd * SCpnt)
  3016.  {
  3017.   int result = SCpnt->result;
  3018.   int this_count = SCpnt->this_count;
  3019. @@ -171,137 +183,130 @@
  3020.   int block_sectors = 0;
  3021.  
  3022.  #ifdef DEBUG
  3023. - printk("sr.c done: %x %xn",result, SCpnt->request.bh->b_data);
  3024. + printk("sr.c done: %x %xn", result, SCpnt->request.bh->b_data);
  3025.  #endif
  3026. -    /*
  3027. -      Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success.
  3028. -      Since this is a relatively rare error condition, no care is taken to
  3029. -      avoid unnecessary additional work such as memcpy's that could be avoided.
  3030. -    */
  3031. + /*
  3032. +    Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success.
  3033. +    Since this is a relatively rare error condition, no care is taken to
  3034. +    avoid unnecessary additional work such as memcpy's that could be avoided.
  3035. +  */
  3036.  
  3037. - if (driver_byte(result) != 0 &&     /* An error occurred */
  3038. -     SCpnt->sense_buffer[0] == 0xF0 &&     /* Sense data is valid */
  3039. + if (driver_byte(result) != 0 && /* An error occurred */
  3040. +     SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */
  3041.       (SCpnt->sense_buffer[2] == MEDIUM_ERROR ||
  3042.        SCpnt->sense_buffer[2] == VOLUME_OVERFLOW ||
  3043. -      SCpnt->sense_buffer[2] == ILLEGAL_REQUEST))
  3044. -   {
  3045. -     long error_sector = (SCpnt->sense_buffer[3] << 24) |
  3046. - (SCpnt->sense_buffer[4] << 16) |
  3047. - (SCpnt->sense_buffer[5] << 8) |
  3048. - SCpnt->sense_buffer[6];
  3049. -     int device_nr = DEVICE_NR(SCpnt->request.rq_dev);
  3050. -     if (SCpnt->request.bh != NULL)
  3051. -       block_sectors = SCpnt->request.bh->b_size >> 9;
  3052. -     if (block_sectors < 4) block_sectors = 4;
  3053. -     if (scsi_CDs[device_nr].sector_size == 2048)
  3054. -       error_sector <<= 2;
  3055. -     error_sector &= ~ (block_sectors - 1);
  3056. -     good_sectors = error_sector - SCpnt->request.sector;
  3057. -     if (good_sectors < 0 || good_sectors >= this_count)
  3058. -       good_sectors = 0;
  3059. -     /*
  3060. -       The SCSI specification allows for the value returned by READ
  3061. -       CAPACITY to be up to 75 2K sectors past the last readable
  3062. -       block.  Therefore, if we hit a medium error within the last
  3063. -       75 2K sectors, we decrease the saved size value.
  3064. -     */
  3065. -     if ((error_sector >> 1) < sr_sizes[device_nr] &&
  3066. - scsi_CDs[device_nr].capacity - error_sector < 4*75)
  3067. -       sr_sizes[device_nr] = error_sector >> 1;
  3068. -   }
  3069. -
  3070. - if (good_sectors > 0)
  3071. -    { /* Some sectors were read successfully. */
  3072. - if (SCpnt->use_sg == 0) {
  3073. -     if (SCpnt->buffer != SCpnt->request.buffer)
  3074. -     {
  3075. - int offset;
  3076. - offset = (SCpnt->request.sector % 4) << 9;
  3077. - memcpy((char *)SCpnt->request.buffer,
  3078. -        (char *)SCpnt->buffer + offset,
  3079. -        good_sectors << 9);
  3080. - /* Even though we are not using scatter-gather, we look
  3081. -  * ahead and see if there is a linked request for the
  3082. -  * other half of this buffer.  If there is, then satisfy
  3083. -  * it. */
  3084. - if((offset == 0) && good_sectors == 2 &&
  3085. -    SCpnt->request.nr_sectors > good_sectors &&
  3086. -    SCpnt->request.bh &&
  3087. -    SCpnt->request.bh->b_reqnext &&
  3088. -    SCpnt->request.bh->b_reqnext->b_size == 1024) {
  3089. -     memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
  3090. -    (char *)SCpnt->buffer + 1024,
  3091. -    1024);
  3092. -     good_sectors += 2;
  3093. - };
  3094. +      SCpnt->sense_buffer[2] == ILLEGAL_REQUEST)) {
  3095. + long error_sector = (SCpnt->sense_buffer[3] << 24) |
  3096. + (SCpnt->sense_buffer[4] << 16) |
  3097. + (SCpnt->sense_buffer[5] << 8) |
  3098. + SCpnt->sense_buffer[6];
  3099. + int device_nr = DEVICE_NR(SCpnt->request.rq_dev);
  3100. + if (SCpnt->request.bh != NULL)
  3101. + block_sectors = SCpnt->request.bh->b_size >> 9;
  3102. + if (block_sectors < 4)
  3103. + block_sectors = 4;
  3104. + if (scsi_CDs[device_nr].sector_size == 2048)
  3105. + error_sector <<= 2;
  3106. + error_sector &= ~(block_sectors - 1);
  3107. + good_sectors = error_sector - SCpnt->request.sector;
  3108. + if (good_sectors < 0 || good_sectors >= this_count)
  3109. + good_sectors = 0;
  3110. + /*
  3111. +    The SCSI specification allows for the value returned by READ
  3112. +    CAPACITY to be up to 75 2K sectors past the last readable
  3113. +    block.  Therefore, if we hit a medium error within the last
  3114. +    75 2K sectors, we decrease the saved size value.
  3115. +  */
  3116. + if ((error_sector >> 1) < sr_sizes[device_nr] &&
  3117. +     scsi_CDs[device_nr].capacity - error_sector < 4 * 75)
  3118. + sr_sizes[device_nr] = error_sector >> 1;
  3119. + }
  3120. + if (good_sectors > 0) { /* Some sectors were read successfully. */
  3121. + if (SCpnt->use_sg == 0) {
  3122. + if (SCpnt->buffer != SCpnt->request.buffer) {
  3123. + int offset;
  3124. + offset = (SCpnt->request.sector % 4) << 9;
  3125. + memcpy((char *) SCpnt->request.buffer,
  3126. +        (char *) SCpnt->buffer + offset,
  3127. +        good_sectors << 9);
  3128. + /* Even though we are not using scatter-gather, we look
  3129. +  * ahead and see if there is a linked request for the
  3130. +  * other half of this buffer.  If there is, then satisfy
  3131. +  * it. */
  3132. + if ((offset == 0) && good_sectors == 2 &&
  3133. +     SCpnt->request.nr_sectors > good_sectors &&
  3134. +     SCpnt->request.bh &&
  3135. +     SCpnt->request.bh->b_reqnext &&
  3136. +     SCpnt->request.bh->b_reqnext->b_size == 1024) {
  3137. + memcpy((char *) SCpnt->request.bh->b_reqnext->b_data,
  3138. +    (char *) SCpnt->buffer + 1024,
  3139. +        1024);
  3140. + good_sectors += 2;
  3141. + };
  3142.  
  3143. - scsi_free(SCpnt->buffer, 2048);
  3144. -     }
  3145. - } else {
  3146. -     struct scatterlist * sgpnt;
  3147. -     int i;
  3148. -     sgpnt = (struct scatterlist *) SCpnt->buffer;
  3149. -     for(i=0; i<SCpnt->use_sg; i++) {
  3150. - if (sgpnt[i].alt_address) {
  3151. -     if (sgpnt[i].alt_address != sgpnt[i].address) {
  3152. - memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
  3153. -     };
  3154. -     scsi_free(sgpnt[i].address, sgpnt[i].length);
  3155. + scsi_free(SCpnt->buffer, 2048);
  3156. + }
  3157. + } else {
  3158. + struct scatterlist *sgpnt;
  3159. + int i;
  3160. + sgpnt = (struct scatterlist *) SCpnt->buffer;
  3161. + for (i = 0; i < SCpnt->use_sg; i++) {
  3162. + if (sgpnt[i].alt_address) {
  3163. + if (sgpnt[i].alt_address != sgpnt[i].address) {
  3164. + memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
  3165. + };
  3166. + scsi_free(sgpnt[i].address, sgpnt[i].length);
  3167. + };
  3168. + };
  3169. + scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */
  3170. + if (SCpnt->request.sector % 4)
  3171. + good_sectors -= 2;