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