]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/scd/scd.c
Fix privilege escalation in cd(4) driver.
[FreeBSD/FreeBSD.git] / sys / dev / scd / scd.c
1 /*-
2  * Copyright (c) 1995 Mikael Hybsch
3  * All rights reserved.
4  *
5  * Portions of this file are copied from mcd.c
6  * which has the following copyrights:
7  *
8  *      Copyright 1993 by Holger Veit (data part)
9  *      Copyright 1993 by Brian Moore (audio part)
10  *      Changes Copyright 1993 by Gary Clark II
11  *      Changes Copyright (C) 1994 by Andrew A. Chernov
12  *
13  *      Rewrote probe routine to work on newer Mitsumi drives.
14  *      Additional changes (C) 1994 by Jordan K. Hubbard
15  *
16  *      All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer
23  *    in this position and unchanged.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  * 3. The name of the author may not be used to endorse or promote products
28  *    derived from this software without specific prior written permission
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
39  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  */
42
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45
46
47 #undef  SCD_DEBUG
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/conf.h>
53 #include <sys/fcntl.h>
54 #include <sys/bio.h>
55 #include <sys/cdio.h>
56 #include <sys/disk.h>
57 #include <sys/bus.h>
58
59 #include <machine/stdarg.h>
60
61 #include <machine/bus.h>
62 #include <machine/resource.h>
63 #include <sys/rman.h>
64
65 #include <isa/isavar.h>
66
67 #include <dev/scd/scdreg.h>
68 #include <dev/scd/scdvar.h>
69
70 /* flags */
71 #define SCDOPEN         0x0001  /* device opened */
72 #define SCDVALID        0x0002  /* parameters loaded */
73 #define SCDINIT         0x0004  /* device is init'd */
74 #define SCDPROBING      0x0020  /* probing */
75 #define SCDTOC          0x0100  /* already read toc */
76 #define SCDMBXBSY       0x0200  /* local mbx is busy */
77 #define SCDSPINNING     0x0400  /* drive is spun up */
78
79 #define SCD_S_BEGIN     0
80 #define SCD_S_BEGIN1    1
81 #define SCD_S_WAITSTAT  2
82 #define SCD_S_WAITFIFO  3
83 #define SCD_S_WAITSPIN  4
84 #define SCD_S_WAITREAD  5
85 #define SCD_S_WAITPARAM 6
86
87 #define RDELAY_WAIT     300
88 #define RDELAY_WAITREAD 300
89
90 #define SCDBLKSIZE      2048
91
92 #ifdef SCD_DEBUG
93    static int scd_debuglevel = SCD_DEBUG;
94 #  define XDEBUG(sc, level, fmt, args...) \
95         do { \
96                 if (scd_debuglevel >= level) \
97                         device_printf(sc->dev, fmt, ## args); \
98         } while (0)
99 #else
100 #  define XDEBUG(sc, level, fmt, args...)
101 #endif
102
103 #define IS_ATTENTION(sc)        ((SCD_READ(sc, IREG_STATUS) & SBIT_ATTENTION) != 0)
104 #define IS_BUSY(sc)             ((SCD_READ(sc, IREG_STATUS) & SBIT_BUSY) != 0)
105 #define IS_DATA_RDY(sc)         ((SCD_READ(sc, IREG_STATUS) & SBIT_DATA_READY) != 0)
106 #define STATUS_BIT(sc, bit)     ((SCD_READ(sc, IREG_STATUS) & (bit)) != 0)
107 #define FSTATUS_BIT(sc, bit)    ((SCD_READ(sc, IREG_FSTATUS) & (bit)) != 0)
108
109 /* prototypes */
110 static  void    hsg2msf(int hsg, bcd_t *msf);
111 static  int     msf2hsg(bcd_t *msf);
112
113 static void process_attention(struct scd_softc *);
114 static int waitfor_status_bits(struct scd_softc *, int bits_set, int bits_clear);
115 static int send_cmd(struct scd_softc *, u_char cmd, u_int nargs, ...);
116 static void init_drive(struct scd_softc *);
117 static int spin_up(struct scd_softc *);
118 static int read_toc(struct scd_softc *);
119 static int get_result(struct scd_softc *, int result_len, u_char *result);
120 static void print_error(struct scd_softc *, int errcode);
121
122 static void scd_start(struct scd_softc *);
123 static void scd_timeout(void *);
124 static void scd_doread(struct scd_softc *, int state, struct scd_mbx *mbxin);
125
126 static int scd_eject(struct scd_softc *);
127 static int scd_stop(struct scd_softc *);
128 static int scd_pause(struct scd_softc *);
129 static int scd_resume(struct scd_softc *);
130 static int scd_playtracks(struct scd_softc *, struct ioc_play_track *pt);
131 static int scd_playmsf(struct scd_softc *, struct ioc_play_msf *msf);
132 static int scd_play(struct scd_softc *, struct ioc_play_msf *msf);
133 static int scd_subchan(struct scd_softc *, struct ioc_read_subchannel *sch);
134 static int read_subcode(struct scd_softc *, struct sony_subchannel_position_data *sch);
135
136 /* for xcdplayer */
137 static int scd_toc_header(struct scd_softc *, struct ioc_toc_header *th);
138 static int scd_toc_entrys(struct scd_softc *, struct ioc_read_toc_entry *te);
139 static int scd_toc_entry(struct scd_softc *, struct ioc_read_toc_single_entry *te);
140 #define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */
141
142 static  d_open_t        scdopen;
143 static  d_close_t       scdclose;
144 static  d_ioctl_t       scdioctl;
145 static  d_strategy_t    scdstrategy;
146
147
148 static struct cdevsw scd_cdevsw = {
149         .d_version =    D_VERSION,
150         .d_open =       scdopen,
151         .d_close =      scdclose,
152         .d_read =       physread,
153         .d_ioctl =      scdioctl,
154         .d_strategy =   scdstrategy,
155         .d_name =       "scd",
156         .d_flags =      D_DISK,
157 };
158
159 int
160 scd_attach(struct scd_softc *sc)
161 {
162         int unit;
163
164         unit = device_get_unit(sc->dev);
165
166         SCD_LOCK(sc);
167         init_drive(sc);
168
169         sc->data.flags = SCDINIT;
170         sc->data.audio_status = CD_AS_AUDIO_INVALID;
171         bioq_init(&sc->data.head);
172         SCD_UNLOCK(sc);
173
174         sc->scd_dev_t = make_dev(&scd_cdevsw, 8 * unit,
175                 UID_ROOT, GID_OPERATOR, 0640, "scd%d", unit);
176         sc->scd_dev_t->si_drv1 = (void *)sc;
177         device_printf(sc->dev,
178             "WARNING: This driver is deprecated and will be removed.\n");
179
180         return (0);
181 }
182
183 static  int
184 scdopen(struct cdev *dev, int flags, int fmt, struct thread *td)
185 {
186         struct scd_softc *sc;
187         int rc;
188
189         sc = (struct scd_softc *)dev->si_drv1;
190
191         /* mark all open part's invalid */
192         SCD_LOCK(sc);
193         if (sc->data.openflag) {
194                 SCD_UNLOCK(sc);
195                 return (ENXIO);
196         }
197
198         XDEBUG(sc, 1, "DEBUG: status = 0x%x\n", SCD_READ(sc, IREG_STATUS));
199
200         if ((rc = spin_up(sc)) != 0) {
201                 print_error(sc, rc);
202                 SCD_UNLOCK(sc);
203                 return (EIO);
204         }
205         if (!(sc->data.flags & SCDTOC)) {
206                 int loop_count = 3;
207
208                 while (loop_count-- > 0 && (rc = read_toc(sc)) != 0) {
209                         if (rc == ERR_NOT_SPINNING) {
210                                 rc = spin_up(sc);
211                                 if (rc) {
212                                         print_error(sc, rc);
213                                         SCD_UNLOCK(sc);
214                                         return (EIO);
215                                 }
216                                 continue;
217                         }
218                         device_printf(sc->dev, "TOC read error 0x%x\n", rc);
219                         SCD_UNLOCK(sc);
220                         return (EIO);
221                 }
222         }
223
224         sc->data.openflag = 1;
225         sc->data.flags |= SCDVALID;
226         SCD_UNLOCK(sc);
227
228         return (0);
229 }
230
231 static  int
232 scdclose(struct cdev *dev, int flags, int fmt, struct thread *td)
233 {
234         struct scd_softc *sc;
235
236         sc = (struct scd_softc *)dev->si_drv1;
237
238         SCD_LOCK(sc);
239         KASSERT(sc->data.openflag, ("device not open"));
240
241         if (sc->data.audio_status != CD_AS_PLAY_IN_PROGRESS) {
242                 (void)send_cmd(sc, CMD_SPIN_DOWN, 0);
243                 sc->data.flags &= ~SCDSPINNING;
244         }
245
246         /* close channel */
247         sc->data.openflag = 0;
248         SCD_UNLOCK(sc);
249
250         return (0);
251 }
252
253 static  void
254 scdstrategy(struct bio *bp)
255 {
256         struct scd_softc *sc;
257
258         sc = (struct scd_softc *)bp->bio_dev->si_drv1;
259
260         /* if device invalidated (e.g. media change, door open), error */
261         SCD_LOCK(sc);
262         if (!(sc->data.flags & SCDVALID)) {
263                 device_printf(sc->dev, "media changed\n");
264                 bp->bio_error = EIO;
265                 goto bad;
266         }
267
268         /* read only */
269         if (!(bp->bio_cmd == BIO_READ)) {
270                 bp->bio_error = EROFS;
271                 goto bad;
272         }
273
274         /* no data to read */
275         if (bp->bio_bcount == 0)
276                 goto done;
277
278         if (!(sc->data.flags & SCDTOC)) {
279                 bp->bio_error = EIO;
280                 goto bad;
281         }
282
283         bp->bio_resid = 0;
284
285         /* queue it */
286         bioq_disksort(&sc->data.head, bp);
287
288         /* now check whether we can perform processing */
289         scd_start(sc);
290         SCD_UNLOCK(sc);
291         return;
292
293 bad:
294         bp->bio_flags |= BIO_ERROR;
295 done:
296         SCD_UNLOCK(sc);
297         bp->bio_resid = bp->bio_bcount;
298         biodone(bp);
299         return;
300 }
301
302 static void
303 scd_start(struct scd_softc *sc)
304 {
305         struct bio *bp;
306
307         SCD_ASSERT_LOCKED(sc);
308         if (sc->data.flags & SCDMBXBSY)
309                 return;
310
311         bp = bioq_takefirst(&sc->data.head);
312         if (bp != 0) {
313                 /* block found to process, dequeue */
314                 sc->data.flags |= SCDMBXBSY;
315         } else {
316                 /* nothing to do */
317                 return;
318         }
319
320         sc->data.mbx.retry = 3;
321         sc->data.mbx.bp = bp;
322
323         scd_doread(sc, SCD_S_BEGIN, &(sc->data.mbx));
324         return;
325 }
326
327 static  int
328 scdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
329 {
330         struct scd_softc *sc;
331         int error;
332
333         sc = (struct scd_softc *)dev->si_drv1;
334
335         XDEBUG(sc, 1, "ioctl: cmd=0x%lx\n", cmd);
336
337         SCD_LOCK(sc);
338         if (!(sc->data.flags & SCDVALID)) {
339                 SCD_UNLOCK(sc);
340                 return (EIO);
341         }
342
343         error = 0;
344         switch (cmd) {
345         case DIOCGMEDIASIZE:
346                 *(off_t *)addr = (off_t)sc->data.disksize * sc->data.blksize;
347                 break;
348         case DIOCGSECTORSIZE:
349                 *(u_int *)addr = sc->data.blksize;
350                 break;
351         case CDIOCPLAYTRACKS:
352                 error = scd_playtracks(sc, (struct ioc_play_track *) addr);
353                 break;
354         case CDIOCPLAYBLOCKS:
355                 error = EINVAL;
356                 break;
357         case CDIOCPLAYMSF:
358                 error = scd_playmsf(sc, (struct ioc_play_msf *) addr);
359                 break;
360         case CDIOCREADSUBCHANNEL:
361                 return scd_subchan(sc, (struct ioc_read_subchannel *) addr);
362         case CDIOREADTOCHEADER:
363                 error = scd_toc_header (sc, (struct ioc_toc_header *) addr);
364                 break;
365         case CDIOREADTOCENTRYS:
366                 return scd_toc_entrys (sc, (struct ioc_read_toc_entry*) addr);
367         case CDIOREADTOCENTRY:
368                 error = scd_toc_entry (sc, (struct ioc_read_toc_single_entry*) addr);
369                 break;
370         case CDIOCSETPATCH:
371         case CDIOCGETVOL:
372         case CDIOCSETVOL:
373         case CDIOCSETMONO:
374         case CDIOCSETSTERIO:
375         case CDIOCSETMUTE:
376         case CDIOCSETLEFT:
377         case CDIOCSETRIGHT:
378                 error = EINVAL;
379                 break;
380         case CDIOCRESUME:
381                 error = scd_resume(sc);
382                 break;
383         case CDIOCPAUSE:
384                 error = scd_pause(sc);
385                 break;
386         case CDIOCSTART:
387                 error = EINVAL;
388                 break;
389         case CDIOCSTOP:
390                 error = scd_stop(sc);
391                 break;
392         case CDIOCEJECT:
393                 error = scd_eject(sc);
394                 break;
395         case CDIOCALLOW:
396                 break;
397         case CDIOCSETDEBUG:
398 #ifdef SCD_DEBUG
399                 scd_debuglevel++;
400 #endif
401                 break;
402         case CDIOCCLRDEBUG:
403 #ifdef SCD_DEBUG
404                 scd_debuglevel = 0;
405
406 #endif
407                 break;
408         default:
409                 device_printf(sc->dev, "unsupported ioctl (cmd=0x%lx)\n", cmd);
410                 error = ENOTTY;
411                 break;
412         }
413         SCD_UNLOCK(sc);
414         return (error);
415 }
416
417 /***************************************************************
418  * lower level of driver starts here
419  **************************************************************/
420
421 static int
422 scd_playtracks(struct scd_softc *sc, struct ioc_play_track *pt)
423 {
424         struct ioc_play_msf msf;
425         int a = pt->start_track;
426         int z = pt->end_track;
427         int rc;
428
429         if (!(sc->data.flags & SCDTOC) && (rc = read_toc(sc)) != 0) {
430                 if (rc == -ERR_NOT_SPINNING) {
431                         if (spin_up(sc) != 0)
432                                 return (EIO);
433                         rc = read_toc(sc);
434                 }
435                 if (rc != 0) {
436                         print_error(sc, rc);
437                         return (EIO);
438                 }
439         }
440
441         XDEBUG(sc, 1, "playtracks from %d:%d to %d:%d\n",
442                 a, pt->start_index, z, pt->end_index);
443
444         if (   a < sc->data.first_track
445             || a > sc->data.last_track
446             || a > z
447             || z > sc->data.last_track)
448                 return (EINVAL);
449
450         bcopy(sc->data.toc[a].start_msf, &msf.start_m, 3);
451         hsg2msf(msf2hsg(sc->data.toc[z+1].start_msf)-1, &msf.end_m);
452
453         return scd_play(sc, &msf);
454 }
455
456 /* The start/end msf is expected to be in bin format */
457 static int
458 scd_playmsf(struct scd_softc *sc, struct ioc_play_msf *msfin)
459 {
460         struct ioc_play_msf msf;
461
462         msf.start_m = bin2bcd(msfin->start_m);
463         msf.start_s = bin2bcd(msfin->start_s);
464         msf.start_f = bin2bcd(msfin->start_f);
465         msf.end_m = bin2bcd(msfin->end_m);
466         msf.end_s = bin2bcd(msfin->end_s);
467         msf.end_f = bin2bcd(msfin->end_f);
468
469         return scd_play(sc, &msf);
470 }
471
472 /* The start/end msf is expected to be in bcd format */
473 static int
474 scd_play(struct scd_softc *sc, struct ioc_play_msf *msf)
475 {
476         int i, rc;
477
478         XDEBUG(sc, 1, "playing: %02x:%02x:%02x -> %02x:%02x:%02x\n",
479                 msf->start_m, msf->start_s, msf->start_f,
480                 msf->end_m, msf->end_s, msf->end_f);
481
482         for (i = 0; i < 2; i++) {
483                 rc = send_cmd(sc, CMD_PLAY_AUDIO, 7,
484                         0x03,
485                         msf->start_m, msf->start_s, msf->start_f,
486                         msf->end_m, msf->end_s, msf->end_f);
487                 if (rc == -ERR_NOT_SPINNING) {
488                         sc->data.flags &= ~SCDSPINNING;
489                         if (spin_up(sc) != 0)
490                                 return (EIO);
491                 } else if (rc < 0) {
492                         print_error(sc, rc);
493                         return (EIO);
494                 } else {
495                         break;
496                 }
497         }
498         sc->data.audio_status = CD_AS_PLAY_IN_PROGRESS;
499         bcopy((char *)msf, (char *)&sc->data.last_play, sizeof(struct ioc_play_msf));
500         return (0);
501 }
502
503 static int
504 scd_stop(struct scd_softc *sc)
505 {
506
507         (void)send_cmd(sc, CMD_STOP_AUDIO, 0);
508         sc->data.audio_status = CD_AS_PLAY_COMPLETED;
509         return (0);
510 }
511
512 static int
513 scd_pause(struct scd_softc *sc)
514 {
515         struct sony_subchannel_position_data subpos;
516
517         if (sc->data.audio_status != CD_AS_PLAY_IN_PROGRESS)
518                 return (EINVAL);
519
520         if (read_subcode(sc, &subpos) != 0)
521                 return (EIO);
522
523         if (send_cmd(sc, CMD_STOP_AUDIO, 0) != 0)
524                 return (EIO);
525
526         sc->data.last_play.start_m = subpos.abs_msf[0];
527         sc->data.last_play.start_s = subpos.abs_msf[1];
528         sc->data.last_play.start_f = subpos.abs_msf[2];
529         sc->data.audio_status = CD_AS_PLAY_PAUSED;
530
531         XDEBUG(sc, 1, "pause @ %02x:%02x:%02x\n",
532                 sc->data.last_play.start_m,
533                 sc->data.last_play.start_s,
534                 sc->data.last_play.start_f);
535
536         return (0);
537 }
538
539 static int
540 scd_resume(struct scd_softc *sc)
541 {
542
543         if (sc->data.audio_status != CD_AS_PLAY_PAUSED)
544                 return (EINVAL);
545         return scd_play(sc, &sc->data.last_play);
546 }
547
548 static int
549 scd_eject(struct scd_softc *sc)
550 {
551
552         sc->data.audio_status = CD_AS_AUDIO_INVALID;
553         sc->data.flags &= ~(SCDSPINNING|SCDTOC);
554
555         if (send_cmd(sc, CMD_STOP_AUDIO, 0) != 0 ||
556             send_cmd(sc, CMD_SPIN_DOWN, 0) != 0 ||
557             send_cmd(sc, CMD_EJECT, 0) != 0)
558         {
559                 return (EIO);
560         }
561         return (0);
562 }
563
564 static int
565 scd_subchan(struct scd_softc *sc, struct ioc_read_subchannel *sch)
566 {
567         struct sony_subchannel_position_data q;
568         struct cd_sub_channel_info data;
569
570         XDEBUG(sc, 1, "subchan af=%d, df=%d\n",
571                 sch->address_format, sch->data_format);
572
573         if (sch->address_format != CD_MSF_FORMAT)
574                 return (EINVAL);
575
576         if (sch->data_format != CD_CURRENT_POSITION)
577                 return (EINVAL);
578
579         if (read_subcode(sc, &q) != 0)
580                 return (EIO);
581
582         data.header.audio_status = sc->data.audio_status;
583         data.what.position.data_format = CD_MSF_FORMAT;
584         data.what.position.track_number = bcd2bin(q.track_number);
585         data.what.position.reladdr.msf.unused = 0;
586         data.what.position.reladdr.msf.minute = bcd2bin(q.rel_msf[0]);
587         data.what.position.reladdr.msf.second = bcd2bin(q.rel_msf[1]);
588         data.what.position.reladdr.msf.frame = bcd2bin(q.rel_msf[2]);
589         data.what.position.absaddr.msf.unused = 0;
590         data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]);
591         data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]);
592         data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]);
593         SCD_UNLOCK(sc);
594
595         if (copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len))!=0)
596                 return (EFAULT);
597         return (0);
598 }
599
600 int
601 scd_probe(struct scd_softc *sc)
602 {
603         struct sony_drive_configuration drive_config;
604         int rc;
605         static char namebuf[8+16+8+3];
606         char *s = namebuf;
607         int loop_count = 0;
608
609         sc->data.flags = SCDPROBING;
610
611         bzero(&drive_config, sizeof(drive_config));
612
613 again:
614         /* Reset drive */
615         SCD_WRITE(sc, OREG_CONTROL, CBIT_RESET_DRIVE);
616
617         /* Calm down */
618         DELAY(300000);
619
620         /* Only the ATTENTION bit may be set */
621         if ((SCD_READ(sc, IREG_STATUS) & ~1) != 0) {
622                 XDEBUG(sc, 1, "too many bits set. probe failed.\n");
623                 return (ENXIO);
624         }
625         rc = send_cmd(sc, CMD_GET_DRIVE_CONFIG, 0);
626         if (rc != sizeof(drive_config)) {
627                 /* Sometimes if the drive is playing audio I get */
628                 /* the bad result 82. Fix by repeating the reset */
629                 if (rc > 0 && loop_count++ == 0)
630                         goto again;
631                 return (ENXIO);
632         }
633         if (get_result(sc, rc, (u_char *)&drive_config) != 0)
634                 return (ENXIO);
635
636         bcopy(drive_config.vendor, namebuf, 8);
637         s = namebuf+8;
638         while (*(s-1) == ' ')   /* Strip trailing spaces */
639                 s--;
640         *s++ = ' ';
641         bcopy(drive_config.product, s, 16);
642         s += 16;
643         while (*(s-1) == ' ')
644                 s--;
645         *s++ = ' ';
646         bcopy(drive_config.revision, s, 8);
647         s += 8;
648         while (*(s-1) == ' ')
649                 s--;
650         *s = 0;
651
652         sc->data.name = namebuf;
653
654         if (drive_config.config & 0x10)
655                 sc->data.double_speed = 1;
656         else
657                 sc->data.double_speed = 0;
658
659         return (0);
660 }
661
662 static int
663 read_subcode(struct scd_softc *sc, struct sony_subchannel_position_data *scp)
664 {
665         int rc;
666
667         rc = send_cmd(sc, CMD_GET_SUBCHANNEL_DATA, 0);
668         if (rc < 0 || rc < sizeof(*scp))
669                 return (EIO);
670         if (get_result(sc, rc, (u_char *)scp) != 0)
671                 return (EIO);
672         return (0);
673 }
674
675 /* State machine copied from mcd.c */
676
677 /* This (and the code in mcd.c) will not work with more than one drive */
678 /* because there is only one sc->ch_mbxsave below. Should fix that some day. */
679 /* (sc->ch_mbxsave & state should probably be included in the scd_data struct and */
680 /*  the unit number used as first argument to scd_doread().) /Micke */
681
682 /* state machine to process read requests
683  * initialize with SCD_S_BEGIN: reset state machine
684  * SCD_S_WAITSTAT:  wait for ready (!busy)
685  * SCD_S_WAITSPIN:  wait for drive to spin up (if not spinning)
686  * SCD_S_WAITFIFO:  wait for param fifo to get ready, them exec. command.
687  * SCD_S_WAITREAD:  wait for data ready, read data
688  * SCD_S_WAITPARAM: wait for command result params, read them, error if bad data read.
689  */
690
691 static void
692 scd_timeout(void *arg)
693 {
694         struct scd_softc *sc;
695         sc = (struct scd_softc *)arg;
696
697         SCD_ASSERT_LOCKED(sc);
698         scd_doread(sc, sc->ch_state, sc->ch_mbxsave);
699 }
700
701 static void
702 scd_doread(struct scd_softc *sc, int state, struct scd_mbx *mbxin)
703 {
704         struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? sc->ch_mbxsave : mbxin;
705         struct  bio *bp = mbx->bp;
706         int     i;
707         int     blknum;
708         caddr_t addr;
709         static char sdata[3];   /* Must be preserved between calls to this function */
710
711         SCD_ASSERT_LOCKED(sc);
712 loop:
713         switch (state) {
714         case SCD_S_BEGIN:
715                 mbx = sc->ch_mbxsave = mbxin;
716
717         case SCD_S_BEGIN1:
718                 /* get status */
719                 mbx->count = RDELAY_WAIT;
720
721                 process_attention(sc);
722                 goto trystat;
723
724         case SCD_S_WAITSTAT:
725                 sc->ch_state = SCD_S_WAITSTAT;
726                 callout_stop(&sc->timer);
727                 if (mbx->count-- <= 0) {
728                         device_printf(sc->dev, "timeout. drive busy.\n");
729                         goto harderr;
730                 }
731
732 trystat:
733                 if (IS_BUSY(sc)) {
734                         sc->ch_state = SCD_S_WAITSTAT;
735                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
736                         return;
737                 }
738
739                 process_attention(sc);
740
741                 /* reject, if audio active */
742                 if (sc->data.audio_status & CD_AS_PLAY_IN_PROGRESS) {
743                         device_printf(sc->dev, "audio is active\n");
744                         goto harderr;
745                 }
746
747                 mbx->sz = sc->data.blksize;
748
749                 /* for first block */
750                 mbx->nblk = howmany(bp->bio_bcount, mbx->sz);
751                 mbx->skip = 0;
752
753 nextblock:
754                 if (!(sc->data.flags & SCDVALID))
755                         goto changed;
756
757                 blknum  = bp->bio_offset / mbx->sz + mbx->skip/mbx->sz;
758
759                 XDEBUG(sc, 2, "scd_doread: read blknum=%d\n", blknum);
760
761                 /* build parameter block */
762                 hsg2msf(blknum, sdata);
763
764                 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
765                 SCD_WRITE(sc, OREG_CONTROL, CBIT_RPARAM_CLEAR);
766                 SCD_WRITE(sc, OREG_CONTROL, CBIT_DATA_READY_CLEAR);
767
768                 if (FSTATUS_BIT(sc, FBIT_WPARAM_READY))
769                         goto writeparam;
770
771                 mbx->count = 100;
772                 sc->ch_state = SCD_S_WAITFIFO;
773                 callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
774                 return;
775
776         case SCD_S_WAITSPIN:
777                 sc->ch_state = SCD_S_WAITSPIN;
778                 callout_stop(&sc->timer);
779                 if (mbx->count-- <= 0) {
780                         device_printf(sc->dev, "timeout waiting for drive to spin up.\n");
781                         goto harderr;
782                 }
783                 if (!STATUS_BIT(sc, SBIT_RESULT_READY)) {
784                         sc->ch_state = SCD_S_WAITSPIN;
785                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
786                         return;
787                 }
788                 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
789                 switch ((i = SCD_READ(sc, IREG_RESULT)) & 0xf0) {
790                 case 0x20:
791                         i = SCD_READ(sc, IREG_RESULT);
792                         print_error(sc, i);
793                         goto harderr;
794                 case 0x00:
795                         (void)SCD_READ(sc, IREG_RESULT);
796                         sc->data.flags |= SCDSPINNING;
797                         break;
798                 }
799                 XDEBUG(sc, 1, "DEBUG: spin up complete\n");
800
801                 state = SCD_S_BEGIN1;
802                 goto loop;
803
804         case SCD_S_WAITFIFO:
805                 sc->ch_state = SCD_S_WAITFIFO;
806                 callout_stop(&sc->timer);
807                 if (mbx->count-- <= 0) {
808                         device_printf(sc->dev, "timeout. write param not ready.\n");
809                         goto harderr;
810                 }
811                 if (!FSTATUS_BIT(sc, FBIT_WPARAM_READY)) {
812                         sc->ch_state = SCD_S_WAITFIFO;
813                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
814                         return;
815                 }
816                 XDEBUG(sc, 1, "mbx->count (writeparamwait) = %d(%d)\n", mbx->count, 100);
817
818 writeparam:
819                 /* The reason this test isn't done 'till now is to make sure */
820                 /* that it is ok to send the SPIN_UP cmd below. */
821                 if (!(sc->data.flags & SCDSPINNING)) {
822                         XDEBUG(sc, 1, "spinning up drive ...\n");
823                         SCD_WRITE(sc, OREG_COMMAND, CMD_SPIN_UP);
824                         mbx->count = 300;
825                         sc->ch_state = SCD_S_WAITSPIN;
826                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
827                         return;
828                 }
829
830                 /* send the read command */
831                 SCD_WRITE(sc, OREG_WPARAMS, sdata[0]);
832                 SCD_WRITE(sc, OREG_WPARAMS, sdata[1]);
833                 SCD_WRITE(sc, OREG_WPARAMS, sdata[2]);
834                 SCD_WRITE(sc, OREG_WPARAMS, 0);
835                 SCD_WRITE(sc, OREG_WPARAMS, 0);
836                 SCD_WRITE(sc, OREG_WPARAMS, 1);
837                 SCD_WRITE(sc, OREG_COMMAND, CMD_READ);
838
839                 mbx->count = RDELAY_WAITREAD;
840                 for (i = 0; i < 50; i++) {
841                         if (STATUS_BIT(sc, SBIT_DATA_READY))
842                                 goto got_data;
843                         DELAY(100);
844                 }
845
846                 sc->ch_state = SCD_S_WAITREAD;
847                 callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
848                 return;
849
850         case SCD_S_WAITREAD:
851                 sc->ch_state = SCD_S_WAITREAD;
852                 callout_stop(&sc->timer);
853                 if (mbx->count-- <= 0) {
854                         if (STATUS_BIT(sc, SBIT_RESULT_READY))
855                                 goto got_param;
856                         device_printf(sc->dev, "timeout while reading data\n");
857                         goto readerr;
858                 }
859                 if (!STATUS_BIT(sc, SBIT_DATA_READY)) {
860                         process_attention(sc);
861                         if (!(sc->data.flags & SCDVALID))
862                                 goto changed;
863                         sc->ch_state = SCD_S_WAITREAD;
864                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
865                         return;
866                 }
867                 XDEBUG(sc, 2, "mbx->count (after RDY_BIT) = %d(%d)\n", mbx->count, RDELAY_WAITREAD);
868
869 got_data:
870                 /* data is ready */
871                 addr = bp->bio_data + mbx->skip;
872                 SCD_WRITE(sc, OREG_CONTROL, CBIT_DATA_READY_CLEAR);
873                 SCD_READ_MULTI(sc, IREG_DATA, addr, mbx->sz);
874
875                 mbx->count = 100;
876                 for (i = 0; i < 20; i++) {
877                         if (STATUS_BIT(sc, SBIT_RESULT_READY))
878                                 goto waitfor_param;
879                         DELAY(100);
880                 }
881                 goto waitfor_param;
882
883         case SCD_S_WAITPARAM:
884                 sc->ch_state = SCD_S_WAITPARAM;
885                 callout_stop(&sc->timer);
886                 if (mbx->count-- <= 0) {
887                         device_printf(sc->dev, "timeout waiting for params\n");
888                         goto readerr;
889                 }
890
891 waitfor_param:
892                 if (!STATUS_BIT(sc, SBIT_RESULT_READY)) {
893                         sc->ch_state = SCD_S_WAITPARAM;
894                         callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */
895                         return;
896                 }
897 #ifdef SCD_DEBUG
898                 if (mbx->count < 100 && scd_debuglevel > 0)
899                         device_printf(sc->dev, "mbx->count (paramwait) = %d(%d)\n", mbx->count, 100);
900 #endif
901
902 got_param:
903                 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
904                 switch ((i = SCD_READ(sc, IREG_RESULT)) & 0xf0) {
905                 case 0x50:
906                         switch (i) {
907                         case ERR_FATAL_READ_ERROR1:
908                         case ERR_FATAL_READ_ERROR2:
909                                 device_printf(sc->dev, "unrecoverable read error 0x%x\n", i);
910                                 goto harderr;
911                         }
912                         break;
913                 case 0x20:
914                         i = SCD_READ(sc, IREG_RESULT);
915                         switch (i) {
916                         case ERR_NOT_SPINNING:
917                                 XDEBUG(sc, 1, "read error: drive not spinning\n");
918                                 if (mbx->retry-- > 0) {
919                                         state = SCD_S_BEGIN1;
920                                         sc->data.flags &= ~SCDSPINNING;
921                                         goto loop;
922                                 }
923                                 goto harderr;
924                         default:
925                                 print_error(sc, i);
926                                 goto readerr;
927                         }
928                 case 0x00:
929                         i = SCD_READ(sc, IREG_RESULT);
930                         break;
931                 }
932
933                 if (--mbx->nblk > 0) {
934                         mbx->skip += mbx->sz;
935                         goto nextblock;
936                 }
937
938                 /* return buffer */
939                 bp->bio_resid = 0;
940                 biodone(bp);
941
942                 sc->data.flags &= ~SCDMBXBSY;
943                 scd_start(sc);
944                 return;
945         }
946
947 readerr:
948         if (mbx->retry-- > 0) {
949                 device_printf(sc->dev, "retrying ...\n");
950                 state = SCD_S_BEGIN1;
951                 goto loop;
952         }
953 harderr:
954         /* invalidate the buffer */
955         bp->bio_error = EIO;
956         bp->bio_flags |= BIO_ERROR;
957         bp->bio_resid = bp->bio_bcount;
958         biodone(bp);
959
960         sc->data.flags &= ~SCDMBXBSY;
961         scd_start(sc);
962         return;
963
964 changed:
965         device_printf(sc->dev, "media changed\n");
966         goto harderr;
967 }
968
969 static void
970 hsg2msf(int hsg, bcd_t *msf)
971 {
972
973         hsg += 150;
974         M_msf(msf) = bin2bcd(hsg / 4500);
975         hsg %= 4500;
976         S_msf(msf) = bin2bcd(hsg / 75);
977         F_msf(msf) = bin2bcd(hsg % 75);
978 }
979
980 static int
981 msf2hsg(bcd_t *msf)
982 {
983
984         return (bcd2bin(M_msf(msf)) * 60 +
985                 bcd2bin(S_msf(msf))) * 75 +
986                 bcd2bin(F_msf(msf)) - 150;
987 }
988
989 static void
990 process_attention(struct scd_softc *sc)
991 {
992         unsigned char code;
993         int count = 0;
994
995         while (IS_ATTENTION(sc) && count++ < 30) {
996                 SCD_WRITE(sc, OREG_CONTROL, CBIT_ATTENTION_CLEAR);
997                 code = SCD_READ(sc, IREG_RESULT);
998
999 #ifdef SCD_DEBUG
1000                 if (scd_debuglevel > 0) {
1001                         if (count == 1)
1002                                 device_printf(sc->dev, "DEBUG: ATTENTIONS = 0x%x", code);
1003                         else
1004                                 printf(",0x%x", code);
1005                 }
1006 #endif
1007
1008                 switch (code) {
1009                 case ATTEN_SPIN_DOWN:
1010                         sc->data.flags &= ~SCDSPINNING;
1011                         break;
1012
1013                 case ATTEN_SPIN_UP_DONE:
1014                         sc->data.flags |= SCDSPINNING;
1015                         break;
1016
1017                 case ATTEN_AUDIO_DONE:
1018                         sc->data.audio_status = CD_AS_PLAY_COMPLETED;
1019                         break;
1020
1021                 case ATTEN_DRIVE_LOADED:
1022                         sc->data.flags &= ~(SCDTOC|SCDSPINNING|SCDVALID);
1023                         sc->data.audio_status = CD_AS_AUDIO_INVALID;
1024                         break;
1025
1026                 case ATTEN_EJECT_PUSHED:
1027                         sc->data.flags &= ~SCDVALID;
1028                         break;
1029                 }
1030                 DELAY(100);
1031         }
1032 #ifdef SCD_DEBUG
1033         if (scd_debuglevel > 0 && count > 0)
1034                 printf("\n");
1035 #endif
1036 }
1037
1038 /* Returns 0 OR sony error code */
1039 static int
1040 spin_up(struct scd_softc *sc)
1041 {
1042         unsigned char res_reg[12];
1043         unsigned int res_size;
1044         int rc;
1045         int loop_count = 0;
1046
1047 again:
1048         rc = send_cmd(sc, CMD_SPIN_UP, 0, 0, res_reg, &res_size);
1049         if (rc != 0) {
1050                 XDEBUG(sc, 2, "CMD_SPIN_UP error 0x%x\n", rc);
1051                 return (rc);
1052         }
1053
1054         if (!(sc->data.flags & SCDTOC)) {
1055                 rc = send_cmd(sc, CMD_READ_TOC, 0);
1056                 if (rc == ERR_NOT_SPINNING) {
1057                         if (loop_count++ < 3)
1058                                 goto again;
1059                         return (rc);
1060                 }
1061                 if (rc != 0)
1062                         return (rc);
1063         }
1064
1065         sc->data.flags |= SCDSPINNING;
1066
1067         return (0);
1068 }
1069
1070 static struct sony_tracklist *
1071 get_tl(struct sony_toc *toc, int size)
1072 {
1073         struct sony_tracklist *tl = &toc->tracks[0];
1074
1075         if (tl->track != 0xb0)
1076                 return (tl);
1077         if (tl->track != 0xb1)
1078                 return (tl);
1079         tl = (struct sony_tracklist *)((char *)tl + 9);
1080         if (tl->track != 0xb2)
1081                 return (tl);
1082         tl = (struct sony_tracklist *)((char *)tl + 9);
1083         if (tl->track != 0xb3)
1084                 return (tl);
1085         tl = (struct sony_tracklist *)((char *)tl + 9);
1086         if (tl->track != 0xb4)
1087                 return (tl);
1088         tl = (struct sony_tracklist *)((char *)tl + 9);
1089         if (tl->track != 0xc0)
1090                 return (tl);
1091         tl = (struct sony_tracklist *)((char *)tl + 9);
1092         return (tl);
1093 }
1094
1095 static int
1096 read_toc(struct scd_softc *sc)
1097 {
1098         struct sony_toc toc;
1099         struct sony_tracklist *tl;
1100         int rc, i, j;
1101         u_long first, last;
1102
1103         rc = send_cmd(sc, CMD_GET_TOC, 1, 1);
1104         if (rc < 0)
1105                 return (rc);
1106         if (rc > sizeof(toc)) {
1107                 device_printf(sc->dev, "program error: toc too large (%d)\n", rc);
1108                 return (EIO);
1109         }
1110         if (get_result(sc, rc, (u_char *)&toc) != 0)
1111                 return (EIO);
1112
1113         XDEBUG(sc, 1, "toc read. len = %d, sizeof(toc) = %d\n", rc, sizeof(toc));
1114
1115         tl = get_tl(&toc, rc);
1116         first = msf2hsg(tl->start_msf);
1117         last = msf2hsg(toc.lead_out_start_msf);
1118         sc->data.blksize = SCDBLKSIZE;
1119         sc->data.disksize = last*sc->data.blksize/DEV_BSIZE;
1120
1121         XDEBUG(sc, 1, "firstsector = %ld, lastsector = %ld", first, last);
1122
1123         sc->data.first_track = bcd2bin(toc.first_track);
1124         sc->data.last_track = bcd2bin(toc.last_track);
1125         if (sc->data.last_track > (MAX_TRACKS-2))
1126                 sc->data.last_track = MAX_TRACKS-2;
1127         for (j = 0, i = sc->data.first_track; i <= sc->data.last_track; i++, j++) {
1128                 sc->data.toc[i].adr = tl[j].adr;
1129                 sc->data.toc[i].ctl = tl[j].ctl; /* for xcdplayer */
1130                 bcopy(tl[j].start_msf, sc->data.toc[i].start_msf, 3);
1131 #ifdef SCD_DEBUG
1132                 if (scd_debuglevel > 0) {
1133                         if ((j % 3) == 0) {
1134                                 printf("\n");
1135                                 device_printf(sc->dev, "tracks ");
1136                         }
1137                         printf("[%03d: %2d %2d %2d]  ", i,
1138                                 bcd2bin(sc->data.toc[i].start_msf[0]),
1139                                 bcd2bin(sc->data.toc[i].start_msf[1]),
1140                                 bcd2bin(sc->data.toc[i].start_msf[2]));
1141                 }
1142 #endif
1143         }
1144         bcopy(toc.lead_out_start_msf, sc->data.toc[sc->data.last_track+1].start_msf, 3);
1145 #ifdef SCD_DEBUG
1146         if (scd_debuglevel > 0) {
1147                 i = sc->data.last_track+1;
1148                 printf("[END: %2d %2d %2d]\n",
1149                         bcd2bin(sc->data.toc[i].start_msf[0]),
1150                         bcd2bin(sc->data.toc[i].start_msf[1]),
1151                         bcd2bin(sc->data.toc[i].start_msf[2]));
1152         }
1153 #endif
1154
1155         sc->data.flags |= SCDTOC;
1156
1157         return (0);
1158 }
1159
1160 static void
1161 init_drive(struct scd_softc *sc)
1162 {
1163         int rc;
1164
1165         rc = send_cmd(sc, CMD_SET_DRIVE_PARAM, 2,
1166                 0x05, 0x03 | ((sc->data.double_speed) ? 0x04: 0));
1167         if (rc != 0)
1168                 device_printf(sc->dev, "Unable to set parameters. Errcode = 0x%x\n", rc);
1169 }
1170
1171 /* Returns 0 or errno */
1172 static int
1173 get_result(struct scd_softc *sc, int result_len, u_char *result)
1174 {
1175         int loop_index = 2; /* send_cmd() reads two bytes ... */
1176
1177         XDEBUG(sc, 1, "DEBUG: get_result: bytes=%d\n", result_len);
1178
1179         while (result_len-- > 0) {
1180                 if (loop_index++ >= 10) {
1181                         loop_index = 1;
1182                         if (waitfor_status_bits(sc, SBIT_RESULT_READY, 0))
1183                                 return (EIO);
1184                         SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
1185                 }
1186                 if (result)
1187                         *result++ = SCD_READ(sc, IREG_RESULT);
1188                 else
1189                         (void)SCD_READ(sc, IREG_RESULT);
1190         }
1191         return (0);
1192 }
1193
1194 /* Returns -0x100 for timeout, -(drive error code) OR number of result bytes */
1195 static int
1196 send_cmd(struct scd_softc *sc, u_char cmd, u_int nargs, ...)
1197 {
1198         va_list ap;
1199         u_char c;
1200         int rc;
1201         int i;
1202
1203         if (waitfor_status_bits(sc, 0, SBIT_BUSY)) {
1204                 device_printf(sc->dev, "drive busy\n");
1205                 return (-0x100);
1206         }
1207
1208         XDEBUG(sc, 1, "DEBUG: send_cmd: cmd=0x%x nargs=%d", cmd, nargs);
1209
1210         SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
1211         SCD_WRITE(sc, OREG_CONTROL, CBIT_RPARAM_CLEAR);
1212
1213         for (i = 0; i < 100; i++)
1214                 if (FSTATUS_BIT(sc, FBIT_WPARAM_READY))
1215                         break;
1216         if (!FSTATUS_BIT(sc, FBIT_WPARAM_READY)) {
1217                 XDEBUG(sc, 1, "\nwparam timeout\n");
1218                 return (-EIO);
1219         }
1220
1221         va_start(ap, nargs);
1222         for (i = 0; i < nargs; i++) {
1223                 c = (u_char)va_arg(ap, int);
1224                 SCD_WRITE(sc, OREG_WPARAMS, c);
1225                 XDEBUG(sc, 1, ",{0x%x}", c);
1226         }
1227         va_end(ap);
1228         XDEBUG(sc, 1, "\n");
1229
1230         SCD_WRITE(sc, OREG_COMMAND, cmd);
1231
1232         rc = waitfor_status_bits(sc, SBIT_RESULT_READY, SBIT_BUSY);
1233         if (rc)
1234                 return (-0x100);
1235
1236         SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR);
1237         switch ((rc = SCD_READ(sc, IREG_RESULT)) & 0xf0) {
1238         case 0x20:
1239                 rc = SCD_READ(sc, IREG_RESULT);
1240                 /* FALLTHROUGH */
1241         case 0x50:
1242                 XDEBUG(sc, 1, "DEBUG: send_cmd: drive_error=0x%x\n", rc);
1243                 return (-rc);
1244         case 0x00:
1245         default:
1246                 rc = SCD_READ(sc, IREG_RESULT);
1247                 XDEBUG(sc, 1, "DEBUG: send_cmd: result_len=%d\n", rc);
1248                 return (rc);
1249         }
1250 }
1251
1252 static void
1253 print_error(struct scd_softc *sc, int errcode)
1254 {
1255
1256         switch (errcode) {
1257         case -ERR_CD_NOT_LOADED:
1258                 device_printf(sc->dev, "door is open\n");
1259                 break;
1260         case -ERR_NO_CD_INSIDE:
1261                 device_printf(sc->dev, "no cd inside\n");
1262                 break;
1263         default:
1264                 if (errcode == -0x100 || errcode > 0)
1265                         device_printf(sc->dev, "device timeout\n");
1266                 else
1267                         device_printf(sc->dev, "unexpected error 0x%x\n", -errcode);
1268                 break;
1269         }
1270 }
1271
1272 /* Returns 0 or errno value */
1273 static int
1274 waitfor_status_bits(struct scd_softc *sc, int bits_set, int bits_clear)
1275 {
1276         u_int flags = sc->data.flags;
1277         u_int max_loop;
1278         u_char c = 0;
1279
1280         if (flags & SCDPROBING) {
1281                 max_loop = 0;
1282                 while (max_loop++ < 1000) {
1283                         c = SCD_READ(sc, IREG_STATUS);
1284                         if (c == 0xff)
1285                                 return (EIO);
1286                         if (c & SBIT_ATTENTION) {
1287                                 process_attention(sc);
1288                                 continue;
1289                         }
1290                         if ((c & bits_set) == bits_set &&
1291                             (c & bits_clear) == 0)
1292                         {
1293                                 break;
1294                         }
1295                         DELAY(10000);
1296                 }
1297         } else {
1298                 max_loop = 100;
1299                 while (max_loop-- > 0) {
1300                         c = SCD_READ(sc, IREG_STATUS);
1301                         if (c & SBIT_ATTENTION) {
1302                                 process_attention(sc);
1303                                 continue;
1304                         }
1305                         if ((c & bits_set) == bits_set &&
1306                             (c & bits_clear) == 0)
1307                         {
1308                                 break;
1309                         }
1310                         SCD_UNLOCK(sc);
1311                         pause("waitfor", hz/10);
1312                         SCD_LOCK(sc);
1313                 }
1314         }
1315         if ((c & bits_set) == bits_set &&
1316             (c & bits_clear) == 0)
1317         {
1318                 return (0);
1319         }
1320 #ifdef SCD_DEBUG
1321         if (scd_debuglevel > 0)
1322                 device_printf(sc->dev, "DEBUG: waitfor: TIMEOUT (0x%x,(0x%x,0x%x))\n", c, bits_set, bits_clear);
1323         else
1324 #endif
1325                 device_printf(sc->dev, "timeout.\n");
1326         return (EIO);
1327 }
1328
1329 /* these two routines for xcdplayer - "borrowed" from mcd.c */
1330 static int
1331 scd_toc_header (struct scd_softc *sc, struct ioc_toc_header* th)
1332 {
1333         int rc;
1334
1335         if (!(sc->data.flags & SCDTOC) && (rc = read_toc(sc)) != 0) {
1336                 print_error(sc, rc);
1337                 return (EIO);
1338         }
1339
1340         th->starting_track = sc->data.first_track;
1341         th->ending_track = sc->data.last_track;
1342         th->len = 0; /* not used */
1343
1344         return (0);
1345 }
1346
1347 static int
1348 scd_toc_entrys (struct scd_softc *sc, struct ioc_read_toc_entry *te)
1349 {
1350         struct cd_toc_entry toc_entry;
1351         int rc, i, len = te->data_len;
1352
1353         if (!(sc->data.flags & SCDTOC) && (rc = read_toc(sc)) != 0) {
1354                 print_error(sc, rc);
1355                 return (EIO);
1356         }
1357
1358         /* find the toc to copy*/
1359         i = te->starting_track;
1360         if (i == SCD_LASTPLUS1)
1361                 i = sc->data.last_track + 1;
1362
1363         /* verify starting track */
1364         if (i < sc->data.first_track || i > sc->data.last_track+1)
1365                 return (EINVAL);
1366
1367         /* valid length ? */
1368         if (len < sizeof(struct cd_toc_entry)
1369             || (len % sizeof(struct cd_toc_entry)) != 0)
1370                 return (EINVAL);
1371
1372         /* copy the toc data */
1373         toc_entry.control = sc->data.toc[i].ctl;
1374         toc_entry.addr_type = te->address_format;
1375         toc_entry.track = i;
1376         if (te->address_format == CD_MSF_FORMAT) {
1377                 toc_entry.addr.msf.unused = 0;
1378                 toc_entry.addr.msf.minute = bcd2bin(sc->data.toc[i].start_msf[0]);
1379                 toc_entry.addr.msf.second = bcd2bin(sc->data.toc[i].start_msf[1]);
1380                 toc_entry.addr.msf.frame = bcd2bin(sc->data.toc[i].start_msf[2]);
1381         }
1382         SCD_UNLOCK(sc);
1383
1384         /* copy the data back */
1385         if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0)
1386                 return (EFAULT);
1387
1388         return (0);
1389 }
1390
1391
1392 static int
1393 scd_toc_entry (struct scd_softc *sc, struct ioc_read_toc_single_entry *te)
1394 {
1395         struct cd_toc_entry toc_entry;
1396         int rc, i;
1397
1398         if (!(sc->data.flags & SCDTOC) && (rc = read_toc(sc)) != 0) {
1399                 print_error(sc, rc);
1400                 return (EIO);
1401         }
1402
1403         /* find the toc to copy*/
1404         i = te->track;
1405         if (i == SCD_LASTPLUS1)
1406                 i = sc->data.last_track + 1;
1407
1408         /* verify starting track */
1409         if (i < sc->data.first_track || i > sc->data.last_track+1)
1410                 return (EINVAL);
1411
1412         /* copy the toc data */
1413         toc_entry.control = sc->data.toc[i].ctl;
1414         toc_entry.addr_type = te->address_format;
1415         toc_entry.track = i;
1416         if (te->address_format == CD_MSF_FORMAT) {
1417                 toc_entry.addr.msf.unused = 0;
1418                 toc_entry.addr.msf.minute = bcd2bin(sc->data.toc[i].start_msf[0]);
1419                 toc_entry.addr.msf.second = bcd2bin(sc->data.toc[i].start_msf[1]);
1420                 toc_entry.addr.msf.frame = bcd2bin(sc->data.toc[i].start_msf[2]);
1421         }
1422
1423         /* copy the data back */
1424         bcopy(&toc_entry, &te->entry, sizeof(struct cd_toc_entry));
1425
1426         return (0);
1427 }