1 /* $NetBSD: cd.c,v 1.96 1996/10/12 23:23:13 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Charles M. 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 M. 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/file.h> 54 #include <sys/stat.h> 55 #include <sys/ioctl.h> 56 #include <sys/buf.h> 57 #include <sys/uio.h> 58 #include <sys/malloc.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 #include <sys/disklabel.h> 62 #include <sys/disk.h> 63 #include <sys/cdio.h> 64 #include <sys/proc.h> 65 #include <sys/conf.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 #define CDOUTSTANDING 4 73 #define CDRETRIES 1 74 75 #define CDUNIT(z) DISKUNIT(z) 76 #define CDPART(z) DISKPART(z) 77 #define MAKECDDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part) 78 79 struct cd_softc { 80 struct device sc_dev; 81 struct disk sc_dk; 82 83 int flags; 84 #define CDF_LOCKED 0x01 85 #define CDF_WANTED 0x02 86 #define CDF_WLABEL 0x04 /* label is writable */ 87 #define CDF_LABELLING 0x08 /* writing label */ 88 #define CDF_ANCIENT 0x10 /* disk is ancient; for minphys */ 89 struct scsi_link *sc_link; /* contains our targ, lun, etc. */ 90 struct cd_parms { 91 int blksize; 92 u_long disksize; /* total number sectors */ 93 } params; 94 struct buf buf_queue; 95 }; 96 97 int cdmatch __P((struct device *, void *, void *)); 98 void cdattach __P((struct device *, struct device *, void *)); 99 int cdlock __P((struct cd_softc *)); 100 void cdunlock __P((struct cd_softc *)); 101 void cdstart __P((void *)); 102 void cdminphys __P((struct buf *)); 103 void cdgetdisklabel __P((struct cd_softc *)); 104 int cddone __P((struct scsi_xfer *, int)); 105 u_long cd_size __P((struct cd_softc *, int)); 106 int cd_get_mode __P((struct cd_softc *, struct cd_mode_data *, int)); 107 int cd_set_mode __P((struct cd_softc *, struct cd_mode_data *)); 108 int cd_play __P((struct cd_softc *, int, int )); 109 int cd_play_big __P((struct cd_softc *, int, int )); 110 int cd_play_tracks __P((struct cd_softc *, int, int, int, int )); 111 int cd_play_msf __P((struct cd_softc *, int, int, int, int, int, int )); 112 int cd_pause __P((struct cd_softc *, int)); 113 int cd_reset __P((struct cd_softc *)); 114 int cd_read_subchannel __P((struct cd_softc *, int, int, int, 115 struct cd_sub_channel_info *, int )); 116 int cd_read_toc __P((struct cd_softc *, int, int, struct cd_toc_entry *, 117 int )); 118 int cd_get_parms __P((struct cd_softc *, int)); 119 120 struct cfattach cd_ca = { 121 sizeof(struct cd_softc), cdmatch, cdattach 122 }; 123 124 struct cfdriver cd_cd = { 125 NULL, "cd", DV_DISK 126 }; 127 128 struct dkdriver cddkdriver = { cdstrategy }; 129 130 struct scsi_device cd_switch = { 131 NULL, /* use default error handler */ 132 cdstart, /* we have a queue, which is started by this */ 133 NULL, /* we do not have an async handler */ 134 cddone, /* deal with stats at interrupt time */ 135 }; 136 137 struct scsi_inquiry_pattern cd_patterns[] = { 138 {T_CDROM, T_REMOV, 139 "", "", ""}, 140 #if 0 141 {T_CDROM, T_REMOV, /* more luns */ 142 "PIONEER ", "CD-ROM DRM-600 ", ""}, 143 #endif 144 }; 145 146 int 147 cdmatch(parent, match, aux) 148 struct device *parent; 149 void *match, *aux; 150 { 151 struct scsibus_attach_args *sa = aux; 152 int priority; 153 154 (void)scsi_inqmatch(sa->sa_inqbuf, 155 (caddr_t)cd_patterns, sizeof(cd_patterns)/sizeof(cd_patterns[0]), 156 sizeof(cd_patterns[0]), &priority); 157 return (priority); 158 } 159 160 /* 161 * The routine called by the low level scsi routine when it discovers 162 * A device suitable for this driver 163 */ 164 void 165 cdattach(parent, self, aux) 166 struct device *parent, *self; 167 void *aux; 168 { 169 struct cd_softc *cd = (void *)self; 170 struct scsibus_attach_args *sa = aux; 171 struct scsi_link *sc_link = sa->sa_sc_link; 172 173 SC_DEBUG(sc_link, SDEV_DB2, ("cdattach: ")); 174 175 /* 176 * Store information needed to contact our base driver 177 */ 178 cd->sc_link = sc_link; 179 sc_link->device = &cd_switch; 180 sc_link->device_softc = cd; 181 if (sc_link->openings > CDOUTSTANDING) 182 sc_link->openings = CDOUTSTANDING; 183 184 /* 185 * Initialize and attach the disk structure. 186 */ 187 cd->sc_dk.dk_driver = &cddkdriver; 188 cd->sc_dk.dk_name = cd->sc_dev.dv_xname; 189 disk_attach(&cd->sc_dk); 190 191 #if !defined(i386) 192 dk_establish(&cd->sc_dk, &cd->sc_dev); /* XXX */ 193 #endif 194 195 /* 196 * Note if this device is ancient. This is used in cdminphys(). 197 */ 198 if ((sa->sa_inqbuf->version & SID_ANSII) == 0) 199 cd->flags |= CDF_ANCIENT; 200 201 printf("\n"); 202 } 203 204 /* 205 * Wait interruptibly for an exclusive lock. 206 * 207 * XXX 208 * Several drivers do this; it should be abstracted and made MP-safe. 209 */ 210 int 211 cdlock(cd) 212 struct cd_softc *cd; 213 { 214 int error; 215 216 while ((cd->flags & CDF_LOCKED) != 0) { 217 cd->flags |= CDF_WANTED; 218 if ((error = tsleep(cd, PRIBIO | PCATCH, "cdlck", 0)) != 0) 219 return error; 220 } 221 cd->flags |= CDF_LOCKED; 222 return 0; 223 } 224 225 /* 226 * Unlock and wake up any waiters. 227 */ 228 void 229 cdunlock(cd) 230 struct cd_softc *cd; 231 { 232 233 cd->flags &= ~CDF_LOCKED; 234 if ((cd->flags & CDF_WANTED) != 0) { 235 cd->flags &= ~CDF_WANTED; 236 wakeup(cd); 237 } 238 } 239 240 /* 241 * open the device. Make sure the partition info is a up-to-date as can be. 242 */ 243 int 244 cdopen(dev, flag, fmt, p) 245 dev_t dev; 246 int flag, fmt; 247 struct proc *p; 248 { 249 struct cd_softc *cd; 250 struct scsi_link *sc_link; 251 int unit, part; 252 int error; 253 254 unit = CDUNIT(dev); 255 if (unit >= cd_cd.cd_ndevs) 256 return ENXIO; 257 cd = cd_cd.cd_devs[unit]; 258 if (!cd) 259 return ENXIO; 260 261 sc_link = cd->sc_link; 262 263 SC_DEBUG(sc_link, SDEV_DB1, 264 ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit, 265 cd_cd.cd_ndevs, CDPART(dev))); 266 267 if ((error = cdlock(cd)) != 0) 268 return error; 269 270 if (cd->sc_dk.dk_openmask != 0) { 271 /* 272 * If any partition is open, but the disk has been invalidated, 273 * disallow further opens. 274 */ 275 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 276 error = EIO; 277 goto bad3; 278 } 279 } else { 280 /* Check that it is still responding and ok. */ 281 error = scsi_test_unit_ready(sc_link, 282 SCSI_IGNORE_ILLEGAL_REQUEST | 283 SCSI_IGNORE_MEDIA_CHANGE | 284 SCSI_IGNORE_NOT_READY); 285 if (error) 286 goto bad3; 287 288 /* Start the pack spinning if necessary. */ 289 error = scsi_start(sc_link, SSS_START, 290 SCSI_IGNORE_ILLEGAL_REQUEST | 291 SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT); 292 if (error) 293 goto bad3; 294 295 sc_link->flags |= SDEV_OPEN; 296 297 /* Lock the pack in. */ 298 error = scsi_prevent(sc_link, PR_PREVENT, 299 SCSI_IGNORE_ILLEGAL_REQUEST | 300 SCSI_IGNORE_MEDIA_CHANGE); 301 if (error) 302 goto bad; 303 304 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 305 sc_link->flags |= SDEV_MEDIA_LOADED; 306 307 /* Load the physical device parameters. */ 308 if (cd_get_parms(cd, 0) != 0) { 309 error = ENXIO; 310 goto bad2; 311 } 312 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded ")); 313 314 /* Fabricate a disk label. */ 315 cdgetdisklabel(cd); 316 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated ")); 317 } 318 } 319 320 part = CDPART(dev); 321 322 /* Check that the partition exists. */ 323 if (part != RAW_PART && 324 (part >= cd->sc_dk.dk_label->d_npartitions || 325 cd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { 326 error = ENXIO; 327 goto bad; 328 } 329 330 /* Insure only one open at a time. */ 331 switch (fmt) { 332 case S_IFCHR: 333 cd->sc_dk.dk_copenmask |= (1 << part); 334 break; 335 case S_IFBLK: 336 cd->sc_dk.dk_bopenmask |= (1 << part); 337 break; 338 } 339 cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask; 340 341 SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n")); 342 cdunlock(cd); 343 return 0; 344 345 bad2: 346 sc_link->flags &= ~SDEV_MEDIA_LOADED; 347 348 bad: 349 if (cd->sc_dk.dk_openmask == 0) { 350 scsi_prevent(sc_link, PR_ALLOW, 351 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE); 352 sc_link->flags &= ~SDEV_OPEN; 353 } 354 355 bad3: 356 cdunlock(cd); 357 return error; 358 } 359 360 /* 361 * close the device.. only called if we are the LAST 362 * occurence of an open device 363 */ 364 int 365 cdclose(dev, flag, fmt, p) 366 dev_t dev; 367 int flag, fmt; 368 struct proc *p; 369 { 370 struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)]; 371 int part = CDPART(dev); 372 int error; 373 374 if ((error = cdlock(cd)) != 0) 375 return error; 376 377 switch (fmt) { 378 case S_IFCHR: 379 cd->sc_dk.dk_copenmask &= ~(1 << part); 380 break; 381 case S_IFBLK: 382 cd->sc_dk.dk_bopenmask &= ~(1 << part); 383 break; 384 } 385 cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask; 386 387 if (cd->sc_dk.dk_openmask == 0) { 388 /* XXXX Must wait for I/O to complete! */ 389 390 scsi_prevent(cd->sc_link, PR_ALLOW, 391 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY); 392 cd->sc_link->flags &= ~SDEV_OPEN; 393 } 394 395 cdunlock(cd); 396 return 0; 397 } 398 399 /* 400 * Actually translate the requested transfer into one the physical driver can 401 * understand. The transfer is described by a buf and will include only one 402 * physical transfer. 403 */ 404 void 405 cdstrategy(bp) 406 struct buf *bp; 407 { 408 struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)]; 409 int opri; 410 411 SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdstrategy ")); 412 SC_DEBUG(cd->sc_link, SDEV_DB1, 413 ("%ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno)); 414 /* 415 * The transfer must be a whole number of blocks. 416 */ 417 if ((bp->b_bcount % cd->sc_dk.dk_label->d_secsize) != 0) { 418 bp->b_error = EINVAL; 419 goto bad; 420 } 421 /* 422 * If the device has been made invalid, error out 423 * maybe the media changed 424 */ 425 if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 426 bp->b_error = EIO; 427 goto bad; 428 } 429 /* 430 * If it's a null transfer, return immediately 431 */ 432 if (bp->b_bcount == 0) 433 goto done; 434 435 /* 436 * Do bounds checking, adjust transfer. if error, process. 437 * If end of partition, just return. 438 */ 439 if (CDPART(bp->b_dev) != RAW_PART && 440 bounds_check_with_label(bp, cd->sc_dk.dk_label, 441 (cd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0) 442 goto done; 443 444 opri = splbio(); 445 446 /* 447 * Place it in the queue of disk activities for this disk 448 */ 449 disksort(&cd->buf_queue, bp); 450 451 /* 452 * Tell the device to get going on the transfer if it's 453 * not doing anything, otherwise just wait for completion 454 */ 455 cdstart(cd); 456 457 splx(opri); 458 return; 459 460 bad: 461 bp->b_flags |= B_ERROR; 462 done: 463 /* 464 * Correctly set the buf to indicate a completed xfer 465 */ 466 bp->b_resid = bp->b_bcount; 467 biodone(bp); 468 } 469 470 /* 471 * cdstart looks to see if there is a buf waiting for the device 472 * and that the device is not already busy. If both are true, 473 * It deques the buf and creates a scsi command to perform the 474 * transfer in the buf. The transfer request will call scsi_done 475 * on completion, which will in turn call this routine again 476 * so that the next queued transfer is performed. 477 * The bufs are queued by the strategy routine (cdstrategy) 478 * 479 * This routine is also called after other non-queued requests 480 * have been made of the scsi driver, to ensure that the queue 481 * continues to be drained. 482 * 483 * must be called at the correct (highish) spl level 484 * cdstart() is called at splbio from cdstrategy and scsi_done 485 */ 486 void 487 cdstart(v) 488 register void *v; 489 { 490 register struct cd_softc *cd = v; 491 register struct scsi_link *sc_link = cd->sc_link; 492 struct buf *bp = 0; 493 struct buf *dp; 494 struct scsi_rw_big cmd_big; 495 struct scsi_rw cmd_small; 496 struct scsi_generic *cmdp; 497 int blkno, nblks, cmdlen; 498 struct partition *p; 499 500 SC_DEBUG(sc_link, SDEV_DB2, ("cdstart ")); 501 /* 502 * Check if the device has room for another command 503 */ 504 while (sc_link->openings > 0) { 505 /* 506 * there is excess capacity, but a special waits 507 * It'll need the adapter as soon as we clear out of the 508 * way and let it run (user level wait). 509 */ 510 if (sc_link->flags & SDEV_WAITING) { 511 sc_link->flags &= ~SDEV_WAITING; 512 wakeup((caddr_t)sc_link); 513 return; 514 } 515 516 /* 517 * See if there is a buf with work for us to do.. 518 */ 519 dp = &cd->buf_queue; 520 if ((bp = dp->b_actf) == NULL) /* yes, an assign */ 521 return; 522 dp->b_actf = bp->b_actf; 523 524 /* 525 * If the deivce has become invalid, abort all the 526 * reads and writes until all files have been closed and 527 * re-opened 528 */ 529 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 530 bp->b_error = EIO; 531 bp->b_flags |= B_ERROR; 532 biodone(bp); 533 continue; 534 } 535 536 /* 537 * We have a buf, now we should make a command 538 * 539 * First, translate the block to absolute and put it in terms 540 * of the logical blocksize of the device. 541 */ 542 blkno = 543 bp->b_blkno / (cd->sc_dk.dk_label->d_secsize / DEV_BSIZE); 544 if (CDPART(bp->b_dev) != RAW_PART) { 545 p = &cd->sc_dk.dk_label->d_partitions[CDPART(bp->b_dev)]; 546 blkno += p->p_offset; 547 } 548 nblks = howmany(bp->b_bcount, cd->sc_dk.dk_label->d_secsize); 549 550 /* 551 * Fill out the scsi command. If the transfer will 552 * fit in a "small" cdb, use it. 553 */ 554 if (((blkno & 0x1fffff) == blkno) && 555 ((nblks & 0xff) == nblks)) { 556 /* 557 * We can fit in a small cdb. 558 */ 559 bzero(&cmd_small, sizeof(cmd_small)); 560 cmd_small.opcode = (bp->b_flags & B_READ) ? 561 READ_COMMAND : WRITE_COMMAND; 562 _lto3b(blkno, cmd_small.addr); 563 cmd_small.length = nblks & 0xff; 564 cmdlen = sizeof(cmd_small); 565 cmdp = (struct scsi_generic *)&cmd_small; 566 } else { 567 /* 568 * Need a large cdb. 569 */ 570 bzero(&cmd_big, sizeof(cmd_big)); 571 cmd_big.opcode = (bp->b_flags & B_READ) ? 572 READ_BIG : WRITE_BIG; 573 _lto4b(blkno, cmd_big.addr); 574 _lto2b(nblks, cmd_big.length); 575 cmdlen = sizeof(cmd_big); 576 cmdp = (struct scsi_generic *)&cmd_big; 577 } 578 579 /* Instrumentation. */ 580 disk_busy(&cd->sc_dk); 581 582 /* 583 * Call the routine that chats with the adapter. 584 * Note: we cannot sleep as we may be an interrupt 585 */ 586 if (scsi_scsi_cmd(sc_link, cmdp, cmdlen, 587 (u_char *) bp->b_data, bp->b_bcount, 588 CDRETRIES, 30000, bp, SCSI_NOSLEEP | 589 ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))) { 590 disk_unbusy(&cd->sc_dk, 0); 591 printf("%s: not queued", cd->sc_dev.dv_xname); 592 } 593 } 594 } 595 596 int 597 cddone(xs, complete) 598 struct scsi_xfer *xs; 599 int complete; 600 { 601 struct cd_softc *cd = xs->sc_link->device_softc; 602 603 if (complete && (xs->bp != NULL)) 604 disk_unbusy(&cd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid)); 605 606 return (0); 607 } 608 609 void 610 cdminphys(bp) 611 struct buf *bp; 612 { 613 struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)]; 614 long max; 615 616 /* 617 * If the device is ancient, we want to make sure that 618 * the transfer fits into a 6-byte cdb. 619 * 620 * XXX Note that the SCSI-I spec says that 256-block transfers 621 * are allowed in a 6-byte read/write, and are specified 622 * by settng the "length" to 0. However, we're conservative 623 * here, allowing only 255-block transfers in case an 624 * ancient device gets confused by length == 0. A length of 0 625 * in a 10-byte read/write actually means 0 blocks. 626 */ 627 if (cd->flags & CDF_ANCIENT) { 628 max = cd->sc_dk.dk_label->d_secsize * 0xff; 629 630 if (bp->b_bcount > max) 631 bp->b_bcount = max; 632 } 633 634 (*cd->sc_link->adapter->scsi_minphys)(bp); 635 } 636 637 int 638 cdread(dev, uio, ioflag) 639 dev_t dev; 640 struct uio *uio; 641 int ioflag; 642 { 643 644 return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio)); 645 } 646 647 int 648 cdwrite(dev, uio, ioflag) 649 dev_t dev; 650 struct uio *uio; 651 int ioflag; 652 { 653 654 return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio)); 655 } 656 657 /* 658 * Perform special action on behalf of the user. 659 * Knows about the internals of this device 660 */ 661 int 662 cdioctl(dev, cmd, addr, flag, p) 663 dev_t dev; 664 u_long cmd; 665 caddr_t addr; 666 int flag; 667 struct proc *p; 668 { 669 struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)]; 670 int error; 671 672 SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdioctl 0x%lx ", cmd)); 673 674 /* 675 * If the device is not valid.. abandon ship 676 */ 677 if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) 678 return EIO; 679 680 switch (cmd) { 681 case DIOCGDINFO: 682 *(struct disklabel *)addr = *(cd->sc_dk.dk_label); 683 return 0; 684 685 case DIOCGPART: 686 ((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label; 687 ((struct partinfo *)addr)->part = 688 &cd->sc_dk.dk_label->d_partitions[CDPART(dev)]; 689 return 0; 690 691 case DIOCWDINFO: 692 case DIOCSDINFO: 693 if ((flag & FWRITE) == 0) 694 return EBADF; 695 696 if ((error = cdlock(cd)) != 0) 697 return error; 698 cd->flags |= CDF_LABELLING; 699 700 error = setdisklabel(cd->sc_dk.dk_label, 701 (struct disklabel *)addr, /*cd->sc_dk.dk_openmask : */0, 702 cd->sc_dk.dk_cpulabel); 703 if (error == 0) { 704 } 705 706 cd->flags &= ~CDF_LABELLING; 707 cdunlock(cd); 708 return error; 709 710 case DIOCWLABEL: 711 return EBADF; 712 713 case CDIOCPLAYTRACKS: { 714 struct ioc_play_track *args = (struct ioc_play_track *)addr; 715 struct cd_mode_data data; 716 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 717 return error; 718 data.page.audio.flags &= ~CD_PA_SOTC; 719 data.page.audio.flags |= CD_PA_IMMED; 720 if ((error = cd_set_mode(cd, &data)) != 0) 721 return error; 722 return cd_play_tracks(cd, args->start_track, 723 args->start_index, args->end_track, 724 args->end_index); 725 } 726 case CDIOCPLAYMSF: { 727 struct ioc_play_msf *args = (struct ioc_play_msf *)addr; 728 struct cd_mode_data data; 729 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 730 return error; 731 data.page.audio.flags &= ~CD_PA_SOTC; 732 data.page.audio.flags |= CD_PA_IMMED; 733 if ((error = cd_set_mode(cd, &data)) != 0) 734 return error; 735 return cd_play_msf(cd, args->start_m, args->start_s, 736 args->start_f, args->end_m, args->end_s, 737 args->end_f); 738 } 739 case CDIOCPLAYBLOCKS: { 740 struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr; 741 struct cd_mode_data data; 742 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 743 return error; 744 data.page.audio.flags &= ~CD_PA_SOTC; 745 data.page.audio.flags |= CD_PA_IMMED; 746 if ((error = cd_set_mode(cd, &data)) != 0) 747 return error; 748 return cd_play(cd, args->blk, args->len); 749 } 750 case CDIOCREADSUBCHANNEL: { 751 struct ioc_read_subchannel *args 752 = (struct ioc_read_subchannel *)addr; 753 struct cd_sub_channel_info data; 754 int len = args->data_len; 755 if (len > sizeof(data) || 756 len < sizeof(struct cd_sub_channel_header)) 757 return EINVAL; 758 error = cd_read_subchannel(cd, args->address_format, 759 args->data_format, args->track, 760 &data, len); 761 if (error) 762 return error; 763 len = min(len, _2btol(data.header.data_len) + 764 sizeof(struct cd_sub_channel_header)); 765 return copyout(&data, args->data, len); 766 } 767 case CDIOREADTOCHEADER: { 768 struct ioc_toc_header th; 769 if ((error = cd_read_toc(cd, 0, 0, 770 (struct cd_toc_entry *) &th, 771 sizeof(th))) != 0) 772 return error; 773 th.len = ntohs(th.len); 774 bcopy(&th, addr, sizeof(th)); 775 return 0; 776 } 777 case CDIOREADTOCENTRYS: { 778 struct cd_toc { 779 struct ioc_toc_header header; 780 struct cd_toc_entry entries[65]; 781 } data; 782 struct ioc_read_toc_entry *te = 783 (struct ioc_read_toc_entry *)addr; 784 struct ioc_toc_header *th; 785 int len = te->data_len; 786 th = &data.header; 787 788 if (len > sizeof(data.entries) || 789 len < sizeof(struct cd_toc_entry)) 790 return EINVAL; 791 error = cd_read_toc(cd, te->address_format, 792 te->starting_track, 793 (struct cd_toc_entry *)&data, 794 len + sizeof(struct ioc_toc_header)); 795 if (error) 796 return error; 797 len = min(len, ntohs(th->len) - (sizeof(th->starting_track) + 798 sizeof(th->ending_track))); 799 return copyout(data.entries, te->data, len); 800 } 801 case CDIOCSETPATCH: { 802 struct ioc_patch *arg = (struct ioc_patch *)addr; 803 struct cd_mode_data data; 804 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 805 return error; 806 data.page.audio.port[LEFT_PORT].channels = arg->patch[0]; 807 data.page.audio.port[RIGHT_PORT].channels = arg->patch[1]; 808 data.page.audio.port[2].channels = arg->patch[2]; 809 data.page.audio.port[3].channels = arg->patch[3]; 810 return cd_set_mode(cd, &data); 811 } 812 case CDIOCGETVOL: { 813 struct ioc_vol *arg = (struct ioc_vol *)addr; 814 struct cd_mode_data data; 815 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 816 return error; 817 arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume; 818 arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume; 819 arg->vol[2] = data.page.audio.port[2].volume; 820 arg->vol[3] = data.page.audio.port[3].volume; 821 return 0; 822 } 823 case CDIOCSETVOL: { 824 struct ioc_vol *arg = (struct ioc_vol *)addr; 825 struct cd_mode_data data; 826 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 827 return error; 828 data.page.audio.port[LEFT_PORT].channels = CHANNEL_0; 829 data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT]; 830 data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1; 831 data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT]; 832 data.page.audio.port[2].volume = arg->vol[2]; 833 data.page.audio.port[3].volume = arg->vol[3]; 834 return cd_set_mode(cd, &data); 835 } 836 case CDIOCSETMONO: { 837 struct cd_mode_data data; 838 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 839 return error; 840 data.page.audio.port[LEFT_PORT].channels = 841 LEFT_CHANNEL | RIGHT_CHANNEL | 4 | 8; 842 data.page.audio.port[RIGHT_PORT].channels = 843 LEFT_CHANNEL | RIGHT_CHANNEL; 844 data.page.audio.port[2].channels = 0; 845 data.page.audio.port[3].channels = 0; 846 return cd_set_mode(cd, &data); 847 } 848 case CDIOCSETSTEREO: { 849 struct cd_mode_data data; 850 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 851 return error; 852 data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL; 853 data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; 854 data.page.audio.port[2].channels = 0; 855 data.page.audio.port[3].channels = 0; 856 return cd_set_mode(cd, &data); 857 } 858 case CDIOCSETMUTE: { 859 struct cd_mode_data data; 860 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 861 return error; 862 data.page.audio.port[LEFT_PORT].channels = 0; 863 data.page.audio.port[RIGHT_PORT].channels = 0; 864 data.page.audio.port[2].channels = 0; 865 data.page.audio.port[3].channels = 0; 866 return cd_set_mode(cd, &data); 867 } 868 case CDIOCSETLEFT: { 869 struct cd_mode_data data; 870 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 871 return error; 872 data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL; 873 data.page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL; 874 data.page.audio.port[2].channels = 0; 875 data.page.audio.port[3].channels = 0; 876 return cd_set_mode(cd, &data); 877 } 878 case CDIOCSETRIGHT: { 879 struct cd_mode_data data; 880 if ((error = cd_get_mode(cd, &data, AUDIO_PAGE)) != 0) 881 return error; 882 data.page.audio.port[LEFT_PORT].channels = RIGHT_CHANNEL; 883 data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; 884 data.page.audio.port[2].channels = 0; 885 data.page.audio.port[3].channels = 0; 886 return cd_set_mode(cd, &data); 887 } 888 case CDIOCRESUME: 889 return cd_pause(cd, 1); 890 case CDIOCPAUSE: 891 return cd_pause(cd, 0); 892 case CDIOCSTART: 893 return scsi_start(cd->sc_link, SSS_START, 0); 894 case CDIOCSTOP: 895 return scsi_start(cd->sc_link, SSS_STOP, 0); 896 case CDIOCEJECT: /* FALLTHROUGH */ 897 case DIOCEJECT: 898 return scsi_start(cd->sc_link, SSS_STOP|SSS_LOEJ, 0); 899 case CDIOCALLOW: 900 return scsi_prevent(cd->sc_link, PR_ALLOW, 0); 901 case CDIOCPREVENT: 902 return scsi_prevent(cd->sc_link, PR_PREVENT, 0); 903 case DIOCLOCK: 904 return scsi_prevent(cd->sc_link, 905 (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0); 906 case CDIOCSETDEBUG: 907 cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2); 908 return 0; 909 case CDIOCCLRDEBUG: 910 cd->sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2); 911 return 0; 912 case CDIOCRESET: 913 return cd_reset(cd); 914 915 default: 916 if (CDPART(dev) != RAW_PART) 917 return ENOTTY; 918 return scsi_do_ioctl(cd->sc_link, dev, cmd, addr, flag, p); 919 } 920 921 #ifdef DIAGNOSTIC 922 panic("cdioctl: impossible"); 923 #endif 924 } 925 926 /* 927 * Load the label information on the named device 928 * Actually fabricate a disklabel 929 * 930 * EVENTUALLY take information about different 931 * data tracks from the TOC and put it in the disklabel 932 */ 933 void 934 cdgetdisklabel(cd) 935 struct cd_softc *cd; 936 { 937 struct disklabel *lp = cd->sc_dk.dk_label; 938 939 bzero(lp, sizeof(struct disklabel)); 940 bzero(cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel)); 941 942 lp->d_secsize = cd->params.blksize; 943 lp->d_ntracks = 1; 944 lp->d_nsectors = 100; 945 lp->d_ncylinders = (cd->params.disksize / 100) + 1; 946 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 947 948 strncpy(lp->d_typename, "SCSI CD-ROM", 16); 949 lp->d_type = DTYPE_SCSI; 950 strncpy(lp->d_packname, "fictitious", 16); 951 lp->d_secperunit = cd->params.disksize; 952 lp->d_rpm = 300; 953 lp->d_interleave = 1; 954 lp->d_flags = D_REMOVABLE; 955 956 lp->d_partitions[0].p_offset = 0; 957 lp->d_partitions[0].p_size = 958 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 959 lp->d_partitions[0].p_fstype = FS_ISO9660; 960 lp->d_partitions[RAW_PART].p_offset = 0; 961 lp->d_partitions[RAW_PART].p_size = 962 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 963 lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660; 964 lp->d_npartitions = RAW_PART + 1; 965 966 lp->d_magic = DISKMAGIC; 967 lp->d_magic2 = DISKMAGIC; 968 lp->d_checksum = dkcksum(lp); 969 } 970 971 /* 972 * Find out from the device what it's capacity is 973 */ 974 u_long 975 cd_size(cd, flags) 976 struct cd_softc *cd; 977 int flags; 978 { 979 struct scsi_read_cd_cap_data rdcap; 980 struct scsi_read_cd_capacity scsi_cmd; 981 int blksize; 982 u_long size; 983 984 /* 985 * make up a scsi command and ask the scsi driver to do 986 * it for you. 987 */ 988 bzero(&scsi_cmd, sizeof(scsi_cmd)); 989 scsi_cmd.opcode = READ_CD_CAPACITY; 990 991 /* 992 * If the command works, interpret the result as a 4 byte 993 * number of blocks and a blocksize 994 */ 995 if (scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 996 sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 997 2000, NULL, flags | SCSI_DATA_IN) != 0) 998 return 0; 999 1000 blksize = _4btol(rdcap.length); 1001 if (blksize < 512) 1002 blksize = 2048; /* some drives lie ! */ 1003 cd->params.blksize = blksize; 1004 1005 size = _4btol(rdcap.addr) + 1; 1006 if (size < 100) 1007 size = 400000; /* ditto */ 1008 cd->params.disksize = size; 1009 1010 return size; 1011 } 1012 1013 /* 1014 * Get the requested page into the buffer given 1015 */ 1016 int 1017 cd_get_mode(cd, data, page) 1018 struct cd_softc *cd; 1019 struct cd_mode_data *data; 1020 int page; 1021 { 1022 struct scsi_mode_sense scsi_cmd; 1023 1024 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1025 bzero(data, sizeof(*data)); 1026 scsi_cmd.opcode = MODE_SENSE; 1027 scsi_cmd.page = page; 1028 scsi_cmd.length = sizeof(*data) & 0xff; 1029 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1030 sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000, 1031 NULL, SCSI_DATA_IN); 1032 } 1033 1034 /* 1035 * Get the requested page into the buffer given 1036 */ 1037 int 1038 cd_set_mode(cd, data) 1039 struct cd_softc *cd; 1040 struct cd_mode_data *data; 1041 { 1042 struct scsi_mode_select scsi_cmd; 1043 1044 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1045 scsi_cmd.opcode = MODE_SELECT; 1046 scsi_cmd.byte2 |= SMS_PF; 1047 scsi_cmd.length = sizeof(*data) & 0xff; 1048 data->header.data_length = 0; 1049 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1050 sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000, 1051 NULL, SCSI_DATA_OUT); 1052 } 1053 1054 /* 1055 * Get scsi driver to send a "start playing" command 1056 */ 1057 int 1058 cd_play(cd, blkno, nblks) 1059 struct cd_softc *cd; 1060 int blkno, nblks; 1061 { 1062 struct scsi_play scsi_cmd; 1063 1064 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1065 scsi_cmd.opcode = PLAY; 1066 _lto4b(blkno, scsi_cmd.blk_addr); 1067 _lto2b(nblks, scsi_cmd.xfer_len); 1068 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1069 sizeof(scsi_cmd), 0, 0, CDRETRIES, 200000, NULL, 0); 1070 } 1071 1072 /* 1073 * Get scsi driver to send a "start playing" command 1074 */ 1075 int 1076 cd_play_big(cd, blkno, nblks) 1077 struct cd_softc *cd; 1078 int blkno, nblks; 1079 { 1080 struct scsi_play_big scsi_cmd; 1081 1082 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1083 scsi_cmd.opcode = PLAY_BIG; 1084 _lto4b(blkno, scsi_cmd.blk_addr); 1085 _lto4b(nblks, scsi_cmd.xfer_len); 1086 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1087 sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0); 1088 } 1089 1090 /* 1091 * Get scsi driver to send a "start playing" command 1092 */ 1093 int 1094 cd_play_tracks(cd, strack, sindex, etrack, eindex) 1095 struct cd_softc *cd; 1096 int strack, sindex, etrack, eindex; 1097 { 1098 struct scsi_play_track scsi_cmd; 1099 1100 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1101 scsi_cmd.opcode = PLAY_TRACK; 1102 scsi_cmd.start_track = strack; 1103 scsi_cmd.start_index = sindex; 1104 scsi_cmd.end_track = etrack; 1105 scsi_cmd.end_index = eindex; 1106 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1107 sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0); 1108 } 1109 1110 /* 1111 * Get scsi driver to send a "play msf" command 1112 */ 1113 int 1114 cd_play_msf(cd, startm, starts, startf, endm, ends, endf) 1115 struct cd_softc *cd; 1116 int startm, starts, startf, endm, ends, endf; 1117 { 1118 struct scsi_play_msf scsi_cmd; 1119 1120 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1121 scsi_cmd.opcode = PLAY_MSF; 1122 scsi_cmd.start_m = startm; 1123 scsi_cmd.start_s = starts; 1124 scsi_cmd.start_f = startf; 1125 scsi_cmd.end_m = endm; 1126 scsi_cmd.end_s = ends; 1127 scsi_cmd.end_f = endf; 1128 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1129 sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0); 1130 } 1131 1132 /* 1133 * Get scsi driver to send a "start up" command 1134 */ 1135 int 1136 cd_pause(cd, go) 1137 struct cd_softc *cd; 1138 int go; 1139 { 1140 struct scsi_pause scsi_cmd; 1141 1142 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1143 scsi_cmd.opcode = PAUSE; 1144 scsi_cmd.resume = go; 1145 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1146 sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0); 1147 } 1148 1149 /* 1150 * Get scsi driver to send a "RESET" command 1151 */ 1152 int 1153 cd_reset(cd) 1154 struct cd_softc *cd; 1155 { 1156 1157 return scsi_scsi_cmd(cd->sc_link, 0, 0, 0, 0, CDRETRIES, 2000, NULL, 1158 SCSI_RESET); 1159 } 1160 1161 /* 1162 * Read subchannel 1163 */ 1164 int 1165 cd_read_subchannel(cd, mode, format, track, data, len) 1166 struct cd_softc *cd; 1167 int mode, format, track, len; 1168 struct cd_sub_channel_info *data; 1169 { 1170 struct scsi_read_subchannel scsi_cmd; 1171 1172 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1173 scsi_cmd.opcode = READ_SUBCHANNEL; 1174 if (mode == CD_MSF_FORMAT) 1175 scsi_cmd.byte2 |= CD_MSF; 1176 scsi_cmd.byte3 = SRS_SUBQ; 1177 scsi_cmd.subchan_format = format; 1178 scsi_cmd.track = track; 1179 _lto2b(len, scsi_cmd.data_len); 1180 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1181 sizeof(struct scsi_read_subchannel), (u_char *)data, len, 1182 CDRETRIES, 5000, NULL, SCSI_DATA_IN|SCSI_SILENT); 1183 } 1184 1185 /* 1186 * Read table of contents 1187 */ 1188 int 1189 cd_read_toc(cd, mode, start, data, len) 1190 struct cd_softc *cd; 1191 int mode, start, len; 1192 struct cd_toc_entry *data; 1193 { 1194 struct scsi_read_toc scsi_cmd; 1195 int ntoc; 1196 1197 bzero(&scsi_cmd, sizeof(scsi_cmd)); 1198 /*if (len!=sizeof(struct ioc_toc_header)) 1199 * ntoc=((len)-sizeof(struct ioc_toc_header))/sizeof(struct cd_toc_entry); 1200 * else */ 1201 ntoc = len; 1202 scsi_cmd.opcode = READ_TOC; 1203 if (mode == CD_MSF_FORMAT) 1204 scsi_cmd.byte2 |= CD_MSF; 1205 scsi_cmd.from_track = start; 1206 _lto2b(ntoc, scsi_cmd.data_len); 1207 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd, 1208 sizeof(struct scsi_read_toc), (u_char *)data, len, CDRETRIES, 1209 5000, NULL, SCSI_DATA_IN); 1210 } 1211 1212 /* 1213 * Get the scsi driver to send a full inquiry to the device and use the 1214 * results to fill out the disk parameter structure. 1215 */ 1216 int 1217 cd_get_parms(cd, flags) 1218 struct cd_softc *cd; 1219 int flags; 1220 { 1221 1222 /* 1223 * give a number of sectors so that sec * trks * cyls 1224 * is <= disk_size 1225 */ 1226 if (cd_size(cd, flags) == 0) 1227 return ENXIO; 1228 1229 return 0; 1230 } 1231 1232 int 1233 cdsize(dev) 1234 dev_t dev; 1235 { 1236 1237 /* CD-ROMs are read-only. */ 1238 return -1; 1239 } 1240 1241 int 1242 cddump(dev, blkno, va, size) 1243 dev_t dev; 1244 daddr_t blkno; 1245 caddr_t va; 1246 size_t size; 1247 { 1248 1249 /* Not implemented. */ 1250 return ENXIO; 1251 } 1252