xref: /netbsd-src/sys/dev/scsipi/cd.c (revision 705ee976cfe4e85b18732519865b1f7b6cbb2322)
1 /*	$NetBSD: cd.c,v 1.40 1994/10/30 21:49:14 cgd Exp $	*/
2 
3 /*
4  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Charles Hannum.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Originally written by Julian Elischer (julian@tfs.com)
34  * for TRW Financial Systems for use under the MACH(2.5) operating system.
35  *
36  * TRW Financial Systems, in accordance with their agreement with Carnegie
37  * Mellon University, makes this software available to CMU to distribute
38  * or use in any manner that they see fit as long as this message is kept with
39  * the software. For this reason TFS also grants any other persons or
40  * organisations permission to use or modify this software.
41  *
42  * TFS supplies this software to be publicly redistributed
43  * on the understanding that TFS is not responsible for the correct
44  * functioning of this software in any circumstances.
45  *
46  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
47  */
48 
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/dkbad.h>
54 #include <sys/conf.h>
55 #include <sys/file.h>
56 #include <sys/stat.h>
57 #include <sys/ioctl.h>
58 #include <sys/buf.h>
59 #include <sys/uio.h>
60 #include <sys/malloc.h>
61 #include <sys/errno.h>
62 #include <sys/device.h>
63 #include <sys/disklabel.h>
64 #include <sys/disk.h>
65 #include <sys/cdio.h>
66 
67 #include <scsi/scsi_all.h>
68 #include <scsi/scsi_cd.h>
69 #include <scsi/scsi_disk.h>	/* rw_big and start_stop come from there */
70 #include <scsi/scsiconf.h>
71 
72 #ifdef	DDB
73 int	Debugger();
74 #else	/* DDB */
75 #define Debugger()
76 #endif	/* DDB */
77 
78 #define	CDOUTSTANDING	2
79 #define	CDRETRIES	1
80 
81 #define	CDUNIT(z)			DISKUNIT(z)
82 #define	CDPART(z)			DISKPART(z)
83 #define	MAKECDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
84 
85 struct cd_data {
86 	struct device sc_dev;
87 	struct dkdevice sc_dk;
88 
89 	struct scsi_link *sc_link;	/* address of scsi low level switch */
90 	u_int32 ad_info;	/* info about the adapter */
91 	u_int32 cmdscount;	/* cmds allowed outstanding by board */
92 	struct cd_parms {
93 		u_int32 blksize;
94 		u_long disksize;	/* total number sectors */
95 	} params;
96 	u_int32 xfer_block_wait;
97 	struct buf buf_queue;
98 };
99 
100 void cdattach __P((struct device *, struct device *, void *));
101 
102 struct cfdriver cdcd = {
103 	NULL, "cd", scsi_targmatch, cdattach, DV_DISK, sizeof(struct cd_data)
104 };
105 
106 int cdgetdisklabel __P((struct cd_data *));
107 int cd_get_parms __P((struct cd_data *, int));
108 void cdstrategy __P((struct buf *));
109 void cdstart __P((int));
110 
111 struct dkdriver cddkdriver = { cdstrategy };
112 
113 struct scsi_device cd_switch = {
114 	NULL,			/* use default error handler */
115 	cdstart,		/* we have a queue, which is started by this */
116 	NULL,			/* we do not have an async handler */
117 	NULL,			/* use default 'done' routine */
118 	"cd",			/* we are to be refered to by this name */
119 	0			/* no device specific flags */
120 };
121 
122 #define CD_STOP		0
123 #define CD_START	1
124 #define CD_EJECT	-2
125 
126 /*
127  * The routine called by the low level scsi routine when it discovers
128  * A device suitable for this driver
129  */
130 void
131 cdattach(parent, self, aux)
132 	struct device *parent, *self;
133 	void *aux;
134 {
135 	struct cd_data *cd = (void *)self;
136 	struct cd_parms *dp = &cd->params;
137 	struct scsi_link *sc_link = aux;
138 
139 	SC_DEBUG(sc_link, SDEV_DB2, ("cdattach: "));
140 
141 	/*
142 	 * Store information needed to contact our base driver
143 	 */
144 	cd->sc_link = sc_link;
145 	sc_link->device = &cd_switch;
146 	sc_link->dev_unit = cd->sc_dev.dv_unit;
147 
148 	cd->sc_dk.dk_driver = &cddkdriver;
149 #if !defined(i386) || defined(NEWCONFIG)
150 	dk_establish(&cd->sc_dk, &cd->sc_dev);
151 #endif
152 
153 	if (cd->sc_link->adapter->adapter_info) {
154 		cd->ad_info = ((*(cd->sc_link->adapter->adapter_info)) (sc_link->adapter_softc));
155 		cd->cmdscount = cd->ad_info & AD_INF_MAX_CMDS;
156 		if (cd->cmdscount > CDOUTSTANDING)
157 			cd->cmdscount = CDOUTSTANDING;
158 	} else {
159 		cd->ad_info = 1;
160 		cd->cmdscount = 1;
161 	}
162 	sc_link->opennings = cd->cmdscount;
163 
164 	/*
165 	 * Use the subdriver to request information regarding
166 	 * the drive. We cannot use interrupts yet, so the
167 	 * request must specify this.
168 	 */
169 	cd_get_parms(cd, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT);
170 	if (dp->disksize)
171 		printf(": cd present, %d x %d byte records\n",
172 		    cd->params.disksize, cd->params.blksize);
173 	else
174 		printf(": drive empty\n");
175 }
176 
177 /*
178  * open the device. Make sure the partition info is a up-to-date as can be.
179  */
180 int
181 cdopen(dev, flag, fmt, p)
182 	dev_t dev;
183 	int flag, fmt;
184 	struct proc *p;
185 {
186 	int error = 0;
187 	int unit, part;
188 	struct cd_data *cd;
189 	struct scsi_link *sc_link;
190 
191 	unit = CDUNIT(dev);
192 	part = CDPART(dev);
193 
194 	if (unit >= cdcd.cd_ndevs)
195 		return ENXIO;
196 	cd = cdcd.cd_devs[unit];
197 	if (!cd)
198 		return ENXIO;
199 
200 	sc_link = cd->sc_link;
201 
202 	SC_DEBUG(sc_link, SDEV_DB1,
203 	    ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
204 	    cdcd.cd_ndevs, part));
205 
206 	/*
207 	 * If it's been invalidated, and not everybody has closed it then
208 	 * forbid re-entry.  (may have changed media)
209 	 */
210 	if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0 &&
211 	    cd->sc_dk.dk_openmask != 0)
212 		return ENXIO;
213 
214 	/*
215 	 * Check that it is still responding and ok.
216 	 * if the media has been changed this will result in a
217 	 * "unit attention" error which the error code will
218 	 * disregard because the SDEV_MEDIA_LOADED flag is not yet set
219 	 */
220 	scsi_test_unit_ready(sc_link, SCSI_SILENT);
221 
222 	/*
223 	 * In case it is a funny one, tell it to start
224 	 * not needed for some drives
225 	 */
226 	scsi_start(sc_link, SSS_START, SCSI_ERR_OK | SCSI_SILENT);
227 
228 	/*
229 	 * Next time actually take notice of error returns
230 	 */
231 	sc_link->flags |= SDEV_OPEN;	/* unit attn errors are now errors */
232 	if (scsi_test_unit_ready(sc_link, 0) != 0) {
233 		SC_DEBUG(sc_link, SDEV_DB3, ("device not responding\n"));
234 		error = ENXIO;
235 		goto bad;
236 	}
237 	SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
238 
239 	/* Lock the pack in. */
240 	scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
241 
242 	/*
243 	 * Load the physical device parameters
244 	 */
245 	if (cd_get_parms(cd, 0)) {
246 		error = ENXIO;
247 		goto bad;
248 	}
249 	SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
250 
251 	/*
252 	 * Make up some partition information
253 	 */
254 	cdgetdisklabel(cd);
255 	SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated "));
256 
257 	/*
258 	 *  Check that the partition exists
259 	 */
260 	if (part != RAW_PART &&
261 	    (part >= cd->sc_dk.dk_label.d_npartitions ||
262 	     cd->sc_dk.dk_label.d_partitions[part].p_fstype == FS_UNUSED)) {
263 		error = ENXIO;
264 		goto bad;
265 	}
266 
267 	/* Insure only one open at a time. */
268 	switch (fmt) {
269 	case S_IFCHR:
270 		cd->sc_dk.dk_copenmask |= (1 << part);
271 		break;
272 	case S_IFBLK:
273 		cd->sc_dk.dk_bopenmask |= (1 << part);
274 		break;
275 	}
276 	cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
277 
278 	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
279 	sc_link->flags |= SDEV_MEDIA_LOADED;
280 	return 0;
281 
282 bad:
283 	if (cd->sc_dk.dk_openmask == 0) {
284 		scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
285 		sc_link->flags &= ~SDEV_OPEN;
286 	}
287 	return error;
288 }
289 
290 /*
291  * close the device.. only called if we are the LAST
292  * occurence of an open device
293  */
294 int
295 cdclose(dev, flag, fmt)
296 	dev_t dev;
297 	int flag, fmt;
298 {
299 	struct cd_data *cd = cdcd.cd_devs[CDUNIT(dev)];
300 	int part = CDPART(dev);
301 
302 	switch (fmt) {
303 	case S_IFCHR:
304 		cd->sc_dk.dk_copenmask &= ~(1 << part);
305 		break;
306 	case S_IFBLK:
307 		cd->sc_dk.dk_bopenmask &= ~(1 << part);
308 		break;
309 	}
310 	cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
311 
312 	if (cd->sc_dk.dk_openmask == 0) {
313 		scsi_prevent(cd->sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
314 		cd->sc_link->flags &= ~SDEV_OPEN;
315 	}
316 	return 0;
317 }
318 
319 /*
320  * trim the size of the transfer if needed,
321  * called by physio
322  * basically the smaller of our max and the scsi driver's
323  * minphys (note we have no max ourselves)
324  *
325  * Trim buffer length if buffer-size is bigger than page size
326  */
327 void
328 cdminphys(bp)
329 	struct buf *bp;
330 {
331 	register struct cd_data *cd = cdcd.cd_devs[CDUNIT(bp->b_dev)];
332 
333 	(cd->sc_link->adapter->scsi_minphys) (bp);
334 }
335 
336 /*
337  * Actually translate the requested transfer into one the physical driver can
338  * understand.  The transfer is described by a buf and will include only one
339  * physical transfer.
340  */
341 void
342 cdstrategy(bp)
343 	struct buf *bp;
344 {
345 	int opri;
346 	struct cd_data *cd;
347 	int unit;
348 
349 	unit = CDUNIT(bp->b_dev);
350 	cd = cdcd.cd_devs[unit];
351 	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdstrategy "));
352 	SC_DEBUG(cd->sc_link, SDEV_DB1,
353 	    ("%d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
354 	cdminphys(bp);
355 	/*
356 	 * If the device has been made invalid, error out
357 	 * maybe the media changed
358 	 */
359 	if (!(cd->sc_link->flags & SDEV_MEDIA_LOADED)) {
360 		bp->b_error = EIO;
361 		goto bad;
362 	}
363 	/*
364 	 * can't ever write to a CD
365 	 */
366 	if ((bp->b_flags & B_READ) == 0) {
367 		bp->b_error = EROFS;
368 		goto bad;
369 	}
370 	/*
371 	 * If it's a null transfer, return immediately
372 	 */
373 	if (bp->b_bcount == 0)
374 		goto done;
375 	/*
376 	 * Decide which unit and partition we are talking about
377 	 */
378 	if (CDPART(bp->b_dev) != RAW_PART) {
379 		/*
380 		 * do bounds checking, adjust transfer. if error, process.
381 		 * if end of partition, just return
382 		 */
383 		if (bounds_check_with_label(bp, &cd->sc_dk.dk_label, 1) <= 0)
384 			goto done;
385 		/* otherwise, process transfer request */
386 	}
387 
388 	opri = splbio();
389 
390 	/*
391 	 * Place it in the queue of disk activities for this disk
392 	 */
393 	disksort(&cd->buf_queue, bp);
394 
395 	/*
396 	 * Tell the device to get going on the transfer if it's
397 	 * not doing anything, otherwise just wait for completion
398 	 */
399 	cdstart(unit);
400 
401 	splx(opri);
402 	return;
403 
404 bad:
405 	bp->b_flags |= B_ERROR;
406 done:
407 	/*
408 	 * Correctly set the buf to indicate a completed xfer
409 	 */
410 	bp->b_resid = bp->b_bcount;
411 	biodone(bp);
412 }
413 
414 /*
415  * cdstart looks to see if there is a buf waiting for the device
416  * and that the device is not already busy. If both are true,
417  * It deques the buf and creates a scsi command to perform the
418  * transfer in the buf. The transfer request will call scsi_done
419  * on completion, which will in turn call this routine again
420  * so that the next queued transfer is performed.
421  * The bufs are queued by the strategy routine (cdstrategy)
422  *
423  * This routine is also called after other non-queued requests
424  * have been made of the scsi driver, to ensure that the queue
425  * continues to be drained.
426  *
427  * must be called at the correct (highish) spl level
428  * cdstart() is called at splbio from cdstrategy and scsi_done
429  */
430 void
431 cdstart(unit)
432 	int unit;
433 {
434 	register struct cd_data *cd = cdcd.cd_devs[unit];
435 	register struct scsi_link *sc_link = cd->sc_link;
436 	struct buf *bp = 0;
437 	struct buf *dp;
438 	struct scsi_rw_big cmd;
439 	int blkno, nblks;
440 	struct partition *p;
441 
442 	SC_DEBUG(sc_link, SDEV_DB2, ("cdstart "));
443 	/*
444 	 * See if there is a buf to do and we are not already
445 	 * doing one
446 	 */
447 	while (sc_link->opennings) {
448 		/*
449 		 * there is excess capacity, but a special waits
450 		 * It'll need the adapter as soon as we clear out of the
451 		 * way and let it run (user level wait).
452 		 */
453 		if (sc_link->flags & SDEV_WAITING) {
454 			sc_link->flags &= ~SDEV_WAITING;
455 			wakeup((caddr_t)sc_link);
456 			return;
457 		}
458 
459 		/*
460 		 * See if there is a buf with work for us to do..
461 		 */
462 		dp = &cd->buf_queue;
463 		if ((bp = dp->b_actf) == NULL)	/* yes, an assign */
464 			return;
465 		dp->b_actf = bp->b_actf;
466 
467 		/*
468 		 * If the deivce has become invalid, abort all the
469 		 * reads and writes until all files have been closed and
470 		 * re-openned
471 		 */
472 		if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
473 			bp->b_error = EIO;
474 			bp->b_flags |= B_ERROR;
475 			biodone(bp);
476 			continue;
477 		}
478 
479 		/*
480 		 * We have a buf, now we should make a command
481 		 *
482 		 * First, translate the block to absolute and put it in terms
483 		 * of the logical blocksize of the device.  Really a bit silly
484 		 * until we have real partitions, but.
485 		 */
486 		blkno =
487 		    bp->b_blkno / (cd->sc_dk.dk_label.d_secsize / DEV_BSIZE);
488 		if (CDPART(bp->b_dev) != RAW_PART) {
489 			p = &cd->sc_dk.dk_label.d_partitions[CDPART(bp->b_dev)];
490 			blkno += p->p_offset;
491 		}
492 		nblks = howmany(bp->b_bcount, cd->sc_dk.dk_label.d_secsize);
493 
494 		/*
495 		 *  Fill out the scsi command
496 		 */
497 		bzero(&cmd, sizeof(cmd));
498 		cmd.op_code = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG;
499 		cmd.addr_3 = (blkno & 0xff000000) >> 24;
500 		cmd.addr_2 = (blkno & 0xff0000) >> 16;
501 		cmd.addr_1 = (blkno & 0xff00) >> 8;
502 		cmd.addr_0 = blkno & 0xff;
503 		cmd.length2 = (nblks & 0xff00) >> 8;
504 		cmd.length1 = (nblks & 0xff);
505 
506 		/*
507 		 * Call the routine that chats with the adapter.
508 		 * Note: we cannot sleep as we may be an interrupt
509 		 */
510 		if (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&cmd,
511 		    sizeof(cmd), (u_char *) bp->b_data, bp->b_bcount,
512 		    CDRETRIES, 30000, bp, SCSI_NOSLEEP |
513 		    ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))
514 		    != SUCCESSFULLY_QUEUED)
515 			printf("%s: not queued", cd->sc_dev.dv_xname);
516 	}
517 }
518 
519 /*
520  * Perform special action on behalf of the user.
521  * Knows about the internals of this device
522  */
523 int
524 cdioctl(dev, cmd, addr, flag)
525 	dev_t dev;
526 	u_long cmd;
527 	caddr_t addr;
528 	int flag;
529 {
530 	int error;
531 	int unit, part;
532 	register struct cd_data *cd;
533 
534 	/*
535 	 * Find the device that the user is talking about
536 	 */
537 	unit = CDUNIT(dev);
538 	part = CDPART(dev);
539 	cd = cdcd.cd_devs[unit];
540 	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdioctl 0x%x ", cmd));
541 
542 	/*
543 	 * If the device is not valid.. abandon ship
544 	 */
545 	if (!(cd->sc_link->flags & SDEV_MEDIA_LOADED))
546 		return EIO;
547 
548 	switch (cmd) {
549 	case DIOCSBAD:
550 		return EINVAL;
551 
552 	case DIOCGDINFO:
553 		*(struct disklabel *)addr = cd->sc_dk.dk_label;
554 		return 0;
555 
556 	case DIOCGPART:
557 		((struct partinfo *)addr)->disklab = &cd->sc_dk.dk_label;
558 		((struct partinfo *)addr)->part =
559 		    &cd->sc_dk.dk_label.d_partitions[CDPART(dev)];
560 		return 0;
561 
562 		/*
563 		 * a bit silly, but someone might want to test something on a
564 		 * section of cdrom.
565 		 */
566 	case DIOCWDINFO:
567 	case DIOCSDINFO:
568 		if ((flag & FWRITE) == 0)
569 			return EBADF;
570 		error = setdisklabel(&cd->sc_dk.dk_label,
571 		    (struct disklabel *)addr, 0, (struct cpu_disklabel *)0);
572 		return error;
573 
574 	case DIOCWLABEL:
575 		return EBADF;
576 
577 	case CDIOCPLAYTRACKS: {
578 		struct ioc_play_track *args = (struct ioc_play_track *)addr;
579 		struct cd_mode_data data;
580 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
581 			return error;
582 		data.page.audio.flags &= ~CD_PA_SOTC;
583 		data.page.audio.flags |= CD_PA_IMMED;
584 		if (error = cd_set_mode(cd, &data))
585 			return error;
586 		return cd_play_tracks(cd, args->start_track, args->start_index,
587 		    args->end_track, args->end_index);
588 	}
589 	case CDIOCPLAYMSF: {
590 		struct ioc_play_msf *args
591 		= (struct ioc_play_msf *)addr;
592 		struct cd_mode_data data;
593 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
594 			return error;
595 		data.page.audio.flags &= ~CD_PA_SOTC;
596 		data.page.audio.flags |= CD_PA_IMMED;
597 		if (error = cd_set_mode(cd, &data))
598 			return error;
599 		return cd_play_msf(cd, args->start_m, args->start_s,
600 		    args->start_f, args->end_m, args->end_s, args->end_f);
601 	}
602 	case CDIOCPLAYBLOCKS: {
603 		struct ioc_play_blocks *args
604 		= (struct ioc_play_blocks *)addr;
605 		struct cd_mode_data data;
606 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
607 			return error;
608 		data.page.audio.flags &= ~CD_PA_SOTC;
609 		data.page.audio.flags |= CD_PA_IMMED;
610 		if (error = cd_set_mode(cd, &data))
611 			return error;
612 		return cd_play(cd, args->blk, args->len);
613 	}
614 	case CDIOCREADSUBCHANNEL: {
615 		struct ioc_read_subchannel *args
616 		= (struct ioc_read_subchannel *)addr;
617 		struct cd_sub_channel_info data;
618 		u_int32 len = args->data_len;
619 		if (len > sizeof(data) ||
620 		    len < sizeof(struct cd_sub_channel_header))
621 			return EINVAL;
622 		if (error = cd_read_subchannel(cd, args->address_format,
623 		    args->data_format, args->track, &data, len))
624 			return error;
625 		len = min(len, ((data.header.data_len[0] << 8) +
626 		    data.header.data_len[1] +
627 		    sizeof(struct cd_sub_channel_header)));
628 		return copyout(&data, args->data, len);
629 	}
630 	case CDIOREADTOCHEADER: {
631 		struct ioc_toc_header th;
632 		if (error = cd_read_toc(cd, 0, 0, &th, sizeof(th)))
633 			return error;
634 		th.len = ntohs(th.len);
635 		bcopy(&th, addr, sizeof(th));
636 		return 0;
637 	}
638 	case CDIOREADTOCENTRYS: {
639 		struct cd_toc {
640 			struct ioc_toc_header header;
641 			struct cd_toc_entry entries[65];
642 		} data;
643 		struct ioc_read_toc_entry *te =
644 		(struct ioc_read_toc_entry *)addr;
645 		struct ioc_toc_header *th;
646 		u_int32 len = te->data_len;
647 		th = &data.header;
648 
649 		if (len > sizeof(data.entries) ||
650 		    len < sizeof(struct cd_toc_entry))
651 			return EINVAL;
652 		if (error = cd_read_toc(cd, te->address_format,
653 		    te->starting_track, (struct cd_toc_entry *)&data,
654 		    len + sizeof(struct ioc_toc_header)))
655 			return error;
656 		len = min(len, ntohs(th->len) - (sizeof(th->starting_track) +
657 		    sizeof(th->ending_track)));
658 		return copyout(data.entries, te->data, len);
659 	}
660 	case CDIOCSETPATCH: {
661 		struct ioc_patch *arg = (struct ioc_patch *)addr;
662 		struct cd_mode_data data;
663 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
664 			return error;
665 		data.page.audio.port[LEFT_PORT].channels = arg->patch[0];
666 		data.page.audio.port[RIGHT_PORT].channels = arg->patch[1];
667 		data.page.audio.port[2].channels = arg->patch[2];
668 		data.page.audio.port[3].channels = arg->patch[3];
669 		return cd_set_mode(cd, &data);
670 	}
671 	case CDIOCGETVOL: {
672 		struct ioc_vol *arg = (struct ioc_vol *)addr;
673 		struct cd_mode_data data;
674 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
675 			return error;
676 		arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
677 		arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
678 		arg->vol[2] = data.page.audio.port[2].volume;
679 		arg->vol[3] = data.page.audio.port[3].volume;
680 		return 0;
681 	}
682 	case CDIOCSETVOL: {
683 		struct ioc_vol *arg = (struct ioc_vol *)addr;
684 		struct cd_mode_data data;
685 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
686 			return error;
687 		data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
688 		data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
689 		data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
690 		data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
691 		data.page.audio.port[2].volume = arg->vol[2];
692 		data.page.audio.port[3].volume = arg->vol[3];
693 		return cd_set_mode(cd, &data);
694 	}
695 	case CDIOCSETMONO: {
696 		struct ioc_vol *arg = (struct ioc_vol *)addr;
697 		struct cd_mode_data data;
698 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
699 			return error;
700 		data.page.audio.port[LEFT_PORT].channels =
701 		    LEFT_CHANNEL | RIGHT_CHANNEL | 4 | 8;
702 		data.page.audio.port[RIGHT_PORT].channels =
703 		    LEFT_CHANNEL | RIGHT_CHANNEL;
704 		data.page.audio.port[2].channels = 0;
705 		data.page.audio.port[3].channels = 0;
706 		return cd_set_mode(cd, &data);
707 	}
708 	case CDIOCSETSTEREO: {
709 		struct ioc_vol *arg = (struct ioc_vol *)addr;
710 		struct cd_mode_data data;
711 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
712 			return error;
713 		data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
714 		data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
715 		data.page.audio.port[2].channels = 0;
716 		data.page.audio.port[3].channels = 0;
717 		return cd_set_mode(cd, &data);
718 	}
719 	case CDIOCSETMUTE: {
720 		struct ioc_vol *arg = (struct ioc_vol *)addr;
721 		struct cd_mode_data data;
722 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
723 			return error;
724 		data.page.audio.port[LEFT_PORT].channels = 0;
725 		data.page.audio.port[RIGHT_PORT].channels = 0;
726 		data.page.audio.port[2].channels = 0;
727 		data.page.audio.port[3].channels = 0;
728 		return cd_set_mode(cd, &data);
729 	}
730 	case CDIOCSETLEFT: {
731 		struct ioc_vol *arg = (struct ioc_vol *)addr;
732 		struct cd_mode_data data;
733 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
734 			return error;
735 		data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
736 		data.page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL;
737 		data.page.audio.port[2].channels = 0;
738 		data.page.audio.port[3].channels = 0;
739 		return cd_set_mode(cd, &data);
740 	}
741 	case CDIOCSETRIGHT: {
742 		struct ioc_vol *arg = (struct ioc_vol *)addr;
743 		struct cd_mode_data data;
744 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
745 			return error;
746 		data.page.audio.port[LEFT_PORT].channels = RIGHT_CHANNEL;
747 		data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
748 		data.page.audio.port[2].channels = 0;
749 		data.page.audio.port[3].channels = 0;
750 		return cd_set_mode(cd, &data);
751 	}
752 	case CDIOCRESUME:
753 		return cd_pause(cd, 1);
754 	case CDIOCPAUSE:
755 		return cd_pause(cd, 0);
756 	case CDIOCSTART:
757 		return scsi_start(cd->sc_link, SSS_START, 0);
758 	case CDIOCSTOP:
759 		return scsi_start(cd->sc_link, SSS_STOP, 0);
760 	case CDIOCEJECT:
761 		return scsi_start(cd->sc_link, SSS_LOEJ, 0);
762 	case CDIOCALLOW:
763 		return scsi_prevent(cd->sc_link, PR_ALLOW, 0);
764 	case CDIOCPREVENT:
765 		return scsi_prevent(cd->sc_link, PR_PREVENT, 0);
766 	case CDIOCSETDEBUG:
767 		cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2);
768 		return 0;
769 	case CDIOCCLRDEBUG:
770 		cd->sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2);
771 		return 0;
772 	case CDIOCRESET:
773 		return cd_reset(cd);
774 	default:
775 		if (part != RAW_PART)
776 			return ENOTTY;
777 		return scsi_do_ioctl(cd->sc_link, dev, cmd, addr, flag);
778 	}
779 #ifdef DIAGNOSTIC
780 	panic("cdioctl: impossible");
781 #endif
782 }
783 
784 /*
785  * Load the label information on the named device
786  * Actually fabricate a disklabel
787  *
788  * EVENTUALLY take information about different
789  * data tracks from the TOC and put it in the disklabel
790  */
791 int
792 cdgetdisklabel(cd)
793 	struct cd_data *cd;
794 {
795 	char *errstring;
796 
797 	bzero(&cd->sc_dk.dk_label, sizeof(struct disklabel));
798 	bzero(&cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
799 	/*
800 	 * make partition 0 the whole disk
801 	 * remember that comparisons with the partition are done
802 	 * assuming the blocks are 512 bytes so fudge it.
803 	 */
804 	cd->sc_dk.dk_label.d_partitions[0].p_offset = 0;
805 	cd->sc_dk.dk_label.d_partitions[0].p_size =
806 	    cd->params.disksize * (cd->params.blksize / DEV_BSIZE);
807 	cd->sc_dk.dk_label.d_partitions[0].p_fstype = FS_ISO9660;
808 	cd->sc_dk.dk_label.d_npartitions = 1;
809 
810 	cd->sc_dk.dk_label.d_secsize = cd->params.blksize;
811 	cd->sc_dk.dk_label.d_ntracks = 1;
812 	cd->sc_dk.dk_label.d_nsectors = 100;
813 	cd->sc_dk.dk_label.d_ncylinders = (cd->params.disksize / 100) + 1;
814 	cd->sc_dk.dk_label.d_secpercyl = 100;
815 
816 	strncpy(cd->sc_dk.dk_label.d_typename, "scsi cd_rom", 16);
817 	strncpy(cd->sc_dk.dk_label.d_packname, "ficticious", 16);
818 	cd->sc_dk.dk_label.d_secperunit = cd->params.disksize;
819 	cd->sc_dk.dk_label.d_rpm = 300;
820 	cd->sc_dk.dk_label.d_interleave = 1;
821 	cd->sc_dk.dk_label.d_flags = D_REMOVABLE;
822 	cd->sc_dk.dk_label.d_magic = DISKMAGIC;
823 	cd->sc_dk.dk_label.d_magic2 = DISKMAGIC;
824 	cd->sc_dk.dk_label.d_checksum = dkcksum(&cd->sc_dk.dk_label);
825 
826 	/*
827 	 * Signal to other users and routines that we now have a
828 	 * disklabel that represents the media (maybe)
829 	 */
830 	return 0;
831 }
832 
833 /*
834  * Find out from the device what it's capacity is
835  */
836 u_int32
837 cd_size(cd, flags)
838 	struct cd_data *cd;
839 	int flags;
840 {
841 	struct scsi_read_cd_cap_data rdcap;
842 	struct scsi_read_cd_capacity scsi_cmd;
843 	u_int32 size, blksize;
844 	int error;
845 
846 	/*
847 	 * make up a scsi command and ask the scsi driver to do
848 	 * it for you.
849 	 */
850 	bzero(&scsi_cmd, sizeof(scsi_cmd));
851 	scsi_cmd.op_code = READ_CD_CAPACITY;
852 
853 	/*
854 	 * If the command works, interpret the result as a 4 byte
855 	 * number of blocks and a blocksize
856 	 */
857 	error = scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
858 	    sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), CDRETRIES,
859 	    20000, NULL, SCSI_DATA_IN | flags);
860 	if (error == EBUSY) {
861 		if (!(flags & SCSI_SILENT))
862 			printf("%s: waiting for drive to spin up\n",
863 			    cd->sc_dev.dv_xname);
864 		if (flags & SCSI_NOSLEEP)
865 			delay(2000000);
866 		else
867 			tsleep(cd, PRIBIO + 1, "cd_size", 2 * hz);
868 		error = scsi_scsi_cmd(cd->sc_link,
869 		    (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd),
870 		    (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 20000, NULL,
871 		    SCSI_DATA_IN | flags);
872 	}
873 
874 	if (error) {
875 		if (!(flags & SCSI_SILENT))
876 			printf("%s: could not get size\n",
877 			    cd->sc_dev.dv_xname);
878 		return 0;
879 	}
880 
881 	blksize = (rdcap.length_3 << 24) + (rdcap.length_2 << 16) +
882 	    (rdcap.length_1 << 8) + rdcap.length_0;
883 	if (blksize < 512)
884 		blksize = 2048;	/* some drives lie ! */
885 	cd->params.blksize = blksize;
886 
887 	size = (rdcap.addr_3 << 24) + (rdcap.addr_2 << 16) +
888 	    (rdcap.addr_1 << 8) + rdcap.addr_0 + 1;
889 	if (size < 100)
890 		size = 400000;	/* ditto */
891 	cd->params.disksize = size;
892 
893 	return size;
894 }
895 
896 /*
897  * Get the requested page into the buffer given
898  */
899 int
900 cd_get_mode(cd, data, page)
901 	struct cd_data *cd;
902 	struct cd_mode_data *data;
903 	int page;
904 {
905 	struct scsi_mode_sense scsi_cmd;
906 	int error;
907 
908 	bzero(&scsi_cmd, sizeof(scsi_cmd));
909 	bzero(data, sizeof(*data));
910 	scsi_cmd.op_code = MODE_SENSE;
911 	scsi_cmd.page = page;
912 	scsi_cmd.length = sizeof(*data) & 0xff;
913 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
914 	    sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000,
915 	    NULL, SCSI_DATA_IN);
916 }
917 
918 /*
919  * Get the requested page into the buffer given
920  */
921 int
922 cd_set_mode(cd, data)
923 	struct cd_data *cd;
924 	struct cd_mode_data *data;
925 {
926 	struct scsi_mode_select scsi_cmd;
927 
928 	bzero(&scsi_cmd, sizeof(scsi_cmd));
929 	scsi_cmd.op_code = MODE_SELECT;
930 	scsi_cmd.byte2 |= SMS_PF;
931 	scsi_cmd.length = sizeof(*data) & 0xff;
932 	data->header.data_length = 0;
933 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
934 	    sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000,
935 	    NULL, SCSI_DATA_OUT);
936 }
937 
938 /*
939  * Get scsi driver to send a "start playing" command
940  */
941 int
942 cd_play(cd, blkno, nblks)
943 	struct cd_data *cd;
944 	int blkno, nblks;
945 {
946 	struct scsi_play scsi_cmd;
947 
948 	bzero(&scsi_cmd, sizeof(scsi_cmd));
949 	scsi_cmd.op_code = PLAY;
950 	scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
951 	scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
952 	scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
953 	scsi_cmd.blk_addr[3] = blkno & 0xff;
954 	scsi_cmd.xfer_len[0] = (nblks >> 8) & 0xff;
955 	scsi_cmd.xfer_len[1] = nblks & 0xff;
956 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
957 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 200000, NULL, 0);
958 }
959 
960 /*
961  * Get scsi driver to send a "start playing" command
962  */
963 int
964 cd_play_big(cd, blkno, nblks)
965 	struct cd_data *cd;
966 	int blkno, nblks;
967 {
968 	struct scsi_play_big scsi_cmd;
969 
970 	bzero(&scsi_cmd, sizeof(scsi_cmd));
971 	scsi_cmd.op_code = PLAY_BIG;
972 	scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
973 	scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
974 	scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
975 	scsi_cmd.blk_addr[3] = blkno & 0xff;
976 	scsi_cmd.xfer_len[0] = (nblks >> 24) & 0xff;
977 	scsi_cmd.xfer_len[1] = (nblks >> 16) & 0xff;
978 	scsi_cmd.xfer_len[2] = (nblks >> 8) & 0xff;
979 	scsi_cmd.xfer_len[3] = nblks & 0xff;
980 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
981 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
982 }
983 
984 /*
985  * Get scsi driver to send a "start playing" command
986  */
987 int
988 cd_play_tracks(cd, strack, sindex, etrack, eindex)
989 	struct cd_data *cd;
990 	int strack, sindex, etrack, eindex;
991 {
992 	struct scsi_play_track scsi_cmd;
993 
994 	bzero(&scsi_cmd, sizeof(scsi_cmd));
995 	scsi_cmd.op_code = PLAY_TRACK;
996 	scsi_cmd.start_track = strack;
997 	scsi_cmd.start_index = sindex;
998 	scsi_cmd.end_track = etrack;
999 	scsi_cmd.end_index = eindex;
1000 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1001 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
1002 }
1003 
1004 /*
1005  * Get scsi driver to send a "play msf" command
1006  */
1007 int
1008 cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
1009 	struct cd_data *cd;
1010 	int startm, starts, startf, endm, ends, endf;
1011 {
1012 	struct scsi_play_msf scsi_cmd;
1013 
1014 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1015 	scsi_cmd.op_code = PLAY_MSF;
1016 	scsi_cmd.start_m = startm;
1017 	scsi_cmd.start_s = starts;
1018 	scsi_cmd.start_f = startf;
1019 	scsi_cmd.end_m = endm;
1020 	scsi_cmd.end_s = ends;
1021 	scsi_cmd.end_f = endf;
1022 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1023 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
1024 }
1025 
1026 /*
1027  * Get scsi driver to send a "start up" command
1028  */
1029 int
1030 cd_pause(cd, go)
1031 	struct cd_data *cd;
1032 	int go;
1033 {
1034 	struct scsi_pause scsi_cmd;
1035 
1036 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1037 	scsi_cmd.op_code = PAUSE;
1038 	scsi_cmd.resume = go;
1039 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1040 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
1041 }
1042 
1043 /*
1044  * Get scsi driver to send a "RESET" command
1045  */
1046 int
1047 cd_reset(cd)
1048 	struct cd_data *cd;
1049 {
1050 
1051 	return scsi_scsi_cmd(cd->sc_link, 0, 0, 0, 0, CDRETRIES, 2000, NULL,
1052 	    SCSI_RESET);
1053 }
1054 
1055 /*
1056  * Read subchannel
1057  */
1058 int
1059 cd_read_subchannel(cd, mode, format, track, data, len)
1060 	struct cd_data *cd;
1061 	int mode, format, len;
1062 	struct cd_sub_channel_info *data;
1063 {
1064 	struct scsi_read_subchannel scsi_cmd;
1065 
1066 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1067 	scsi_cmd.op_code = READ_SUBCHANNEL;
1068 	if (mode == CD_MSF_FORMAT)
1069 		scsi_cmd.byte2 |= CD_MSF;
1070 	scsi_cmd.byte3 = SRS_SUBQ;
1071 	scsi_cmd.subchan_format = format;
1072 	scsi_cmd.track = track;
1073 	scsi_cmd.data_len[0] = (len) >> 8;
1074 	scsi_cmd.data_len[1] = (len) & 0xff;
1075 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1076 	    sizeof(struct scsi_read_subchannel), (u_char *)data, len,
1077 	    CDRETRIES, 5000, NULL, SCSI_DATA_IN);
1078 }
1079 
1080 /*
1081  * Read table of contents
1082  */
1083 int
1084 cd_read_toc(cd, mode, start, data, len)
1085 	struct cd_data *cd;
1086 	int mode, start, len;
1087 	struct cd_toc_entry *data;
1088 {
1089 	struct scsi_read_toc scsi_cmd;
1090 	int ntoc;
1091 
1092 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1093 	/*if (len!=sizeof(struct ioc_toc_header))
1094 	 * ntoc=((len)-sizeof(struct ioc_toc_header))/sizeof(struct cd_toc_entry);
1095 	 * else */
1096 	ntoc = len;
1097 	scsi_cmd.op_code = READ_TOC;
1098 	if (mode == CD_MSF_FORMAT)
1099 		scsi_cmd.byte2 |= CD_MSF;
1100 	scsi_cmd.from_track = start;
1101 	scsi_cmd.data_len[0] = (ntoc) >> 8;
1102 	scsi_cmd.data_len[1] = (ntoc) & 0xff;
1103 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1104 	    sizeof(struct scsi_read_toc), (u_char *)data, len, CDRETRIES,
1105 	    5000, NULL, SCSI_DATA_IN);
1106 }
1107 
1108 #define b2tol(a)	(((unsigned)(a##_1) << 8) + (unsigned)a##_0)
1109 
1110 /*
1111  * Get the scsi driver to send a full inquiry to the device and use the
1112  * results to fill out the disk parameter structure.
1113  */
1114 int
1115 cd_get_parms(cd, flags)
1116 	struct cd_data *cd;
1117 	int flags;
1118 {
1119 
1120 	/*
1121 	 * First check if we have it all loaded
1122 	 */
1123 	if (cd->sc_link->flags & SDEV_MEDIA_LOADED)
1124 		return 0;
1125 
1126 	/*
1127 	 * give a number of sectors so that sec * trks * cyls
1128 	 * is <= disk_size
1129 	 */
1130 	if (!cd_size(cd, flags))
1131 		return ENXIO;
1132 
1133 	cd->sc_link->flags |= SDEV_MEDIA_LOADED;
1134 	return 0;
1135 }
1136 
1137 int
1138 cdsize(dev)
1139 	dev_t dev;
1140 {
1141 
1142 	return -1;
1143 }
1144 
1145 int
1146 cddump()
1147 {
1148 
1149 	/* Not implemented. */
1150 	return EINVAL;
1151 }
1152