vserver 1.9.5.x5
[linux-2.6.git] / drivers / cdrom / mcdx.c
1 /*
2  * The Mitsumi CDROM interface
3  * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
4  * VERSION: 2.14(hs)
5  *
6  * ... anyway, I'm back again, thanks to Marcin, he adopted
7  * large portions of my code (at least the parts containing
8  * my main thoughts ...)
9  *
10  ****************** H E L P *********************************
11  * If you ever plan to update your CD ROM drive and perhaps
12  * want to sell or simply give away your Mitsumi FX-001[DS]
13  * -- Please --
14  * mail me (heiko@lotte.sax.de).  When my last drive goes
15  * ballistic no more driver support will be available from me!
16  *************************************************************
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2, or (at your option)
21  * any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; see the file COPYING.  If not, write to
30  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31  *
32  * Thanks to
33  *  The Linux Community at all and ...
34  *  Martin Harriss (he wrote the first Mitsumi Driver)
35  *  Eberhard Moenkeberg (he gave me much support and the initial kick)
36  *  Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they
37  *      improved the original driver)
38  *  Jon Tombs, Bjorn Ekwall (module support)
39  *  Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
40  *  Gerd Knorr (he lent me his PhotoCD)
41  *  Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
42  *  Andreas Kies (testing the mysterious hang-ups)
43  *  Heiko Eissfeldt (VERIFY_READ/WRITE)
44  *  Marcin Dalecki (improved performance, shortened code)
45  *  ... somebody forgotten?
46  *
47  *  9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
48  *                     Removed init_module & cleanup_module in favor of 
49  *                     module_init & module_exit.
50  *                     Torben Mathiasen <tmm@image.dk>
51  */
52
53
54 #if RCS
55 static const char *mcdx_c_version
56     = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
57 #endif
58
59 #include <linux/module.h>
60
61 #include <linux/errno.h>
62 #include <linux/interrupt.h>
63 #include <linux/fs.h>
64 #include <linux/kernel.h>
65 #include <linux/cdrom.h>
66 #include <linux/ioport.h>
67 #include <linux/mm.h>
68 #include <linux/slab.h>
69 #include <linux/init.h>
70 #include <asm/io.h>
71 #include <asm/current.h>
72 #include <asm/uaccess.h>
73
74 #include <linux/major.h>
75 #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
76 #include <linux/blkdev.h>
77 #include <linux/devfs_fs_kernel.h>
78
79 #include "mcdx.h"
80
81 #ifndef HZ
82 #error HZ not defined
83 #endif
84
85 #define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args)
86
87 #if !MCDX_QUIET
88 #define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args)
89 #else
90 #define xinfo(fmt, args...) { ; }
91 #endif
92
93 #if MCDX_DEBUG
94 #define xtrace(lvl, fmt, args...) \
95                 { if (lvl > 0) \
96                         { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } }
97 #define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args)
98 #else
99 #define xtrace(lvl, fmt, args...) { ; }
100 #define xdebug(fmt, args...) { ; }
101 #endif
102
103 /* CONSTANTS *******************************************************/
104
105 /* Following are the number of sectors we _request_ from the drive
106    every time an access outside the already requested range is done.
107    The _direct_ size is the number of sectors we're allowed to skip
108    directly (performing a read instead of requesting the new sector
109    needed */
110 const int REQUEST_SIZE = 800;   /* should be less then 255 * 4 */
111 const int DIRECT_SIZE = 400;    /* should be less then REQUEST_SIZE */
112
113 enum drivemodes { TOC, DATA, RAW, COOKED };
114 enum datamodes { MODE0, MODE1, MODE2 };
115 enum resetmodes { SOFT, HARD };
116
117 const int SINGLE = 0x01;        /* single speed drive (FX001S, LU) */
118 const int DOUBLE = 0x02;        /* double speed drive (FX001D, ..? */
119 const int DOOR = 0x04;          /* door locking capability */
120 const int MULTI = 0x08;         /* multi session capability */
121
122 const unsigned char READ1X = 0xc0;
123 const unsigned char READ2X = 0xc1;
124
125
126 /* DECLARATIONS ****************************************************/
127 struct s_subqcode {
128         unsigned char control;
129         unsigned char tno;
130         unsigned char index;
131         struct cdrom_msf0 tt;
132         struct cdrom_msf0 dt;
133 };
134
135 struct s_diskinfo {
136         unsigned int n_first;
137         unsigned int n_last;
138         struct cdrom_msf0 msf_leadout;
139         struct cdrom_msf0 msf_first;
140 };
141
142 struct s_multi {
143         unsigned char multi;
144         struct cdrom_msf0 msf_last;
145 };
146
147 struct s_version {
148         unsigned char code;
149         unsigned char ver;
150 };
151
152 /* Per drive/controller stuff **************************************/
153
154 struct s_drive_stuff {
155         /* waitqueues */
156         wait_queue_head_t busyq;
157         wait_queue_head_t lockq;
158         wait_queue_head_t sleepq;
159
160         /* flags */
161         volatile int introk;    /* status of last irq operation */
162         volatile int busy;      /* drive performs an operation */
163         volatile int lock;      /* exclusive usage */
164
165         /* cd infos */
166         struct s_diskinfo di;
167         struct s_multi multi;
168         struct s_subqcode *toc; /* first entry of the toc array */
169         struct s_subqcode start;
170         struct s_subqcode stop;
171         int xa;                 /* 1 if xa disk */
172         int audio;              /* 1 if audio disk */
173         int audiostatus;
174
175         /* `buffer' control */
176         volatile int valid;     /* pending, ..., values are valid */
177         volatile int pending;   /* next sector to be read */
178         volatile int low_border;        /* first sector not to be skipped direct */
179         volatile int high_border;       /* first sector `out of area' */
180 #ifdef AK2
181         volatile int int_err;
182 #endif                          /* AK2 */
183
184         /* adds and odds */
185         unsigned wreg_data;     /* w data */
186         unsigned wreg_reset;    /* w hardware reset */
187         unsigned wreg_hcon;     /* w hardware conf */
188         unsigned wreg_chn;      /* w channel */
189         unsigned rreg_data;     /* r data */
190         unsigned rreg_status;   /* r status */
191
192         int irq;                /* irq used by this drive */
193         int present;            /* drive present and its capabilities */
194         unsigned char readcmd;  /* read cmd depends on single/double speed */
195         unsigned char playcmd;  /* play should always be single speed */
196         unsigned int xxx;       /* set if changed, reset while open */
197         unsigned int yyy;       /* set if changed, reset by media_changed */
198         int users;              /* keeps track of open/close */
199         int lastsector;         /* last block accessible */
200         int status;             /* last operation's error / status */
201         int readerrs;           /* # of blocks read w/o error */
202         struct cdrom_device_info info;
203         struct gendisk *disk;
204 };
205
206
207 /* Prototypes ******************************************************/
208
209 /*      The following prototypes are already declared elsewhere.  They are
210         repeated here to show what's going on.  And to sense, if they're
211         changed elsewhere. */
212
213 /* declared in blk.h */
214 int mcdx_init(void);
215 void do_mcdx_request(request_queue_t * q);
216
217 static int mcdx_block_open(struct inode *inode, struct file *file)
218 {
219         struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
220         return cdrom_open(&p->info, inode, file);
221 }
222
223 static int mcdx_block_release(struct inode *inode, struct file *file)
224 {
225         struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
226         return cdrom_release(&p->info, file);
227 }
228
229 static int mcdx_block_ioctl(struct inode *inode, struct file *file,
230                                 unsigned cmd, unsigned long arg)
231 {
232         struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
233         return cdrom_ioctl(file, &p->info, inode, cmd, arg);
234 }
235
236 static int mcdx_block_media_changed(struct gendisk *disk)
237 {
238         struct s_drive_stuff *p = disk->private_data;
239         return cdrom_media_changed(&p->info);
240 }
241
242 static struct block_device_operations mcdx_bdops =
243 {
244         .owner          = THIS_MODULE,
245         .open           = mcdx_block_open,
246         .release        = mcdx_block_release,
247         .ioctl          = mcdx_block_ioctl,
248         .media_changed  = mcdx_block_media_changed,
249 };
250
251
252 /*      Indirect exported functions. These functions are exported by their
253         addresses, such as mcdx_open and mcdx_close in the
254         structure mcdx_dops. */
255
256 /* exported by file_ops */
257 static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
258 static void mcdx_close(struct cdrom_device_info *cdi);
259 static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
260 static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
261 static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
262 static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
263                             unsigned int cmd, void *arg);
264
265 /* misc internal support functions */
266 static void log2msf(unsigned int, struct cdrom_msf0 *);
267 static unsigned int msf2log(const struct cdrom_msf0 *);
268 static unsigned int uint2bcd(unsigned int);
269 static unsigned int bcd2uint(unsigned char);
270 static unsigned port(int *);
271 static int irq(int *);
272 static void mcdx_delay(struct s_drive_stuff *, long jifs);
273 static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
274                          int nr_sectors);
275 static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
276                      int nr_sectors);
277
278 static int mcdx_config(struct s_drive_stuff *, int);
279 static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
280                                int);
281 static int mcdx_stop(struct s_drive_stuff *, int);
282 static int mcdx_hold(struct s_drive_stuff *, int);
283 static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
284 static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
285 static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
286 static int mcdx_requestsubqcode(struct s_drive_stuff *,
287                                 struct s_subqcode *, int);
288 static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
289                                      struct s_multi *, int);
290 static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
291                                int);
292 static int mcdx_getstatus(struct s_drive_stuff *, int);
293 static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
294 static int mcdx_talk(struct s_drive_stuff *,
295                      const unsigned char *cmd, size_t,
296                      void *buffer, size_t size, unsigned int timeout, int);
297 static int mcdx_readtoc(struct s_drive_stuff *);
298 static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
299 static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
300 static int mcdx_setattentuator(struct s_drive_stuff *,
301                                struct cdrom_volctrl *, int);
302
303 /* static variables ************************************************/
304
305 static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
306 static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
307 static DEFINE_SPINLOCK(mcdx_lock);
308 static struct request_queue *mcdx_queue;
309
310 /* You can only set the first two pairs, from old MODULE_PARM code.  */
311 static int mcdx_set(const char *val, struct kernel_param *kp)
312 {
313         get_options((char *)val, 4, (int *)mcdx_drive_map);
314         return 0;
315 }
316 module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
317
318 static struct cdrom_device_ops mcdx_dops = {
319         .open           = mcdx_open,
320         .release        = mcdx_close,
321         .media_changed  = mcdx_media_changed,
322         .tray_move      = mcdx_tray_move,
323         .lock_door      = mcdx_lockdoor,
324         .audio_ioctl    = mcdx_audio_ioctl,
325         .capability     = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
326                           CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
327 };
328
329 /* KERNEL INTERFACE FUNCTIONS **************************************/
330
331
332 static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
333                             unsigned int cmd, void *arg)
334 {
335         struct s_drive_stuff *stuffp = cdi->handle;
336
337         if (!stuffp->present)
338                 return -ENXIO;
339
340         if (stuffp->xxx) {
341                 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
342                         stuffp->lastsector = -1;
343                 } else {
344                         stuffp->lastsector = (CD_FRAMESIZE / 512)
345                             * msf2log(&stuffp->di.msf_leadout) - 1;
346                 }
347
348                 if (stuffp->toc) {
349                         kfree(stuffp->toc);
350                         stuffp->toc = NULL;
351                         if (-1 == mcdx_readtoc(stuffp))
352                                 return -1;
353                 }
354
355                 stuffp->xxx = 0;
356         }
357
358         switch (cmd) {
359         case CDROMSTART:{
360                         xtrace(IOCTL, "ioctl() START\n");
361                         /* Spin up the drive.  Don't think we can do this.
362                            * For now, ignore it.
363                          */
364                         return 0;
365                 }
366
367         case CDROMSTOP:{
368                         xtrace(IOCTL, "ioctl() STOP\n");
369                         stuffp->audiostatus = CDROM_AUDIO_INVALID;
370                         if (-1 == mcdx_stop(stuffp, 1))
371                                 return -EIO;
372                         return 0;
373                 }
374
375         case CDROMPLAYTRKIND:{
376                         struct cdrom_ti *ti = (struct cdrom_ti *) arg;
377
378                         xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
379                         if ((ti->cdti_trk0 < stuffp->di.n_first)
380                             || (ti->cdti_trk0 > stuffp->di.n_last)
381                             || (ti->cdti_trk1 < stuffp->di.n_first))
382                                 return -EINVAL;
383                         if (ti->cdti_trk1 > stuffp->di.n_last)
384                                 ti->cdti_trk1 = stuffp->di.n_last;
385                         xtrace(PLAYTRK, "ioctl() track %d to %d\n",
386                                ti->cdti_trk0, ti->cdti_trk1);
387                         return mcdx_playtrk(stuffp, ti);
388                 }
389
390         case CDROMPLAYMSF:{
391                         struct cdrom_msf *msf = (struct cdrom_msf *) arg;
392
393                         xtrace(IOCTL, "ioctl() PLAYMSF\n");
394
395                         if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
396                             && (-1 == mcdx_hold(stuffp, 1)))
397                                 return -EIO;
398
399                         msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
400                         msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
401                         msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
402
403                         msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
404                         msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
405                         msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
406
407                         stuffp->stop.dt.minute = msf->cdmsf_min1;
408                         stuffp->stop.dt.second = msf->cdmsf_sec1;
409                         stuffp->stop.dt.frame = msf->cdmsf_frame1;
410
411                         return mcdx_playmsf(stuffp, msf);
412                 }
413
414         case CDROMRESUME:{
415                         xtrace(IOCTL, "ioctl() RESUME\n");
416                         return mcdx_playtrk(stuffp, NULL);
417                 }
418
419         case CDROMREADTOCENTRY:{
420                         struct cdrom_tocentry *entry =
421                             (struct cdrom_tocentry *) arg;
422                         struct s_subqcode *tp = NULL;
423                         xtrace(IOCTL, "ioctl() READTOCENTRY\n");
424
425                         if (-1 == mcdx_readtoc(stuffp))
426                                 return -1;
427                         if (entry->cdte_track == CDROM_LEADOUT)
428                                 tp = &stuffp->toc[stuffp->di.n_last -
429                                                   stuffp->di.n_first + 1];
430                         else if (entry->cdte_track > stuffp->di.n_last
431                                  || entry->cdte_track < stuffp->di.n_first)
432                                 return -EINVAL;
433                         else
434                                 tp = &stuffp->toc[entry->cdte_track -
435                                                   stuffp->di.n_first];
436
437                         if (NULL == tp)
438                                 return -EIO;
439                         entry->cdte_adr = tp->control;
440                         entry->cdte_ctrl = tp->control >> 4;
441                         /* Always return stuff in MSF, and let the Uniform cdrom driver
442                            worry about what the user actually wants */
443                         entry->cdte_addr.msf.minute =
444                             bcd2uint(tp->dt.minute);
445                         entry->cdte_addr.msf.second =
446                             bcd2uint(tp->dt.second);
447                         entry->cdte_addr.msf.frame =
448                             bcd2uint(tp->dt.frame);
449                         return 0;
450                 }
451
452         case CDROMSUBCHNL:{
453                         struct cdrom_subchnl *sub =
454                             (struct cdrom_subchnl *) arg;
455                         struct s_subqcode q;
456
457                         xtrace(IOCTL, "ioctl() SUBCHNL\n");
458
459                         if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
460                                 return -EIO;
461
462                         xtrace(SUBCHNL, "audiostatus: %x\n",
463                                stuffp->audiostatus);
464                         sub->cdsc_audiostatus = stuffp->audiostatus;
465                         sub->cdsc_adr = q.control;
466                         sub->cdsc_ctrl = q.control >> 4;
467                         sub->cdsc_trk = bcd2uint(q.tno);
468                         sub->cdsc_ind = bcd2uint(q.index);
469
470                         xtrace(SUBCHNL, "trk %d, ind %d\n",
471                                sub->cdsc_trk, sub->cdsc_ind);
472                         /* Always return stuff in MSF, and let the Uniform cdrom driver
473                            worry about what the user actually wants */
474                         sub->cdsc_absaddr.msf.minute =
475                             bcd2uint(q.dt.minute);
476                         sub->cdsc_absaddr.msf.second =
477                             bcd2uint(q.dt.second);
478                         sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
479                         sub->cdsc_reladdr.msf.minute =
480                             bcd2uint(q.tt.minute);
481                         sub->cdsc_reladdr.msf.second =
482                             bcd2uint(q.tt.second);
483                         sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
484                         xtrace(SUBCHNL,
485                                "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
486                                sub->cdsc_absaddr.msf.minute,
487                                sub->cdsc_absaddr.msf.second,
488                                sub->cdsc_absaddr.msf.frame,
489                                sub->cdsc_reladdr.msf.minute,
490                                sub->cdsc_reladdr.msf.second,
491                                sub->cdsc_reladdr.msf.frame);
492
493                         return 0;
494                 }
495
496         case CDROMREADTOCHDR:{
497                         struct cdrom_tochdr *toc =
498                             (struct cdrom_tochdr *) arg;
499
500                         xtrace(IOCTL, "ioctl() READTOCHDR\n");
501                         toc->cdth_trk0 = stuffp->di.n_first;
502                         toc->cdth_trk1 = stuffp->di.n_last;
503                         xtrace(TOCHDR,
504                                "ioctl() track0 = %d, track1 = %d\n",
505                                stuffp->di.n_first, stuffp->di.n_last);
506                         return 0;
507                 }
508
509         case CDROMPAUSE:{
510                         xtrace(IOCTL, "ioctl() PAUSE\n");
511                         if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
512                                 return -EINVAL;
513                         if (-1 == mcdx_stop(stuffp, 1))
514                                 return -EIO;
515                         stuffp->audiostatus = CDROM_AUDIO_PAUSED;
516                         if (-1 ==
517                             mcdx_requestsubqcode(stuffp, &stuffp->start,
518                                                  1))
519                                 return -EIO;
520                         return 0;
521                 }
522
523         case CDROMMULTISESSION:{
524                         struct cdrom_multisession *ms =
525                             (struct cdrom_multisession *) arg;
526                         xtrace(IOCTL, "ioctl() MULTISESSION\n");
527                         /* Always return stuff in LBA, and let the Uniform cdrom driver
528                            worry about what the user actually wants */
529                         ms->addr.lba = msf2log(&stuffp->multi.msf_last);
530                         ms->xa_flag = !!stuffp->multi.multi;
531                         xtrace(MS,
532                                "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
533                                ms->xa_flag, ms->addr.lba,
534                                stuffp->multi.msf_last.minute,
535                                stuffp->multi.msf_last.second,
536                                stuffp->multi.msf_last.frame);
537
538                         return 0;
539                 }
540
541         case CDROMEJECT:{
542                         xtrace(IOCTL, "ioctl() EJECT\n");
543                         if (stuffp->users > 1)
544                                 return -EBUSY;
545                         return (mcdx_tray_move(cdi, 1));
546                 }
547
548         case CDROMCLOSETRAY:{
549                         xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
550                         return (mcdx_tray_move(cdi, 0));
551                 }
552
553         case CDROMVOLCTRL:{
554                         struct cdrom_volctrl *volctrl =
555                             (struct cdrom_volctrl *) arg;
556                         xtrace(IOCTL, "ioctl() VOLCTRL\n");
557
558 #if 0                           /* not tested! */
559                         /* adjust for the weirdness of workman (md) */
560                         /* can't test it (hs) */
561                         volctrl.channel2 = volctrl.channel1;
562                         volctrl.channel1 = volctrl.channel3 = 0x00;
563 #endif
564                         return mcdx_setattentuator(stuffp, volctrl, 2);
565                 }
566
567         default:
568                 return -EINVAL;
569         }
570 }
571
572 void do_mcdx_request(request_queue_t * q)
573 {
574         struct s_drive_stuff *stuffp;
575         struct request *req;
576
577       again:
578
579         req = elv_next_request(q);
580         if (!req)
581                 return;
582
583         stuffp = req->rq_disk->private_data;
584
585         if (!stuffp->present) {
586                 xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
587                 xtrace(REQUEST, "end_request(0): bad device\n");
588                 end_request(req, 0);
589                 return;
590         }
591
592         if (stuffp->audio) {
593                 xwarn("do_request() attempt to read from audio cd\n");
594                 xtrace(REQUEST, "end_request(0): read from audio\n");
595                 end_request(req, 0);
596                 return;
597         }
598
599         xtrace(REQUEST, "do_request() (%lu + %lu)\n",
600                req->sector, req->nr_sectors);
601
602         if (req->cmd != READ) {
603                 xwarn("do_request(): non-read command to cd!!\n");
604                 xtrace(REQUEST, "end_request(0): write\n");
605                 end_request(req, 0);
606                 return;
607         }
608         else {
609                 stuffp->status = 0;
610                 while (req->nr_sectors) {
611                         int i;
612
613                         i = mcdx_transfer(stuffp,
614                                           req->buffer,
615                                           req->sector,
616                                           req->nr_sectors);
617
618                         if (i == -1) {
619                                 end_request(req, 0);
620                                 goto again;
621                         }
622                         req->sector += i;
623                         req->nr_sectors -= i;
624                         req->buffer += (i * 512);
625                 }
626                 end_request(req, 1);
627                 goto again;
628
629                 xtrace(REQUEST, "end_request(1)\n");
630                 end_request(req, 1);
631         }
632
633         goto again;
634 }
635
636 static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
637 {
638         struct s_drive_stuff *stuffp;
639         xtrace(OPENCLOSE, "open()\n");
640         stuffp = cdi->handle;
641         if (!stuffp->present)
642                 return -ENXIO;
643
644         /* Make the modules looking used ... (thanx bjorn).
645          * But we shouldn't forget to decrement the module counter
646          * on error return */
647
648         /* this is only done to test if the drive talks with us */
649         if (-1 == mcdx_getstatus(stuffp, 1))
650                 return -EIO;
651
652         if (stuffp->xxx) {
653
654                 xtrace(OPENCLOSE, "open() media changed\n");
655                 stuffp->audiostatus = CDROM_AUDIO_INVALID;
656                 stuffp->readcmd = 0;
657                 xtrace(OPENCLOSE, "open() Request multisession info\n");
658                 if (-1 ==
659                     mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
660                         xinfo("No multidiskinfo\n");
661         } else {
662                 /* multisession ? */
663                 if (!stuffp->multi.multi)
664                         stuffp->multi.msf_last.second = 2;
665
666                 xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
667                        stuffp->multi.multi,
668                        stuffp->multi.msf_last.minute,
669                        stuffp->multi.msf_last.second,
670                        stuffp->multi.msf_last.frame);
671
672                 {;
673                 }               /* got multisession information */
674                 /* request the disks table of contents (aka diskinfo) */
675                 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
676
677                         stuffp->lastsector = -1;
678
679                 } else {
680
681                         stuffp->lastsector = (CD_FRAMESIZE / 512)
682                             * msf2log(&stuffp->di.msf_leadout) - 1;
683
684                         xtrace(OPENCLOSE,
685                                "open() start %d (%02x:%02x.%02x) %d\n",
686                                stuffp->di.n_first,
687                                stuffp->di.msf_first.minute,
688                                stuffp->di.msf_first.second,
689                                stuffp->di.msf_first.frame,
690                                msf2log(&stuffp->di.msf_first));
691                         xtrace(OPENCLOSE,
692                                "open() last %d (%02x:%02x.%02x) %d\n",
693                                stuffp->di.n_last,
694                                stuffp->di.msf_leadout.minute,
695                                stuffp->di.msf_leadout.second,
696                                stuffp->di.msf_leadout.frame,
697                                msf2log(&stuffp->di.msf_leadout));
698                 }
699
700                 if (stuffp->toc) {
701                         xtrace(MALLOC, "open() free old toc @ %p\n",
702                                stuffp->toc);
703                         kfree(stuffp->toc);
704
705                         stuffp->toc = NULL;
706                 }
707
708                 xtrace(OPENCLOSE, "open() init irq generation\n");
709                 if (-1 == mcdx_config(stuffp, 1))
710                         return -EIO;
711 #if FALLBACK
712                 /* Set the read speed */
713                 xwarn("AAA %x AAA\n", stuffp->readcmd);
714                 if (stuffp->readerrs)
715                         stuffp->readcmd = READ1X;
716                 else
717                         stuffp->readcmd =
718                             stuffp->present | SINGLE ? READ1X : READ2X;
719                 xwarn("XXX %x XXX\n", stuffp->readcmd);
720 #else
721                 stuffp->readcmd =
722                     stuffp->present | SINGLE ? READ1X : READ2X;
723 #endif
724
725                 /* try to get the first sector, iff any ... */
726                 if (stuffp->lastsector >= 0) {
727                         char buf[512];
728                         int ans;
729                         int tries;
730
731                         stuffp->xa = 0;
732                         stuffp->audio = 0;
733
734                         for (tries = 6; tries; tries--) {
735
736                                 stuffp->introk = 1;
737
738                                 xtrace(OPENCLOSE, "open() try as %s\n",
739                                        stuffp->xa ? "XA" : "normal");
740                                 /* set data mode */
741                                 if (-1 == (ans = mcdx_setdatamode(stuffp,
742                                                                   stuffp->
743                                                                   xa ?
744                                                                   MODE2 :
745                                                                   MODE1,
746                                                                   1))) {
747                                         /* return -EIO; */
748                                         stuffp->xa = 0;
749                                         break;
750                                 }
751
752                                 if ((stuffp->audio = e_audio(ans)))
753                                         break;
754
755                                 while (0 ==
756                                        (ans =
757                                         mcdx_transfer(stuffp, buf, 0, 1)));
758
759                                 if (ans == 1)
760                                         break;
761                                 stuffp->xa = !stuffp->xa;
762                         }
763                 }
764                 /* xa disks will be read in raw mode, others not */
765                 if (-1 == mcdx_setdrivemode(stuffp,
766                                             stuffp->xa ? RAW : COOKED,
767                                             1))
768                         return -EIO;
769                 if (stuffp->audio) {
770                         xinfo("open() audio disk found\n");
771                 } else if (stuffp->lastsector >= 0) {
772                         xinfo("open() %s%s disk found\n",
773                               stuffp->xa ? "XA / " : "",
774                               stuffp->multi.
775                               multi ? "Multi Session" : "Single Session");
776                 }
777         }
778         stuffp->xxx = 0;
779         stuffp->users++;
780         return 0;
781 }
782
783 static void mcdx_close(struct cdrom_device_info *cdi)
784 {
785         struct s_drive_stuff *stuffp;
786
787         xtrace(OPENCLOSE, "close()\n");
788
789         stuffp = cdi->handle;
790
791         --stuffp->users;
792 }
793
794 static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
795 /*      Return: 1 if media changed since last call to this function
796                         0 otherwise */
797 {
798         struct s_drive_stuff *stuffp;
799
800         xinfo("mcdx_media_changed called for device %s\n", cdi->name);
801
802         stuffp = cdi->handle;
803         mcdx_getstatus(stuffp, 1);
804
805         if (stuffp->yyy == 0)
806                 return 0;
807
808         stuffp->yyy = 0;
809         return 1;
810 }
811
812 #ifndef MODULE
813 static int __init mcdx_setup(char *str)
814 {
815         int pi[4];
816         (void) get_options(str, ARRAY_SIZE(pi), pi);
817
818         if (pi[0] > 0)
819                 mcdx_drive_map[0][0] = pi[1];
820         if (pi[0] > 1)
821                 mcdx_drive_map[0][1] = pi[2];
822         return 1;
823 }
824
825 __setup("mcdx=", mcdx_setup);
826
827 #endif
828
829 /* DIRTY PART ******************************************************/
830
831 static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
832 /* This routine is used for sleeping.
833  * A jifs value <0 means NO sleeping,
834  *              =0 means minimal sleeping (let the kernel
835  *                 run for other processes)
836  *              >0 means at least sleep for that amount.
837  *      May be we could use a simple count loop w/ jumps to itself, but
838  *      I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
839 {
840         if (jifs < 0)
841                 return;
842
843         xtrace(SLEEP, "*** delay: sleepq\n");
844         interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
845         xtrace(SLEEP, "delay awoken\n");
846         if (signal_pending(current)) {
847                 xtrace(SLEEP, "got signal\n");
848         }
849 }
850
851 static irqreturn_t mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
852 {
853         struct s_drive_stuff *stuffp = dev_id;
854         unsigned char b;
855
856         if (stuffp == NULL) {
857                 xwarn("mcdx: no device for intr %d\n", irq);
858                 return IRQ_NONE;
859         }
860 #ifdef AK2
861         if (!stuffp->busy && stuffp->pending)
862                 stuffp->int_err = 1;
863
864 #endif                          /* AK2 */
865         /* get the interrupt status */
866         b = inb(stuffp->rreg_status);
867         stuffp->introk = ~b & MCDX_RBIT_DTEN;
868
869         /* NOTE: We only should get interrupts if the data we
870          * requested are ready to transfer.
871          * But the drive seems to generate ``asynchronous'' interrupts
872          * on several error conditions too.  (Despite the err int enable
873          * setting during initialisation) */
874
875         /* if not ok, read the next byte as the drives status */
876         if (!stuffp->introk) {
877                 xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
878                 if (~b & MCDX_RBIT_STEN) {
879                         xinfo("intr() irq %d    status 0x%02x\n",
880                               irq, inb(stuffp->rreg_data));
881                 } else {
882                         xinfo("intr() irq %d ambiguous hw status\n", irq);
883                 }
884         } else {
885                 xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
886         }
887
888         stuffp->busy = 0;
889         wake_up_interruptible(&stuffp->busyq);
890         return IRQ_HANDLED;
891 }
892
893
894 static int mcdx_talk(struct s_drive_stuff *stuffp,
895           const unsigned char *cmd, size_t cmdlen,
896           void *buffer, size_t size, unsigned int timeout, int tries)
897 /* Send a command to the drive, wait for the result.
898  * returns -1 on timeout, drive status otherwise
899  * If buffer is not zero, the result (length size) is stored there.
900  * If buffer is zero the size should be the number of bytes to read
901  * from the drive.  These bytes are discarded.
902  */
903 {
904         int st;
905         char c;
906         int discard;
907
908         /* Somebody wants the data read? */
909         if ((discard = (buffer == NULL)))
910                 buffer = &c;
911
912         while (stuffp->lock) {
913                 xtrace(SLEEP, "*** talk: lockq\n");
914                 interruptible_sleep_on(&stuffp->lockq);
915                 xtrace(SLEEP, "talk: awoken\n");
916         }
917
918         stuffp->lock = 1;
919
920         /* An operation other then reading data destroys the
921            * data already requested and remembered in stuffp->request, ... */
922         stuffp->valid = 0;
923
924 #if MCDX_DEBUG & TALK
925         {
926                 unsigned char i;
927                 xtrace(TALK,
928                        "talk() %d / %d tries, res.size %d, command 0x%02x",
929                        tries, timeout, size, (unsigned char) cmd[0]);
930                 for (i = 1; i < cmdlen; i++)
931                         xtrace(TALK, " 0x%02x", cmd[i]);
932                 xtrace(TALK, "\n");
933         }
934 #endif
935
936         /*  give up if all tries are done (bad) or if the status
937          *  st != -1 (good) */
938         for (st = -1; st == -1 && tries; tries--) {
939
940                 char *bp = (char *) buffer;
941                 size_t sz = size;
942
943                 outsb(stuffp->wreg_data, cmd, cmdlen);
944                 xtrace(TALK, "talk() command sent\n");
945
946                 /* get the status byte */
947                 if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
948                         xinfo("talk() %02x timed out (status), %d tr%s left\n",
949                              cmd[0], tries - 1, tries == 2 ? "y" : "ies");
950                         continue;
951                 }
952                 st = *bp;
953                 sz--;
954                 if (!discard)
955                         bp++;
956
957                 xtrace(TALK, "talk() got status 0x%02x\n", st);
958
959                 /* command error? */
960                 if (e_cmderr(st)) {
961                         xwarn("command error cmd = %02x %s \n",
962                               cmd[0], cmdlen > 1 ? "..." : "");
963                         st = -1;
964                         continue;
965                 }
966
967                 /* audio status? */
968                 if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
969                         stuffp->audiostatus =
970                             e_audiobusy(st) ? CDROM_AUDIO_PLAY :
971                             CDROM_AUDIO_NO_STATUS;
972                 else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
973                          && e_audiobusy(st) == 0)
974                         stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
975
976                 /* media change? */
977                 if (e_changed(st)) {
978                         xinfo("talk() media changed\n");
979                         stuffp->xxx = stuffp->yyy = 1;
980                 }
981
982                 /* now actually get the data */
983                 while (sz--) {
984                         if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
985                                 xinfo("talk() %02x timed out (data), %d tr%s left\n",
986                                      cmd[0], tries - 1,
987                                      tries == 2 ? "y" : "ies");
988                                 st = -1;
989                                 break;
990                         }
991                         if (!discard)
992                                 bp++;
993                         xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
994                 }
995         }
996
997 #if !MCDX_QUIET
998         if (!tries && st == -1)
999                 xinfo("talk() giving up\n");
1000 #endif
1001
1002         stuffp->lock = 0;
1003         wake_up_interruptible(&stuffp->lockq);
1004
1005         xtrace(TALK, "talk() done with 0x%02x\n", st);
1006         return st;
1007 }
1008
1009 /* MODULE STUFF ***********************************************************/
1010
1011 int __mcdx_init(void)
1012 {
1013         int i;
1014         int drives = 0;
1015
1016         mcdx_init();
1017         for (i = 0; i < MCDX_NDRIVES; i++) {
1018                 if (mcdx_stuffp[i]) {
1019                         xtrace(INIT, "init_module() drive %d stuff @ %p\n",
1020                                i, mcdx_stuffp[i]);
1021                         drives++;
1022                 }
1023         }
1024
1025         if (!drives)
1026                 return -EIO;
1027
1028         return 0;
1029 }
1030
1031 void __exit mcdx_exit(void)
1032 {
1033         int i;
1034
1035         xinfo("cleanup_module called\n");
1036
1037         for (i = 0; i < MCDX_NDRIVES; i++) {
1038                 struct s_drive_stuff *stuffp = mcdx_stuffp[i];
1039                 if (!stuffp)
1040                         continue;
1041                 del_gendisk(stuffp->disk);
1042                 if (unregister_cdrom(&stuffp->info)) {
1043                         printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
1044                         continue;
1045                 }
1046                 put_disk(stuffp->disk);
1047                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1048                 free_irq(stuffp->irq, NULL);
1049                 if (stuffp->toc) {
1050                         xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
1051                                stuffp->toc);
1052                         kfree(stuffp->toc);
1053                 }
1054                 xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
1055                        stuffp);
1056                 mcdx_stuffp[i] = NULL;
1057                 kfree(stuffp);
1058         }
1059
1060         if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
1061                 xwarn("cleanup() unregister_blkdev() failed\n");
1062         }
1063         blk_cleanup_queue(mcdx_queue);
1064 #if !MCDX_QUIET
1065         else
1066         xinfo("cleanup() succeeded\n");
1067 #endif
1068 }
1069
1070 #ifdef MODULE
1071 module_init(__mcdx_init);
1072 #endif
1073 module_exit(mcdx_exit);
1074
1075
1076 /* Support functions ************************************************/
1077
1078 int __init mcdx_init_drive(int drive)
1079 {
1080         struct s_version version;
1081         struct gendisk *disk;
1082         struct s_drive_stuff *stuffp;
1083         int size = sizeof(*stuffp);
1084         char msg[80];
1085
1086         xtrace(INIT, "init() try drive %d\n", drive);
1087
1088         xtrace(INIT, "kmalloc space for stuffpt's\n");
1089         xtrace(MALLOC, "init() malloc %d bytes\n", size);
1090         if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
1091                 xwarn("init() malloc failed\n");
1092                 return 1;
1093         }
1094
1095         disk = alloc_disk(1);
1096         if (!disk) {
1097                 xwarn("init() malloc failed\n");
1098                 kfree(stuffp);
1099                 return 1;
1100         }
1101
1102         xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
1103                sizeof(*stuffp), stuffp);
1104
1105         /* set default values */
1106         memset(stuffp, 0, sizeof(*stuffp));
1107
1108         stuffp->present = 0;    /* this should be 0 already */
1109         stuffp->toc = NULL;     /* this should be NULL already */
1110
1111         /* setup our irq and i/o addresses */
1112         stuffp->irq = irq(mcdx_drive_map[drive]);
1113         stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
1114         stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
1115         stuffp->wreg_hcon = stuffp->wreg_reset + 1;
1116         stuffp->wreg_chn = stuffp->wreg_hcon + 1;
1117
1118         init_waitqueue_head(&stuffp->busyq);
1119         init_waitqueue_head(&stuffp->lockq);
1120         init_waitqueue_head(&stuffp->sleepq);
1121
1122         /* check if i/o addresses are available */
1123         if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
1124                 xwarn("0x%03x,%d: Init failed. "
1125                       "I/O ports (0x%03x..0x%03x) already in use.\n",
1126                       stuffp->wreg_data, stuffp->irq,
1127                       stuffp->wreg_data,
1128                       stuffp->wreg_data + MCDX_IO_SIZE - 1);
1129                 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1130                 kfree(stuffp);
1131                 put_disk(disk);
1132                 xtrace(INIT, "init() continue at next drive\n");
1133                 return 0;       /* next drive */
1134         }
1135
1136         xtrace(INIT, "init() i/o port is available at 0x%03x\n"
1137                stuffp->wreg_data);
1138         xtrace(INIT, "init() hardware reset\n");
1139         mcdx_reset(stuffp, HARD, 1);
1140
1141         xtrace(INIT, "init() get version\n");
1142         if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
1143                 /* failed, next drive */
1144                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1145                 xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
1146                       MCDX, stuffp->wreg_data, stuffp->irq);
1147                 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1148                 kfree(stuffp);
1149                 put_disk(disk);
1150                 xtrace(INIT, "init() continue at next drive\n");
1151                 return 0;
1152         }
1153
1154         switch (version.code) {
1155         case 'D':
1156                 stuffp->readcmd = READ2X;
1157                 stuffp->present = DOUBLE | DOOR | MULTI;
1158                 break;
1159         case 'F':
1160                 stuffp->readcmd = READ1X;
1161                 stuffp->present = SINGLE | DOOR | MULTI;
1162                 break;
1163         case 'M':
1164                 stuffp->readcmd = READ1X;
1165                 stuffp->present = SINGLE;
1166                 break;
1167         default:
1168                 stuffp->present = 0;
1169                 break;
1170         }
1171
1172         stuffp->playcmd = READ1X;
1173
1174         if (!stuffp->present) {
1175                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1176                 xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
1177                       MCDX, stuffp->wreg_data, stuffp->irq);
1178                 kfree(stuffp);
1179                 put_disk(disk);
1180                 return 0;       /* next drive */
1181         }
1182
1183         xtrace(INIT, "init() register blkdev\n");
1184         if (register_blkdev(MAJOR_NR, "mcdx")) {
1185                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1186                 kfree(stuffp);
1187                 put_disk(disk);
1188                 return 1;
1189         }
1190
1191         mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
1192         if (!mcdx_queue) {
1193                 unregister_blkdev(MAJOR_NR, "mcdx");
1194                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1195                 kfree(stuffp);
1196                 put_disk(disk);
1197                 return 1;
1198         }
1199
1200         xtrace(INIT, "init() subscribe irq and i/o\n");
1201         if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", stuffp)) {
1202                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1203                 xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
1204                       MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
1205                 stuffp->irq = 0;
1206                 blk_cleanup_queue(mcdx_queue);
1207                 kfree(stuffp);
1208                 put_disk(disk);
1209                 return 0;
1210         }
1211
1212         xtrace(INIT, "init() get garbage\n");
1213         {
1214                 int i;
1215                 mcdx_delay(stuffp, HZ / 2);
1216                 for (i = 100; i; i--)
1217                         (void) inb(stuffp->rreg_status);
1218         }
1219
1220
1221 #if WE_KNOW_WHY
1222         /* irq 11 -> channel register */
1223         outb(0x50, stuffp->wreg_chn);
1224 #endif
1225
1226         xtrace(INIT, "init() set non dma but irq mode\n");
1227         mcdx_config(stuffp, 1);
1228
1229         stuffp->info.ops = &mcdx_dops;
1230         stuffp->info.speed = 2;
1231         stuffp->info.capacity = 1;
1232         stuffp->info.handle = stuffp;
1233         sprintf(stuffp->info.name, "mcdx%d", drive);
1234         disk->major = MAJOR_NR;
1235         disk->first_minor = drive;
1236         strcpy(disk->disk_name, stuffp->info.name);
1237         disk->fops = &mcdx_bdops;
1238         disk->flags = GENHD_FL_CD;
1239         stuffp->disk = disk;
1240
1241         sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
1242                 " (Firmware version %c %x)\n",
1243                 stuffp->wreg_data, stuffp->irq, version.code, version.ver);
1244         mcdx_stuffp[drive] = stuffp;
1245         xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
1246         if (register_cdrom(&stuffp->info) != 0) {
1247                 printk("Cannot register Mitsumi CD-ROM!\n");
1248                 free_irq(stuffp->irq, NULL);
1249                 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1250                 kfree(stuffp);
1251                 put_disk(disk);
1252                 if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
1253                         xwarn("cleanup() unregister_blkdev() failed\n");
1254                 blk_cleanup_queue(mcdx_queue);
1255                 return 2;
1256         }
1257         disk->private_data = stuffp;
1258         disk->queue = mcdx_queue;
1259         add_disk(disk);
1260         printk(msg);
1261         return 0;
1262 }
1263
1264 int __init mcdx_init(void)
1265 {
1266         int drive;
1267         xwarn("Version 2.14(hs) \n");
1268
1269         xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
1270
1271         /* zero the pointer array */
1272         for (drive = 0; drive < MCDX_NDRIVES; drive++)
1273                 mcdx_stuffp[drive] = NULL;
1274
1275         /* do the initialisation */
1276         for (drive = 0; drive < MCDX_NDRIVES; drive++) {
1277                 switch (mcdx_init_drive(drive)) {
1278                 case 2:
1279                         return -EIO;
1280                 case 1:
1281                         break;
1282                 }
1283         }
1284         return 0;
1285 }
1286
1287 static int mcdx_transfer(struct s_drive_stuff *stuffp,
1288               char *p, int sector, int nr_sectors)
1289 /*      This seems to do the actually transfer.  But it does more.  It
1290         keeps track of errors occurred and will (if possible) fall back
1291         to single speed on error.
1292         Return: -1 on timeout or other error
1293                         else status byte (as in stuff->st) */
1294 {
1295         int ans;
1296
1297         ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
1298         return ans;
1299 #if FALLBACK
1300         if (-1 == ans)
1301                 stuffp->readerrs++;
1302         else
1303                 return ans;
1304
1305         if (stuffp->readerrs && stuffp->readcmd == READ1X) {
1306                 xwarn("XXX Already reading 1x -- no chance\n");
1307                 return -1;
1308         }
1309
1310         xwarn("XXX Fallback to 1x\n");
1311
1312         stuffp->readcmd = READ1X;
1313         return mcdx_transfer(stuffp, p, sector, nr_sectors);
1314 #endif
1315
1316 }
1317
1318
1319 static int mcdx_xfer(struct s_drive_stuff *stuffp,
1320                      char *p, int sector, int nr_sectors)
1321 /*      This does actually the transfer from the drive.
1322         Return: -1 on timeout or other error
1323                         else status byte (as in stuff->st) */
1324 {
1325         int border;
1326         int done = 0;
1327         long timeout;
1328
1329         if (stuffp->audio) {
1330                 xwarn("Attempt to read from audio CD.\n");
1331                 return -1;
1332         }
1333
1334         if (!stuffp->readcmd) {
1335                 xinfo("Can't transfer from missing disk.\n");
1336                 return -1;
1337         }
1338
1339         while (stuffp->lock) {
1340                 interruptible_sleep_on(&stuffp->lockq);
1341         }
1342
1343         if (stuffp->valid && (sector >= stuffp->pending)
1344             && (sector < stuffp->low_border)) {
1345
1346                 /* All (or at least a part of the sectors requested) seems
1347                    * to be already requested, so we don't need to bother the
1348                    * drive with new requests ...
1349                    * Wait for the drive become idle, but first
1350                    * check for possible occurred errors --- the drive
1351                    * seems to report them asynchronously */
1352
1353
1354                 border = stuffp->high_border < (border =
1355                                                 sector + nr_sectors)
1356                     ? stuffp->high_border : border;
1357
1358                 stuffp->lock = current->pid;
1359
1360                 do {
1361
1362                         while (stuffp->busy) {
1363
1364                                 timeout =
1365                                     interruptible_sleep_on_timeout
1366                                     (&stuffp->busyq, 5 * HZ);
1367
1368                                 if (!stuffp->introk) {
1369                                         xtrace(XFER,
1370                                                "error via interrupt\n");
1371                                 } else if (!timeout) {
1372                                         xtrace(XFER, "timeout\n");
1373                                 } else if (signal_pending(current)) {
1374                                         xtrace(XFER, "signal\n");
1375                                 } else
1376                                         continue;
1377
1378                                 stuffp->lock = 0;
1379                                 stuffp->busy = 0;
1380                                 stuffp->valid = 0;
1381
1382                                 wake_up_interruptible(&stuffp->lockq);
1383                                 xtrace(XFER, "transfer() done (-1)\n");
1384                                 return -1;
1385                         }
1386
1387                         /* check if we need to set the busy flag (as we
1388                          * expect an interrupt */
1389                         stuffp->busy = (3 == (stuffp->pending & 3));
1390
1391                         /* Test if it's the first sector of a block,
1392                          * there we have to skip some bytes as we read raw data */
1393                         if (stuffp->xa && (0 == (stuffp->pending & 3))) {
1394                                 const int HEAD =
1395                                     CD_FRAMESIZE_RAW - CD_XA_TAIL -
1396                                     CD_FRAMESIZE;
1397                                 insb(stuffp->rreg_data, p, HEAD);
1398                         }
1399
1400                         /* now actually read the data */
1401                         insb(stuffp->rreg_data, p, 512);
1402
1403                         /* test if it's the last sector of a block,
1404                          * if so, we have to handle XA special */
1405                         if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
1406                                 char dummy[CD_XA_TAIL];
1407                                 insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
1408                         }
1409
1410                         if (stuffp->pending == sector) {
1411                                 p += 512;
1412                                 done++;
1413                                 sector++;
1414                         }
1415                 } while (++(stuffp->pending) < border);
1416
1417                 stuffp->lock = 0;
1418                 wake_up_interruptible(&stuffp->lockq);
1419
1420         } else {
1421
1422                 /* The requested sector(s) is/are out of the
1423                  * already requested range, so we have to bother the drive
1424                  * with a new request. */
1425
1426                 static unsigned char cmd[] = {
1427                         0,
1428                         0, 0, 0,
1429                         0, 0, 0
1430                 };
1431
1432                 cmd[0] = stuffp->readcmd;
1433
1434                 /* The numbers held in ->pending, ..., should be valid */
1435                 stuffp->valid = 1;
1436                 stuffp->pending = sector & ~3;
1437
1438                 /* do some sanity checks */
1439                 if (stuffp->pending > stuffp->lastsector) {
1440                         xwarn
1441                             ("transfer() sector %d from nirvana requested.\n",
1442                              stuffp->pending);
1443                         stuffp->status = MCDX_ST_EOM;
1444                         stuffp->valid = 0;
1445                         xtrace(XFER, "transfer() done (-1)\n");
1446                         return -1;
1447                 }
1448
1449                 if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
1450                     > stuffp->lastsector + 1) {
1451                         xtrace(XFER, "cut low_border\n");
1452                         stuffp->low_border = stuffp->lastsector + 1;
1453                 }
1454                 if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
1455                     > stuffp->lastsector + 1) {
1456                         xtrace(XFER, "cut high_border\n");
1457                         stuffp->high_border = stuffp->lastsector + 1;
1458                 }
1459
1460                 {               /* Convert the sector to be requested to MSF format */
1461                         struct cdrom_msf0 pending;
1462                         log2msf(stuffp->pending / 4, &pending);
1463                         cmd[1] = pending.minute;
1464                         cmd[2] = pending.second;
1465                         cmd[3] = pending.frame;
1466                 }
1467
1468                 cmd[6] =
1469                     (unsigned
1470                      char) ((stuffp->high_border - stuffp->pending) / 4);
1471                 xtrace(XFER, "[%2d]\n", cmd[6]);
1472
1473                 stuffp->busy = 1;
1474                 /* Now really issue the request command */
1475                 outsb(stuffp->wreg_data, cmd, sizeof cmd);
1476
1477         }
1478 #ifdef AK2
1479         if (stuffp->int_err) {
1480                 stuffp->valid = 0;
1481                 stuffp->int_err = 0;
1482                 return -1;
1483         }
1484 #endif                          /* AK2 */
1485
1486         stuffp->low_border = (stuffp->low_border +=
1487                               done) <
1488             stuffp->high_border ? stuffp->low_border : stuffp->high_border;
1489
1490         return done;
1491 }
1492
1493
1494 /*      Access to elements of the mcdx_drive_map members */
1495
1496 static unsigned port(int *ip)
1497 {
1498         return ip[0];
1499 }
1500 static int irq(int *ip)
1501 {
1502         return ip[1];
1503 }
1504
1505 /*      Misc number converters */
1506
1507 static unsigned int bcd2uint(unsigned char c)
1508 {
1509         return (c >> 4) * 10 + (c & 0x0f);
1510 }
1511
1512 static unsigned int uint2bcd(unsigned int ival)
1513 {
1514         return ((ival / 10) << 4) | (ival % 10);
1515 }
1516
1517 static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
1518 {
1519         l += CD_MSF_OFFSET;
1520         pmsf->minute = uint2bcd(l / 4500), l %= 4500;
1521         pmsf->second = uint2bcd(l / 75);
1522         pmsf->frame = uint2bcd(l % 75);
1523 }
1524
1525 static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
1526 {
1527         return bcd2uint(pmsf->frame)
1528             + bcd2uint(pmsf->second) * 75
1529             + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
1530 }
1531
1532 int mcdx_readtoc(struct s_drive_stuff *stuffp)
1533 /*  Read the toc entries from the CD,
1534  *  Return: -1 on failure, else 0 */
1535 {
1536
1537         if (stuffp->toc) {
1538                 xtrace(READTOC, "ioctl() toc already read\n");
1539                 return 0;
1540         }
1541
1542         xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
1543                stuffp->di.n_last - stuffp->di.n_first + 1);
1544
1545         if (-1 == mcdx_hold(stuffp, 1))
1546                 return -1;
1547
1548         xtrace(READTOC, "ioctl() tocmode\n");
1549         if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
1550                 return -EIO;
1551
1552         /* all seems to be ok so far ... malloc */
1553         {
1554                 int size;
1555                 size =
1556                     sizeof(struct s_subqcode) * (stuffp->di.n_last -
1557                                                  stuffp->di.n_first + 2);
1558
1559                 xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
1560                 stuffp->toc = kmalloc(size, GFP_KERNEL);
1561                 if (!stuffp->toc) {
1562                         xwarn("Cannot malloc %d bytes for toc\n", size);
1563                         mcdx_setdrivemode(stuffp, DATA, 1);
1564                         return -EIO;
1565                 }
1566         }
1567
1568         /* now read actually the index */
1569         {
1570                 int trk;
1571                 int retries;
1572
1573                 for (trk = 0;
1574                      trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
1575                      trk++)
1576                         stuffp->toc[trk].index = 0;
1577
1578                 for (retries = 300; retries; retries--) {       /* why 300? */
1579                         struct s_subqcode q;
1580                         unsigned int idx;
1581
1582                         if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
1583                                 mcdx_setdrivemode(stuffp, DATA, 1);
1584                                 return -EIO;
1585                         }
1586
1587                         idx = bcd2uint(q.index);
1588
1589                         if ((idx > 0)
1590                             && (idx <= stuffp->di.n_last)
1591                             && (q.tno == 0)
1592                             && (stuffp->toc[idx - stuffp->di.n_first].
1593                                 index == 0)) {
1594                                 stuffp->toc[idx - stuffp->di.n_first] = q;
1595                                 xtrace(READTOC,
1596                                        "ioctl() toc idx %d (trk %d)\n",
1597                                        idx, trk);
1598                                 trk--;
1599                         }
1600                         if (trk == 0)
1601                                 break;
1602                 }
1603                 memset(&stuffp->
1604                        toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
1605                        sizeof(stuffp->toc[0]));
1606                 stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
1607                             1].dt = stuffp->di.msf_leadout;
1608         }
1609
1610         /* unset toc mode */
1611         xtrace(READTOC, "ioctl() undo toc mode\n");
1612         if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
1613                 return -EIO;
1614
1615 #if MCDX_DEBUG && READTOC
1616         {
1617                 int trk;
1618                 for (trk = 0;
1619                      trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
1620                      trk++)
1621                         xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
1622                                "  %02x:%02x.%02x  %02x:%02x.%02x\n",
1623                                trk + stuffp->di.n_first,
1624                                stuffp->toc[trk].control,
1625                                stuffp->toc[trk].tno,
1626                                stuffp->toc[trk].index,
1627                                stuffp->toc[trk].tt.minute,
1628                                stuffp->toc[trk].tt.second,
1629                                stuffp->toc[trk].tt.frame,
1630                                stuffp->toc[trk].dt.minute,
1631                                stuffp->toc[trk].dt.second,
1632                                stuffp->toc[trk].dt.frame);
1633         }
1634 #endif
1635
1636         return 0;
1637 }
1638
1639 static int
1640 mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
1641 {
1642         unsigned char cmd[7] = {
1643                 0, 0, 0, 0, 0, 0, 0
1644         };
1645
1646         if (!stuffp->readcmd) {
1647                 xinfo("Can't play from missing disk.\n");
1648                 return -1;
1649         }
1650
1651         cmd[0] = stuffp->playcmd;
1652
1653         cmd[1] = msf->cdmsf_min0;
1654         cmd[2] = msf->cdmsf_sec0;
1655         cmd[3] = msf->cdmsf_frame0;
1656         cmd[4] = msf->cdmsf_min1;
1657         cmd[5] = msf->cdmsf_sec1;
1658         cmd[6] = msf->cdmsf_frame1;
1659
1660         xtrace(PLAYMSF, "ioctl(): play %x "
1661                "%02x:%02x:%02x -- %02x:%02x:%02x\n",
1662                cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
1663
1664         outsb(stuffp->wreg_data, cmd, sizeof cmd);
1665
1666         if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
1667                 xwarn("playmsf() timeout\n");
1668                 return -1;
1669         }
1670
1671         stuffp->audiostatus = CDROM_AUDIO_PLAY;
1672         return 0;
1673 }
1674
1675 static int
1676 mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
1677 {
1678         struct s_subqcode *p;
1679         struct cdrom_msf msf;
1680
1681         if (-1 == mcdx_readtoc(stuffp))
1682                 return -1;
1683
1684         if (ti)
1685                 p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
1686         else
1687                 p = &stuffp->start;
1688
1689         msf.cdmsf_min0 = p->dt.minute;
1690         msf.cdmsf_sec0 = p->dt.second;
1691         msf.cdmsf_frame0 = p->dt.frame;
1692
1693         if (ti) {
1694                 p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
1695                 stuffp->stop = *p;
1696         } else
1697                 p = &stuffp->stop;
1698
1699         msf.cdmsf_min1 = p->dt.minute;
1700         msf.cdmsf_sec1 = p->dt.second;
1701         msf.cdmsf_frame1 = p->dt.frame;
1702
1703         return mcdx_playmsf(stuffp, &msf);
1704 }
1705
1706
1707 /* Drive functions ************************************************/
1708
1709 static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
1710 {
1711         struct s_drive_stuff *stuffp = cdi->handle;
1712
1713         if (!stuffp->present)
1714                 return -ENXIO;
1715         if (!(stuffp->present & DOOR))
1716                 return -ENOSYS;
1717
1718         if (position)           /* 1: eject */
1719                 return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
1720         else                    /* 0: close */
1721                 return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
1722         return 1;
1723 }
1724
1725 static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
1726 {
1727         return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
1728 }
1729
1730 static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
1731 {
1732         return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
1733 }
1734
1735 static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
1736                      struct s_subqcode *sub, int tries)
1737 {
1738         char buf[11];
1739         int ans;
1740
1741         if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
1742                                    2 * HZ, tries)))
1743                 return -1;
1744         sub->control = buf[1];
1745         sub->tno = buf[2];
1746         sub->index = buf[3];
1747         sub->tt.minute = buf[4];
1748         sub->tt.second = buf[5];
1749         sub->tt.frame = buf[6];
1750         sub->dt.minute = buf[8];
1751         sub->dt.second = buf[9];
1752         sub->dt.frame = buf[10];
1753
1754         return ans;
1755 }
1756
1757 static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
1758                           struct s_multi *multi, int tries)
1759 {
1760         char buf[5];
1761         int ans;
1762
1763         if (stuffp->present & MULTI) {
1764                 ans =
1765                     mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
1766                               tries);
1767                 multi->multi = buf[1];
1768                 multi->msf_last.minute = buf[2];
1769                 multi->msf_last.second = buf[3];
1770                 multi->msf_last.frame = buf[4];
1771                 return ans;
1772         } else {
1773                 multi->multi = 0;
1774                 return 0;
1775         }
1776 }
1777
1778 static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
1779                     int tries)
1780 {
1781         char buf[9];
1782         int ans;
1783         ans =
1784             mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
1785         if (ans == -1) {
1786                 info->n_first = 0;
1787                 info->n_last = 0;
1788         } else {
1789                 info->n_first = bcd2uint(buf[1]);
1790                 info->n_last = bcd2uint(buf[2]);
1791                 info->msf_leadout.minute = buf[3];
1792                 info->msf_leadout.second = buf[4];
1793                 info->msf_leadout.frame = buf[5];
1794                 info->msf_first.minute = buf[6];
1795                 info->msf_first.second = buf[7];
1796                 info->msf_first.frame = buf[8];
1797         }
1798         return ans;
1799 }
1800
1801 static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
1802                   int tries)
1803 {
1804         char cmd[2];
1805         int ans;
1806
1807         xtrace(HW, "setdrivemode() %d\n", mode);
1808
1809         if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries)))
1810                 return -1;
1811
1812         switch (mode) {
1813         case TOC:
1814                 cmd[1] |= 0x04;
1815                 break;
1816         case DATA:
1817                 cmd[1] &= ~0x04;
1818                 break;
1819         case RAW:
1820                 cmd[1] |= 0x40;
1821                 break;
1822         case COOKED:
1823                 cmd[1] &= ~0x40;
1824                 break;
1825         default:
1826                 break;
1827         }
1828         cmd[0] = 0x50;
1829         return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1830 }
1831
1832 static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
1833                  int tries)
1834 {
1835         unsigned char cmd[2] = { 0xa0 };
1836         xtrace(HW, "setdatamode() %d\n", mode);
1837         switch (mode) {
1838         case MODE0:
1839                 cmd[1] = 0x00;
1840                 break;
1841         case MODE1:
1842                 cmd[1] = 0x01;
1843                 break;
1844         case MODE2:
1845                 cmd[1] = 0x02;
1846                 break;
1847         default:
1848                 return -EINVAL;
1849         }
1850         return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1851 }
1852
1853 static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
1854 {
1855         char cmd[4];
1856
1857         xtrace(HW, "config()\n");
1858
1859         cmd[0] = 0x90;
1860
1861         cmd[1] = 0x10;          /* irq enable */
1862         cmd[2] = 0x05;          /* pre, err irq enable */
1863
1864         if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries))
1865                 return -1;
1866
1867         cmd[1] = 0x02;          /* dma select */
1868         cmd[2] = 0x00;          /* no dma */
1869
1870         return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
1871 }
1872
1873 static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
1874                     int tries)
1875 {
1876         char buf[3];
1877         int ans;
1878
1879         if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
1880                                    1, buf, sizeof(buf), 2 * HZ, tries)))
1881                 return ans;
1882
1883         ver->code = buf[1];
1884         ver->ver = buf[2];
1885
1886         return ans;
1887 }
1888
1889 static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
1890 {
1891         if (mode == HARD) {
1892                 outb(0, stuffp->wreg_chn);      /* no dma, no irq -> hardware */
1893                 outb(0, stuffp->wreg_reset);    /* hw reset */
1894                 return 0;
1895         } else
1896                 return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
1897 }
1898
1899 static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
1900 {
1901         struct s_drive_stuff *stuffp = cdi->handle;
1902         char cmd[2] = { 0xfe };
1903
1904         if (!(stuffp->present & DOOR))
1905                 return -ENOSYS;
1906         if (stuffp->present & DOOR) {
1907                 cmd[1] = lock ? 0x01 : 0x00;
1908                 return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
1909         } else
1910                 return 0;
1911 }
1912
1913 static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
1914 {
1915         return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
1916 }
1917
1918 static int
1919 mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
1920 {
1921         unsigned long timeout = to + jiffies;
1922         char c;
1923
1924         if (!buf)
1925                 buf = &c;
1926
1927         while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
1928                 if (time_after(jiffies, timeout))
1929                         return -1;
1930                 mcdx_delay(stuffp, delay);
1931         }
1932
1933         *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
1934
1935         return 0;
1936 }
1937
1938 static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
1939                     struct cdrom_volctrl *vol, int tries)
1940 {
1941         char cmd[5];
1942         cmd[0] = 0xae;
1943         cmd[1] = vol->channel0;
1944         cmd[2] = 0;
1945         cmd[3] = vol->channel1;
1946         cmd[4] = 0;
1947
1948         return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
1949 }
1950
1951 MODULE_LICENSE("GPL");
1952 MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);