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