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