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