Deleted Added
full compact
mcd.c (104545) mcd.c (106490)
1/*
2 * Copyright 1993 by Holger Veit (data part)
3 * Copyright 1993 by Brian Moore (audio part)
4 * Changes Copyright 1993 by Gary Clark II
5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia
6 *
7 * Rewrote probe routine to work on newer Mitsumi drives.
8 * Additional changes (C) 1994 by Jordan K. Hubbard

--- 26 unchanged lines hidden (view full) ---

35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
1/*
2 * Copyright 1993 by Holger Veit (data part)
3 * Copyright 1993 by Brian Moore (audio part)
4 * Changes Copyright 1993 by Gary Clark II
5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia
6 *
7 * Rewrote probe routine to work on newer Mitsumi drives.
8 * Additional changes (C) 1994 by Jordan K. Hubbard

--- 26 unchanged lines hidden (view full) ---

35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 * $FreeBSD: head/sys/dev/mcd/mcd.c 104545 2002-10-06 00:19:38Z mdodd $
43 * $FreeBSD: head/sys/dev/mcd/mcd.c 106490 2002-11-06 08:08:55Z mdodd $
44 */
45static const char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
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>

--- 137 unchanged lines hidden (view full) ---

189#define RDELAY_WAITREAD 800
190
191#define MIN_DELAY 15
192#define DELAY_GETREPLY 5000000
193
194int
195mcd_attach(struct mcd_softc *sc)
196{
44 */
45static const char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
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>

--- 137 unchanged lines hidden (view full) ---

189#define RDELAY_WAITREAD 800
190
191#define MIN_DELAY 15
192#define DELAY_GETREPLY 5000000
193
194int
195mcd_attach(struct mcd_softc *sc)
196{
197 struct mcd_data *cd;
198 int unit;
199
197 int unit;
198
200 cd = &sc->data;
201 unit = device_get_unit(sc->dev);
202
199 unit = device_get_unit(sc->dev);
200
203 cd->flags |= MCDINIT;
201 sc->data.flags |= MCDINIT;
204 mcd_soft_reset(sc);
202 mcd_soft_reset(sc);
205 bioq_init(&cd->head);
203 bioq_init(&sc->data.head);
206
207#ifdef NOTYET
208 /* wire controller for interrupts and dma */
209 mcd_configure(sc);
210#endif
211 /* name filled in probe */
212 sc->mcd_dev_t = make_dev(&mcd_cdevsw, 8 * unit,
213 UID_ROOT, GID_OPERATOR, 0640, "mcd%d", unit);
214
215 sc->mcd_dev_t->si_drv1 = (void *)sc;
216
204
205#ifdef NOTYET
206 /* wire controller for interrupts and dma */
207 mcd_configure(sc);
208#endif
209 /* name filled in probe */
210 sc->mcd_dev_t = make_dev(&mcd_cdevsw, 8 * unit,
211 UID_ROOT, GID_OPERATOR, 0640, "mcd%d", unit);
212
213 sc->mcd_dev_t->si_drv1 = (void *)sc;
214
217 return 0;
215 return (0);
218}
219
220static int
221mcdopen(dev_t dev, int flags, int fmt, struct thread *td)
222{
223 struct mcd_softc *sc;
216}
217
218static int
219mcdopen(dev_t dev, int flags, int fmt, struct thread *td)
220{
221 struct mcd_softc *sc;
224 struct mcd_data *cd;
225 int r,retry;
226
227 sc = (struct mcd_softc *)dev->si_drv1;
222 int r,retry;
223
224 sc = (struct mcd_softc *)dev->si_drv1;
228 cd = &sc->data;
229
230 /* not initialized*/
225
226 /* not initialized*/
231 if (!(cd->flags & MCDINIT))
232 return ENXIO;
227 if (!(sc->data.flags & MCDINIT))
228 return (ENXIO);
233
234 /* invalidated in the meantime? mark all open part's invalid */
229
230 /* invalidated in the meantime? mark all open part's invalid */
235 if (!(cd->flags & MCDVALID) && cd->openflags)
236 return ENXIO;
231 if (!(sc->data.flags & MCDVALID) && sc->data.openflags)
232 return (ENXIO);
237
238 if (mcd_getstat(sc, 1) == -1)
233
234 if (mcd_getstat(sc, 1) == -1)
239 return EIO;
235 return (EIO);
240
236
241 if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN))
242 || !(cd->status & MCDDSKIN))
237 if ( (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN))
238 || !(sc->data.status & MCDDSKIN))
243 for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
239 for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
244 (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsn1", hz/WAIT_FRAC);
240 (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn1", hz/WAIT_FRAC);
245 if ((r = mcd_getstat(sc, 1)) == -1)
241 if ((r = mcd_getstat(sc, 1)) == -1)
246 return EIO;
242 return (EIO);
247 if (r != -2)
248 break;
249 }
250
243 if (r != -2)
244 break;
245 }
246
251 if (cd->status & MCDDOOROPEN) {
247 if (sc->data.status & MCDDOOROPEN) {
252 device_printf(sc->dev, "door is open\n");
248 device_printf(sc->dev, "door is open\n");
253 return ENXIO;
249 return (ENXIO);
254 }
250 }
255 if (!(cd->status & MCDDSKIN)) {
251 if (!(sc->data.status & MCDDSKIN)) {
256 device_printf(sc->dev, "no CD inside\n");
252 device_printf(sc->dev, "no CD inside\n");
257 return ENXIO;
253 return (ENXIO);
258 }
254 }
259 if (cd->status & MCDDSKCHNG) {
255 if (sc->data.status & MCDDSKCHNG) {
260 device_printf(sc->dev, "CD not sensed\n");
256 device_printf(sc->dev, "CD not sensed\n");
261 return ENXIO;
257 return (ENXIO);
262 }
263
264 if (mcdsize(dev) < 0) {
265 device_printf(sc->dev, "failed to get disk size\n");
258 }
259
260 if (mcdsize(dev) < 0) {
261 device_printf(sc->dev, "failed to get disk size\n");
266 return ENXIO;
262 return (ENXIO);
267 }
268
263 }
264
269 dev->si_bsize_phys = cd->blksize;
265 dev->si_bsize_phys = sc->data.blksize;
270
266
271 cd->openflags = 1;
272 cd->partflags |= MCDREADRAW;
273 cd->flags |= MCDVALID;
267 sc->data.openflags = 1;
268 sc->data.partflags |= MCDREADRAW;
269 sc->data.flags |= MCDVALID;
274
275 (void) mcd_lock_door(sc, MCD_LK_LOCK);
270
271 (void) mcd_lock_door(sc, MCD_LK_LOCK);
276 if (!(cd->flags & MCDVALID))
277 return ENXIO;
272 if (!(sc->data.flags & MCDVALID))
273 return (ENXIO);
278
274
279 return (mcd_read_toc(sc));
275 return mcd_read_toc(sc);
280}
281
282static int
283mcdclose(dev_t dev, int flags, int fmt, struct thread *td)
284{
285 struct mcd_softc *sc;
276}
277
278static int
279mcdclose(dev_t dev, int flags, int fmt, struct thread *td)
280{
281 struct mcd_softc *sc;
286 struct mcd_data *cd;
287
288 sc = (struct mcd_softc *)dev->si_drv1;
282
283 sc = (struct mcd_softc *)dev->si_drv1;
289 cd = &sc->data;
290
284
291 if (!(cd->flags & MCDINIT) || !cd->openflags)
292 return ENXIO;
285 if (!(sc->data.flags & MCDINIT) || !sc->data.openflags)
286 return (ENXIO);
293
294 (void) mcd_lock_door(sc, MCD_LK_UNLOCK);
287
288 (void) mcd_lock_door(sc, MCD_LK_UNLOCK);
295 cd->openflags = 0;
296 cd->partflags &= ~MCDREADRAW;
289 sc->data.openflags = 0;
290 sc->data.partflags &= ~MCDREADRAW;
297
291
298 return 0;
292 return (0);
299}
300
301static void
302mcdstrategy(struct bio *bp)
303{
304 struct mcd_softc *sc;
293}
294
295static void
296mcdstrategy(struct bio *bp)
297{
298 struct mcd_softc *sc;
305 struct mcd_data *cd;
306 int s;
307
308 sc = (struct mcd_softc *)bp->bio_dev->si_drv1;
299 int s;
300
301 sc = (struct mcd_softc *)bp->bio_dev->si_drv1;
309 cd = &sc->data;
310
311 /* test validity */
312/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n",
313 bp,unit,bp->bio_blkno,bp->bio_bcount);*/
314
315 if (bp->bio_blkno < 0) {
316 device_printf(sc->dev, "strategy failure: blkno = %ld, bcount = %ld\n",
317 (long)bp->bio_blkno, bp->bio_bcount);
318 bp->bio_error = EINVAL;
319 bp->bio_flags |= BIO_ERROR;
320 goto bad;
321 }
322
323 /* if device invalidated (e.g. media change, door open), error */
302
303 /* test validity */
304/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n",
305 bp,unit,bp->bio_blkno,bp->bio_bcount);*/
306
307 if (bp->bio_blkno < 0) {
308 device_printf(sc->dev, "strategy failure: blkno = %ld, bcount = %ld\n",
309 (long)bp->bio_blkno, bp->bio_bcount);
310 bp->bio_error = EINVAL;
311 bp->bio_flags |= BIO_ERROR;
312 goto bad;
313 }
314
315 /* if device invalidated (e.g. media change, door open), error */
324 if (!(cd->flags & MCDVALID)) {
316 if (!(sc->data.flags & MCDVALID)) {
325 device_printf(sc->dev, "media changed\n");
326 bp->bio_error = EIO;
327 goto bad;
328 }
329
330 /* read only */
331 if (!(bp->bio_cmd == BIO_READ)) {
332 bp->bio_error = EROFS;
333 goto bad;
334 }
335
336 /* no data to read */
337 if (bp->bio_bcount == 0)
338 goto done;
339
317 device_printf(sc->dev, "media changed\n");
318 bp->bio_error = EIO;
319 goto bad;
320 }
321
322 /* read only */
323 if (!(bp->bio_cmd == BIO_READ)) {
324 bp->bio_error = EROFS;
325 goto bad;
326 }
327
328 /* no data to read */
329 if (bp->bio_bcount == 0)
330 goto done;
331
340 if (!(cd->flags & MCDTOC)) {
332 if (!(sc->data.flags & MCDTOC)) {
341 bp->bio_error = EIO;
342 goto bad;
343 }
344
345 bp->bio_pblkno = bp->bio_blkno;
346 bp->bio_resid = 0;
347
348 /* queue it */
349 s = splbio();
333 bp->bio_error = EIO;
334 goto bad;
335 }
336
337 bp->bio_pblkno = bp->bio_blkno;
338 bp->bio_resid = 0;
339
340 /* queue it */
341 s = splbio();
350 bioqdisksort(&cd->head, bp);
342 bioqdisksort(&sc->data.head, bp);
351 splx(s);
352
353 /* now check whether we can perform processing */
354 mcd_start(sc);
355 return;
356
357bad:
358 bp->bio_flags |= BIO_ERROR;
359done:
360 bp->bio_resid = bp->bio_bcount;
361 biodone(bp);
362 return;
363}
364
365static void
366mcd_start(struct mcd_softc *sc)
367{
343 splx(s);
344
345 /* now check whether we can perform processing */
346 mcd_start(sc);
347 return;
348
349bad:
350 bp->bio_flags |= BIO_ERROR;
351done:
352 bp->bio_resid = bp->bio_bcount;
353 biodone(bp);
354 return;
355}
356
357static void
358mcd_start(struct mcd_softc *sc)
359{
368 struct mcd_data *cd = &sc->data;
369 struct bio *bp;
370 int s = splbio();
371
360 struct bio *bp;
361 int s = splbio();
362
372 if (cd->flags & MCDMBXBSY) {
363 if (sc->data.flags & MCDMBXBSY) {
373 splx(s);
374 return;
375 }
376
364 splx(s);
365 return;
366 }
367
377 bp = bioq_first(&cd->head);
368 bp = bioq_first(&sc->data.head);
378 if (bp != 0) {
379 /* block found to process, dequeue */
380 /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/
369 if (bp != 0) {
370 /* block found to process, dequeue */
371 /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/
381 bioq_remove(&cd->head, bp);
382 cd->flags |= MCDMBXBSY;
372 bioq_remove(&sc->data.head, bp);
373 sc->data.flags |= MCDMBXBSY;
383 splx(s);
384 } else {
385 /* nothing to do */
386 splx(s);
387 return;
388 }
389
374 splx(s);
375 } else {
376 /* nothing to do */
377 splx(s);
378 return;
379 }
380
390 cd->mbx.retry = MCD_RETRYS;
391 cd->mbx.bp = bp;
381 sc->data.mbx.retry = MCD_RETRYS;
382 sc->data.mbx.bp = bp;
392
383
393 mcd_doread(sc, MCD_S_BEGIN,&(cd->mbx));
384 mcd_doread(sc, MCD_S_BEGIN,&(sc->data.mbx));
394 return;
395}
396
397static int
398mcdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
399{
400 struct mcd_softc *sc;
385 return;
386}
387
388static int
389mcdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
390{
391 struct mcd_softc *sc;
401 struct mcd_data *cd;
402 int retry,r;
403
404 sc = (struct mcd_softc *)dev->si_drv1;
392 int retry,r;
393
394 sc = (struct mcd_softc *)dev->si_drv1;
405 cd = &sc->data;
406
407 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
395
396 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
408 return EIO;
397 return (EIO);
409MCD_TRACE("ioctl called 0x%lx\n", cmd);
410
411 switch (cmd) {
412 case CDIOCSETPATCH:
413 case CDIOCGETVOL:
414 case CDIOCSETVOL:
415 case CDIOCSETMONO:
416 case CDIOCSETSTERIO:
417 case CDIOCSETMUTE:
418 case CDIOCSETLEFT:
419 case CDIOCSETRIGHT:
398MCD_TRACE("ioctl called 0x%lx\n", cmd);
399
400 switch (cmd) {
401 case CDIOCSETPATCH:
402 case CDIOCGETVOL:
403 case CDIOCSETVOL:
404 case CDIOCSETMONO:
405 case CDIOCSETSTERIO:
406 case CDIOCSETMUTE:
407 case CDIOCSETLEFT:
408 case CDIOCSETRIGHT:
420 return EINVAL;
409 return (EINVAL);
421 case CDIOCEJECT:
422 return mcd_eject(sc);
423 case CDIOCSETDEBUG:
410 case CDIOCEJECT:
411 return mcd_eject(sc);
412 case CDIOCSETDEBUG:
424 cd->debug = 1;
425 return 0;
413 sc->data.debug = 1;
414 return (0);
426 case CDIOCCLRDEBUG:
415 case CDIOCCLRDEBUG:
427 cd->debug = 0;
428 return 0;
416 sc->data.debug = 0;
417 return (0);
429 case CDIOCRESET:
430 return mcd_hard_reset(sc);
431 case CDIOCALLOW:
432 return mcd_lock_door(sc, MCD_LK_UNLOCK);
433 case CDIOCPREVENT:
434 return mcd_lock_door(sc, MCD_LK_LOCK);
435 case CDIOCCLOSE:
436 return mcd_inject(sc);
437 }
438
418 case CDIOCRESET:
419 return mcd_hard_reset(sc);
420 case CDIOCALLOW:
421 return mcd_lock_door(sc, MCD_LK_UNLOCK);
422 case CDIOCPREVENT:
423 return mcd_lock_door(sc, MCD_LK_LOCK);
424 case CDIOCCLOSE:
425 return mcd_inject(sc);
426 }
427
439 if (!(cd->flags & MCDVALID)) {
440 if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN))
441 || !(cd->status & MCDDSKIN))
428 if (!(sc->data.flags & MCDVALID)) {
429 if ( (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN))
430 || !(sc->data.status & MCDDSKIN))
442 for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
431 for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
443 (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsn2", hz/WAIT_FRAC);
432 (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn2", hz/WAIT_FRAC);
444 if ((r = mcd_getstat(sc, 1)) == -1)
433 if ((r = mcd_getstat(sc, 1)) == -1)
445 return EIO;
434 return (EIO);
446 if (r != -2)
447 break;
448 }
435 if (r != -2)
436 break;
437 }
449 if ( (cd->status & (MCDDOOROPEN|MCDDSKCHNG))
450 || !(cd->status & MCDDSKIN)
438 if ( (sc->data.status & (MCDDOOROPEN|MCDDSKCHNG))
439 || !(sc->data.status & MCDDSKIN)
451 || mcdsize(dev) < 0
452 )
440 || mcdsize(dev) < 0
441 )
453 return ENXIO;
454 cd->flags |= MCDVALID;
455 cd->partflags |= MCDREADRAW;
442 return (ENXIO);
443 sc->data.flags |= MCDVALID;
444 sc->data.partflags |= MCDREADRAW;
456 (void) mcd_lock_door(sc, MCD_LK_LOCK);
445 (void) mcd_lock_door(sc, MCD_LK_LOCK);
457 if (!(cd->flags & MCDVALID))
458 return ENXIO;
446 if (!(sc->data.flags & MCDVALID))
447 return (ENXIO);
459 }
460
461 switch (cmd) {
462 case DIOCGMEDIASIZE:
448 }
449
450 switch (cmd) {
451 case DIOCGMEDIASIZE:
463 *(off_t *)addr = (off_t)cd->disksize * cd->blksize;
452 *(off_t *)addr = (off_t)sc->data.disksize * sc->data.blksize;
464 return (0);
465 break;
466 case DIOCGSECTORSIZE:
453 return (0);
454 break;
455 case DIOCGSECTORSIZE:
467 *(u_int *)addr = cd->blksize;
456 *(u_int *)addr = sc->data.blksize;
468 return (0);
469 break;
470
471 case CDIOCPLAYTRACKS:
472 return mcd_playtracks(sc, (struct ioc_play_track *) addr);
473 case CDIOCPLAYBLOCKS:
474 return mcd_playblocks(sc, (struct ioc_play_blocks *) addr);
475 case CDIOCPLAYMSF:

--- 5 unchanged lines hidden (view full) ---

481 case CDIOREADTOCENTRYS:
482 return mcd_toc_entrys(sc, (struct ioc_read_toc_entry *) addr);
483 case CDIOCRESUME:
484 return mcd_resume(sc);
485 case CDIOCPAUSE:
486 return mcd_pause(sc);
487 case CDIOCSTART:
488 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
457 return (0);
458 break;
459
460 case CDIOCPLAYTRACKS:
461 return mcd_playtracks(sc, (struct ioc_play_track *) addr);
462 case CDIOCPLAYBLOCKS:
463 return mcd_playblocks(sc, (struct ioc_play_blocks *) addr);
464 case CDIOCPLAYMSF:

--- 5 unchanged lines hidden (view full) ---

470 case CDIOREADTOCENTRYS:
471 return mcd_toc_entrys(sc, (struct ioc_read_toc_entry *) addr);
472 case CDIOCRESUME:
473 return mcd_resume(sc);
474 case CDIOCPAUSE:
475 return mcd_pause(sc);
476 case CDIOCSTART:
477 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
489 return EIO;
490 return 0;
478 return (EIO);
479 return (0);
491 case CDIOCSTOP:
492 return mcd_stop(sc);
493 default:
480 case CDIOCSTOP:
481 return mcd_stop(sc);
482 default:
494 return ENOTTY;
483 return (ENOTTY);
495 }
496 /*NOTREACHED*/
497}
498
499static int
500mcdsize(dev_t dev)
501{
502 struct mcd_softc *sc;
484 }
485 /*NOTREACHED*/
486}
487
488static int
489mcdsize(dev_t dev)
490{
491 struct mcd_softc *sc;
503 struct mcd_data *cd;
504 int size;
505
506 sc = (struct mcd_softc *)dev->si_drv1;
492 int size;
493
494 sc = (struct mcd_softc *)dev->si_drv1;
507 cd = &sc->data;
508
509 if (mcd_volinfo(sc) == 0) {
495
496 if (mcd_volinfo(sc) == 0) {
510 cd->blksize = MCDBLK;
511 size = msf2hsg(cd->volinfo.vol_msf, 0);
512 cd->disksize = size * (MCDBLK/DEV_BSIZE);
513 return 0;
497 sc->data.blksize = MCDBLK;
498 size = msf2hsg(sc->data.volinfo.vol_msf, 0);
499 sc->data.disksize = size * (MCDBLK/DEV_BSIZE);
500 return (0);
514 }
501 }
515 return -1;
502 return (-1);
516}
517
518/***************************************************************
519 * lower level of driver starts here
520 **************************************************************/
521
522#ifdef NOTDEF
523static char

--- 19 unchanged lines hidden (view full) ---

543/* Wait for non-busy - return 0 on timeout */
544static int
545twiddle_thumbs(struct mcd_softc *sc, int count, char *whine)
546{
547 int i;
548
549 for (i = 0; i < count; i++) {
550 if (!(MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL))
503}
504
505/***************************************************************
506 * lower level of driver starts here
507 **************************************************************/
508
509#ifdef NOTDEF
510static char

--- 19 unchanged lines hidden (view full) ---

530/* Wait for non-busy - return 0 on timeout */
531static int
532twiddle_thumbs(struct mcd_softc *sc, int count, char *whine)
533{
534 int i;
535
536 for (i = 0; i < count; i++) {
537 if (!(MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL))
551 return 1;
538 return (1);
552 }
553 if (bootverbose)
554 device_printf(sc->dev, "timeout %s\n", whine);
539 }
540 if (bootverbose)
541 device_printf(sc->dev, "timeout %s\n", whine);
555 return 0;
542 return (0);
556}
557
558/* check to see if a Mitsumi CD-ROM is attached to the ISA bus */
559
560int
561mcd_probe(struct mcd_softc *sc)
562{
563 int unit;

--- 65 unchanged lines hidden (view full) ---

629 sc->data.name = "Mitsumi ???";
630 break;
631 }
632
633 if (bootverbose)
634 device_printf(sc->dev, "type %s, version info: %c %x\n",
635 sc->data.name, stbytes[1], stbytes[2]);
636
543}
544
545/* check to see if a Mitsumi CD-ROM is attached to the ISA bus */
546
547int
548mcd_probe(struct mcd_softc *sc)
549{
550 int unit;

--- 65 unchanged lines hidden (view full) ---

616 sc->data.name = "Mitsumi ???";
617 break;
618 }
619
620 if (bootverbose)
621 device_printf(sc->dev, "type %s, version info: %c %x\n",
622 sc->data.name, stbytes[1], stbytes[2]);
623
637 return 0;
624 return (0);
638}
639
640
641static int
642mcd_waitrdy(struct mcd_softc *sc, int dly)
643{
644 int i;
645
646 /* wait until flag port senses status ready */
647 for (i=0; i<dly; i+=MIN_DELAY) {
648 if (!(MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL))
625}
626
627
628static int
629mcd_waitrdy(struct mcd_softc *sc, int dly)
630{
631 int i;
632
633 /* wait until flag port senses status ready */
634 for (i=0; i<dly; i+=MIN_DELAY) {
635 if (!(MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL))
649 return 0;
636 return (0);
650 DELAY(MIN_DELAY);
651 }
637 DELAY(MIN_DELAY);
638 }
652 return -1;
639 return (-1);
653}
654
655static int
656mcd_getreply(struct mcd_softc *sc, int dly)
657{
658
659 /* wait data to become ready */
660 if (mcd_waitrdy(sc, dly)<0) {
661 device_printf(sc->dev, "timeout getreply\n");
640}
641
642static int
643mcd_getreply(struct mcd_softc *sc, int dly)
644{
645
646 /* wait data to become ready */
647 if (mcd_waitrdy(sc, dly)<0) {
648 device_printf(sc->dev, "timeout getreply\n");
662 return -1;
649 return (-1);
663 }
664
665 /* get the data */
650 }
651
652 /* get the data */
666 return MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
653 return (MCD_READ(sc, MCD_REG_STATUS) & 0xFF);
667}
668
669static int
670mcd_getstat(struct mcd_softc *sc, int sflg)
671{
672 int i;
654}
655
656static int
657mcd_getstat(struct mcd_softc *sc, int sflg)
658{
659 int i;
673 struct mcd_data *cd = &sc->data;
674
675 /* get the status */
676 if (sflg)
677 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDGETSTAT);
678 i = mcd_getreply(sc, DELAY_GETREPLY);
679 if (i<0 || (i & MCD_ST_CMDCHECK)) {
660
661 /* get the status */
662 if (sflg)
663 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDGETSTAT);
664 i = mcd_getreply(sc, DELAY_GETREPLY);
665 if (i<0 || (i & MCD_ST_CMDCHECK)) {
680 cd->curr_mode = MCD_MD_UNKNOWN;
681 return -1;
666 sc->data.curr_mode = MCD_MD_UNKNOWN;
667 return (-1);
682 }
683
668 }
669
684 cd->status = i;
670 sc->data.status = i;
685
686 if (mcd_setflags(sc) < 0)
671
672 if (mcd_setflags(sc) < 0)
687 return -2;
688 return cd->status;
673 return (-2);
674 return (sc->data.status);
689}
690
691static int
692mcd_setflags(struct mcd_softc *sc)
693{
675}
676
677static int
678mcd_setflags(struct mcd_softc *sc)
679{
694 struct mcd_data *cd = &sc->data;
695
696 /* check flags */
680
681 /* check flags */
697 if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN))
698 || !(cd->status & MCDDSKIN)) {
682 if ( (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN))
683 || !(sc->data.status & MCDDSKIN)) {
699 MCD_TRACE("setflags: sensed DSKCHNG or DOOROPEN or !DSKIN\n");
700 mcd_soft_reset(sc);
684 MCD_TRACE("setflags: sensed DSKCHNG or DOOROPEN or !DSKIN\n");
685 mcd_soft_reset(sc);
701 return -1;
686 return (-1);
702 }
703
687 }
688
704 if (cd->status & MCDAUDIOBSY)
705 cd->audio_status = CD_AS_PLAY_IN_PROGRESS;
706 else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS)
707 cd->audio_status = CD_AS_PLAY_COMPLETED;
708 return 0;
689 if (sc->data.status & MCDAUDIOBSY)
690 sc->data.audio_status = CD_AS_PLAY_IN_PROGRESS;
691 else if (sc->data.audio_status == CD_AS_PLAY_IN_PROGRESS)
692 sc->data.audio_status = CD_AS_PLAY_COMPLETED;
693 return (0);
709}
710
711static int
712mcd_get(struct mcd_softc *sc, char *buf, int nmax)
713{
714 int i,k;
715
716 for (i=0; i<nmax; i++) {
717 /* wait for data */
718 if ((k = mcd_getreply(sc, DELAY_GETREPLY)) < 0) {
719 device_printf(sc->dev, "timeout mcd_get\n");
694}
695
696static int
697mcd_get(struct mcd_softc *sc, char *buf, int nmax)
698{
699 int i,k;
700
701 for (i=0; i<nmax; i++) {
702 /* wait for data */
703 if ((k = mcd_getreply(sc, DELAY_GETREPLY)) < 0) {
704 device_printf(sc->dev, "timeout mcd_get\n");
720 return -1;
705 return (-1);
721 }
722 buf[i] = k;
723 }
706 }
707 buf[i] = k;
708 }
724 return i;
709 return (i);
725}
726
727static int
728mcd_send(struct mcd_softc *sc, int cmd,int nretrys)
729{
730 int i,k=0;
731
732/*MCD_TRACE("mcd_send: command = 0x%02x\n",cmd,0,0,0);*/
733 for (i=0; i<nretrys; i++) {
734 MCD_WRITE(sc, MCD_REG_COMMAND, cmd);
735 if ((k=mcd_getstat(sc, 0)) != -1)
736 break;
737 }
738 if (k == -2) {
739 device_printf(sc->dev, "media changed\n");
710}
711
712static int
713mcd_send(struct mcd_softc *sc, int cmd,int nretrys)
714{
715 int i,k=0;
716
717/*MCD_TRACE("mcd_send: command = 0x%02x\n",cmd,0,0,0);*/
718 for (i=0; i<nretrys; i++) {
719 MCD_WRITE(sc, MCD_REG_COMMAND, cmd);
720 if ((k=mcd_getstat(sc, 0)) != -1)
721 break;
722 }
723 if (k == -2) {
724 device_printf(sc->dev, "media changed\n");
740 return -1;
725 return (-1);
741 }
742 if (i == nretrys) {
743 device_printf(sc->dev, "mcd_send retry cnt exceeded\n");
726 }
727 if (i == nretrys) {
728 device_printf(sc->dev, "mcd_send retry cnt exceeded\n");
744 return -1;
729 return (-1);
745 }
746/*MCD_TRACE("mcd_send: done\n",0,0,0,0);*/
730 }
731/*MCD_TRACE("mcd_send: done\n",0,0,0,0);*/
747 return 0;
732 return (0);
748}
749
750static void
751hsg2msf(int hsg, bcd_t *msf)
752{
753 hsg += 150;
754 F_msf(msf) = bin2bcd(hsg % 75);
755 hsg /= 75;

--- 7 unchanged lines hidden (view full) ---

763{
764 return (bcd2bin(M_msf(msf)) * 60 + bcd2bin(S_msf(msf))) * 75 +
765 bcd2bin(F_msf(msf)) - (!relative) * 150;
766}
767
768static int
769mcd_volinfo(struct mcd_softc *sc)
770{
733}
734
735static void
736hsg2msf(int hsg, bcd_t *msf)
737{
738 hsg += 150;
739 F_msf(msf) = bin2bcd(hsg % 75);
740 hsg /= 75;

--- 7 unchanged lines hidden (view full) ---

748{
749 return (bcd2bin(M_msf(msf)) * 60 + bcd2bin(S_msf(msf))) * 75 +
750 bcd2bin(F_msf(msf)) - (!relative) * 150;
751}
752
753static int
754mcd_volinfo(struct mcd_softc *sc)
755{
771 struct mcd_data *cd = &sc->data;
772
773 /* Just return if we already have it */
756
757 /* Just return if we already have it */
774 if (cd->flags & MCDVOLINFO) return 0;
758 if (sc->data.flags & MCDVOLINFO) return (0);
775
776/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/
777
778 /* send volume info command */
779 if (mcd_send(sc, MCD_CMDGETVOLINFO,MCD_RETRYS) < 0)
759
760/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/
761
762 /* send volume info command */
763 if (mcd_send(sc, MCD_CMDGETVOLINFO,MCD_RETRYS) < 0)
780 return EIO;
764 return (EIO);
781
782 /* get data */
765
766 /* get data */
783 if (mcd_get(sc, (char*) &cd->volinfo,sizeof(struct mcd_volinfo)) < 0) {
767 if (mcd_get(sc, (char*) &sc->data.volinfo,sizeof(struct mcd_volinfo)) < 0) {
784 device_printf(sc->dev, "mcd_volinfo: error read data\n");
768 device_printf(sc->dev, "mcd_volinfo: error read data\n");
785 return EIO;
769 return (EIO);
786 }
787
770 }
771
788 if (cd->volinfo.trk_low > 0 &&
789 cd->volinfo.trk_high >= cd->volinfo.trk_low
772 if (sc->data.volinfo.trk_low > 0 &&
773 sc->data.volinfo.trk_high >= sc->data.volinfo.trk_low
790 ) {
774 ) {
791 cd->flags |= MCDVOLINFO; /* volinfo is OK */
792 return 0;
775 sc->data.flags |= MCDVOLINFO; /* volinfo is OK */
776 return (0);
793 }
794
777 }
778
795 return EINVAL;
779 return (EINVAL);
796}
797
798/* state machine to process read requests
799 * initialize with MCD_S_BEGIN: calculate sizes, and read status
800 * MCD_S_WAITSTAT: wait for status reply, set mode
801 * MCD_S_WAITMODE: waits for status reply from set mode, set read command
802 * MCD_S_WAITREAD: wait for read ready, read data
803 */

--- 7 unchanged lines hidden (view full) ---

811 mcd_doread(sc, sc->ch_state, sc->ch_mbxsave);
812}
813
814static void
815mcd_doread(struct mcd_softc *sc, int state, struct mcd_mbx *mbxin)
816{
817 struct mcd_mbx *mbx;
818 struct bio *bp;
780}
781
782/* state machine to process read requests
783 * initialize with MCD_S_BEGIN: calculate sizes, and read status
784 * MCD_S_WAITSTAT: wait for status reply, set mode
785 * MCD_S_WAITMODE: waits for status reply from set mode, set read command
786 * MCD_S_WAITREAD: wait for read ready, read data
787 */

--- 7 unchanged lines hidden (view full) ---

795 mcd_doread(sc, sc->ch_state, sc->ch_mbxsave);
796}
797
798static void
799mcd_doread(struct mcd_softc *sc, int state, struct mcd_mbx *mbxin)
800{
801 struct mcd_mbx *mbx;
802 struct bio *bp;
819 struct mcd_data *cd;
820 int rm, i, k;
821 struct mcd_read2 rbuf;
822 int blknum;
823 caddr_t addr;
824
825 mbx = (state!=MCD_S_BEGIN) ? sc->ch_mbxsave : mbxin;
826 bp = mbx->bp;
803 int rm, i, k;
804 struct mcd_read2 rbuf;
805 int blknum;
806 caddr_t addr;
807
808 mbx = (state!=MCD_S_BEGIN) ? sc->ch_mbxsave : mbxin;
809 bp = mbx->bp;
827 cd = &sc->data;
828
829loop:
830 switch (state) {
831 case MCD_S_BEGIN:
832 mbx = sc->ch_mbxsave = mbxin;
833
834 case MCD_S_BEGIN1:
835retry_status:

--- 7 unchanged lines hidden (view full) ---

843 sc->ch_state = MCD_S_WAITSTAT;
844 untimeout(mcd_timeout,(caddr_t)sc, sc->ch);
845 if (mbx->count-- >= 0) {
846 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) {
847 sc->ch_state = MCD_S_WAITSTAT;
848 timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
849 return;
850 }
810
811loop:
812 switch (state) {
813 case MCD_S_BEGIN:
814 mbx = sc->ch_mbxsave = mbxin;
815
816 case MCD_S_BEGIN1:
817retry_status:

--- 7 unchanged lines hidden (view full) ---

825 sc->ch_state = MCD_S_WAITSTAT;
826 untimeout(mcd_timeout,(caddr_t)sc, sc->ch);
827 if (mbx->count-- >= 0) {
828 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) {
829 sc->ch_state = MCD_S_WAITSTAT;
830 timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
831 return;
832 }
851 cd->status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
852 if (cd->status & MCD_ST_CMDCHECK)
833 sc->data.status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
834 if (sc->data.status & MCD_ST_CMDCHECK)
853 goto retry_status;
854 if (mcd_setflags(sc) < 0)
855 goto changed;
856 MCD_TRACE("got WAITSTAT delay=%d\n",
857 RDELAY_WAITSTAT-mbx->count);
858 /* reject, if audio active */
835 goto retry_status;
836 if (mcd_setflags(sc) < 0)
837 goto changed;
838 MCD_TRACE("got WAITSTAT delay=%d\n",
839 RDELAY_WAITSTAT-mbx->count);
840 /* reject, if audio active */
859 if (cd->status & MCDAUDIOBSY) {
841 if (sc->data.status & MCDAUDIOBSY) {
860 device_printf(sc->dev, "audio is active\n");
861 goto readerr;
862 }
863
864retry_mode:
865 /* to check for raw/cooked mode */
842 device_printf(sc->dev, "audio is active\n");
843 goto readerr;
844 }
845
846retry_mode:
847 /* to check for raw/cooked mode */
866 if (cd->flags & MCDREADRAW) {
848 if (sc->data.flags & MCDREADRAW) {
867 rm = MCD_MD_RAW;
868 mbx->sz = MCDRBLK;
869 } else {
870 rm = MCD_MD_COOKED;
849 rm = MCD_MD_RAW;
850 mbx->sz = MCDRBLK;
851 } else {
852 rm = MCD_MD_COOKED;
871 mbx->sz = cd->blksize;
853 mbx->sz = sc->data.blksize;
872 }
873
854 }
855
874 if (rm == cd->curr_mode)
856 if (rm == sc->data.curr_mode)
875 goto modedone;
876
877 mbx->count = RDELAY_WAITMODE;
878
857 goto modedone;
858
859 mbx->count = RDELAY_WAITMODE;
860
879 cd->curr_mode = MCD_MD_UNKNOWN;
861 sc->data.curr_mode = MCD_MD_UNKNOWN;
880 mbx->mode = rm;
881 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSETMODE);
882 MCD_WRITE(sc, MCD_REG_COMMAND, rm);
883
884 sc->ch_state = MCD_S_WAITMODE;
885 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
886 return;
887 } else {

--- 8 unchanged lines hidden (view full) ---

896 device_printf(sc->dev, "timeout set mode\n");
897 goto readerr;
898 }
899 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) {
900 sc->ch_state = MCD_S_WAITMODE;
901 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100);
902 return;
903 }
862 mbx->mode = rm;
863 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSETMODE);
864 MCD_WRITE(sc, MCD_REG_COMMAND, rm);
865
866 sc->ch_state = MCD_S_WAITMODE;
867 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
868 return;
869 } else {

--- 8 unchanged lines hidden (view full) ---

878 device_printf(sc->dev, "timeout set mode\n");
879 goto readerr;
880 }
881 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) {
882 sc->ch_state = MCD_S_WAITMODE;
883 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100);
884 return;
885 }
904 cd->status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
905 if (cd->status & MCD_ST_CMDCHECK) {
906 cd->curr_mode = MCD_MD_UNKNOWN;
886 sc->data.status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
887 if (sc->data.status & MCD_ST_CMDCHECK) {
888 sc->data.curr_mode = MCD_MD_UNKNOWN;
907 goto retry_mode;
908 }
909 if (mcd_setflags(sc) < 0)
910 goto changed;
889 goto retry_mode;
890 }
891 if (mcd_setflags(sc) < 0)
892 goto changed;
911 cd->curr_mode = mbx->mode;
893 sc->data.curr_mode = mbx->mode;
912 MCD_TRACE("got WAITMODE delay=%d\n",
913 RDELAY_WAITMODE-mbx->count);
914modedone:
915 /* for first block */
916 mbx->nblk = (bp->bio_bcount + (mbx->sz-1)) / mbx->sz;
917 mbx->skip = 0;
918
919nextblock:
920 blknum = (bp->bio_blkno / (mbx->sz/DEV_BSIZE))
921 + mbx->skip/mbx->sz;
922
923 MCD_TRACE("mcd_doread: read blknum=%d for bp=%p\n",
924 blknum, bp);
925
926 /* build parameter block */
927 hsg2msf(blknum,rbuf.start_msf);
928retry_read:
929 /* send the read command */
930 disable_intr();
894 MCD_TRACE("got WAITMODE delay=%d\n",
895 RDELAY_WAITMODE-mbx->count);
896modedone:
897 /* for first block */
898 mbx->nblk = (bp->bio_bcount + (mbx->sz-1)) / mbx->sz;
899 mbx->skip = 0;
900
901nextblock:
902 blknum = (bp->bio_blkno / (mbx->sz/DEV_BSIZE))
903 + mbx->skip/mbx->sz;
904
905 MCD_TRACE("mcd_doread: read blknum=%d for bp=%p\n",
906 blknum, bp);
907
908 /* build parameter block */
909 hsg2msf(blknum,rbuf.start_msf);
910retry_read:
911 /* send the read command */
912 disable_intr();
931 MCD_WRITE(sc, MCD_REG_COMMAND, cd->read_command);
913 MCD_WRITE(sc, MCD_REG_COMMAND, sc->data.read_command);
932 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[0]);
933 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[1]);
934 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[2]);
935 MCD_WRITE(sc, MCD_REG_COMMAND, 0);
936 MCD_WRITE(sc, MCD_REG_COMMAND, 0);
937 MCD_WRITE(sc, MCD_REG_COMMAND, 1);
938 enable_intr();
939

--- 39 unchanged lines hidden (view full) ---

979 mbx->skip += mbx->sz;
980 goto nextblock;
981 }
982
983 /* return buffer */
984 bp->bio_resid = 0;
985 biodone(bp);
986
914 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[0]);
915 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[1]);
916 MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[2]);
917 MCD_WRITE(sc, MCD_REG_COMMAND, 0);
918 MCD_WRITE(sc, MCD_REG_COMMAND, 0);
919 MCD_WRITE(sc, MCD_REG_COMMAND, 1);
920 enable_intr();
921

--- 39 unchanged lines hidden (view full) ---

961 mbx->skip += mbx->sz;
962 goto nextblock;
963 }
964
965 /* return buffer */
966 bp->bio_resid = 0;
967 biodone(bp);
968
987 cd->flags &= ~(MCDMBXBSY|MCDREADRAW);
969 sc->data.flags &= ~(MCDMBXBSY|MCDREADRAW);
988 mcd_start(sc);
989 return;
990 }
991 if (!(k & MFL_STATUS_NOT_AVAIL)) {
970 mcd_start(sc);
971 return;
972 }
973 if (!(k & MFL_STATUS_NOT_AVAIL)) {
992 cd->status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
993 if (cd->status & MCD_ST_CMDCHECK)
974 sc->data.status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF;
975 if (sc->data.status & MCD_ST_CMDCHECK)
994 goto retry_read;
995 if (mcd_setflags(sc) < 0)
996 goto changed;
997 }
998 sc->ch_state = MCD_S_WAITREAD;
999 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
1000 return;
1001 } else {

--- 9 unchanged lines hidden (view full) ---

1011 goto loop;
1012 }
1013harderr:
1014 /* invalidate the buffer */
1015 bp->bio_flags |= BIO_ERROR;
1016 bp->bio_resid = bp->bio_bcount;
1017 biodone(bp);
1018
976 goto retry_read;
977 if (mcd_setflags(sc) < 0)
978 goto changed;
979 }
980 sc->ch_state = MCD_S_WAITREAD;
981 sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */
982 return;
983 } else {

--- 9 unchanged lines hidden (view full) ---

993 goto loop;
994 }
995harderr:
996 /* invalidate the buffer */
997 bp->bio_flags |= BIO_ERROR;
998 bp->bio_resid = bp->bio_bcount;
999 biodone(bp);
1000
1019 cd->flags &= ~(MCDMBXBSY|MCDREADRAW);
1001 sc->data.flags &= ~(MCDMBXBSY|MCDREADRAW);
1020 mcd_start(sc);
1021 return;
1022
1023changed:
1024 device_printf(sc->dev, "media changed\n");
1025 goto harderr;
1026
1027#ifdef NOTDEF
1028 device_printf(sc->dev, "unit timeout, resetting\n");
1029 MCD_WRITE(sc, MCD_REG_RESET, MCD_CMDRESET);
1030 DELAY(300000);
1031 (void)mcd_getstat(sc, 1);
1032 (void)mcd_getstat(sc, 1);
1002 mcd_start(sc);
1003 return;
1004
1005changed:
1006 device_printf(sc->dev, "media changed\n");
1007 goto harderr;
1008
1009#ifdef NOTDEF
1010 device_printf(sc->dev, "unit timeout, resetting\n");
1011 MCD_WRITE(sc, MCD_REG_RESET, MCD_CMDRESET);
1012 DELAY(300000);
1013 (void)mcd_getstat(sc, 1);
1014 (void)mcd_getstat(sc, 1);
1033 /*cd->status &= ~MCDDSKCHNG; */
1034 cd->debug = 1; /* preventive set debug mode */
1015 /*sc->data.status &= ~MCDDSKCHNG; */
1016 sc->data.debug = 1; /* preventive set debug mode */
1035
1036#endif
1037
1038}
1039
1040static int
1041mcd_lock_door(struct mcd_softc *sc, int lock)
1042{
1043
1044 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDLOCKDRV);
1045 MCD_WRITE(sc, MCD_REG_COMMAND, lock);
1046 if (mcd_getstat(sc, 0) == -1)
1017
1018#endif
1019
1020}
1021
1022static int
1023mcd_lock_door(struct mcd_softc *sc, int lock)
1024{
1025
1026 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDLOCKDRV);
1027 MCD_WRITE(sc, MCD_REG_COMMAND, lock);
1028 if (mcd_getstat(sc, 0) == -1)
1047 return EIO;
1048 return 0;
1029 return (EIO);
1030 return (0);
1049}
1050
1051static int
1052mcd_close_tray(struct mcd_softc *sc)
1053{
1031}
1032
1033static int
1034mcd_close_tray(struct mcd_softc *sc)
1035{
1054 struct mcd_data *cd = &sc->data;
1055 int retry, r;
1056
1057 if (mcd_getstat(sc, 1) == -1)
1036 int retry, r;
1037
1038 if (mcd_getstat(sc, 1) == -1)
1058 return EIO;
1059 if (cd->status & MCDDOOROPEN) {
1039 return (EIO);
1040 if (sc->data.status & MCDDOOROPEN) {
1060 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDCLOSETRAY);
1061 for (retry = 0; retry < CLOSE_TRAY_SECS * WAIT_FRAC; retry++) {
1062 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL)
1041 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDCLOSETRAY);
1042 for (retry = 0; retry < CLOSE_TRAY_SECS * WAIT_FRAC; retry++) {
1043 if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL)
1063 (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdcls", hz/WAIT_FRAC);
1044 (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdcls", hz/WAIT_FRAC);
1064 else {
1065 if ((r = mcd_getstat(sc, 0)) == -1)
1045 else {
1046 if ((r = mcd_getstat(sc, 0)) == -1)
1066 return EIO;
1067 return 0;
1047 return (EIO);
1048 return (0);
1068 }
1069 }
1049 }
1050 }
1070 return ENXIO;
1051 return (ENXIO);
1071 }
1052 }
1072 return 0;
1053 return (0);
1073}
1074
1075static int
1076mcd_eject(struct mcd_softc *sc)
1077{
1054}
1055
1056static int
1057mcd_eject(struct mcd_softc *sc)
1058{
1078 struct mcd_data *cd = &sc->data;
1079 int r;
1080
1081 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
1059 int r;
1060
1061 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
1082 return EIO;
1083 if (cd->status & MCDDOOROPEN)
1084 return 0;
1062 return (EIO);
1063 if (sc->data.status & MCDDOOROPEN)
1064 return (0);
1085 if ((r = mcd_stop(sc)) == EIO)
1065 if ((r = mcd_stop(sc)) == EIO)
1086 return r;
1066 return (r);
1087 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDEJECTDISK);
1088 if (mcd_getstat(sc, 0) == -1)
1067 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDEJECTDISK);
1068 if (mcd_getstat(sc, 0) == -1)
1089 return EIO;
1090 return 0;
1069 return (EIO);
1070 return (0);
1091}
1092
1093static int
1094mcd_inject(struct mcd_softc *sc)
1095{
1071}
1072
1073static int
1074mcd_inject(struct mcd_softc *sc)
1075{
1096 struct mcd_data *cd = &sc->data;
1097
1098 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
1076
1077 if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
1099 return EIO;
1100 if (cd->status & MCDDOOROPEN)
1078 return (EIO);
1079 if (sc->data.status & MCDDOOROPEN)
1101 return mcd_close_tray(sc);
1080 return mcd_close_tray(sc);
1102 return 0;
1081 return (0);
1103}
1104
1105static int
1106mcd_hard_reset(struct mcd_softc *sc)
1107{
1082}
1083
1084static int
1085mcd_hard_reset(struct mcd_softc *sc)
1086{
1108 struct mcd_data *cd = &sc->data;
1109
1110 MCD_WRITE(sc, MCD_REG_RESET, MCD_CMDRESET);
1087
1088 MCD_WRITE(sc, MCD_REG_RESET, MCD_CMDRESET);
1111 cd->curr_mode = MCD_MD_UNKNOWN;
1112 cd->audio_status = CD_AS_AUDIO_INVALID;
1113 return 0;
1089 sc->data.curr_mode = MCD_MD_UNKNOWN;
1090 sc->data.audio_status = CD_AS_AUDIO_INVALID;
1091 return (0);
1114}
1115
1116static void
1117mcd_soft_reset(struct mcd_softc *sc)
1118{
1092}
1093
1094static void
1095mcd_soft_reset(struct mcd_softc *sc)
1096{
1119 struct mcd_data *cd = &sc->data;
1120
1097
1121 cd->flags &= (MCDINIT|MCDPROBING|MCDNEWMODEL);
1122 cd->curr_mode = MCD_MD_UNKNOWN;
1123 cd->partflags = 0;
1124 cd->audio_status = CD_AS_AUDIO_INVALID;
1098 sc->data.flags &= (MCDINIT|MCDPROBING|MCDNEWMODEL);
1099 sc->data.curr_mode = MCD_MD_UNKNOWN;
1100 sc->data.partflags = 0;
1101 sc->data.audio_status = CD_AS_AUDIO_INVALID;
1125}
1126
1127static int
1128mcd_setmode(struct mcd_softc *sc, int mode)
1129{
1102}
1103
1104static int
1105mcd_setmode(struct mcd_softc *sc, int mode)
1106{
1130 struct mcd_data *cd = &sc->data;
1131 int retry, st;
1132
1107 int retry, st;
1108
1133 if (cd->curr_mode == mode)
1134 return 0;
1135 if (cd->debug)
1109 if (sc->data.curr_mode == mode)
1110 return (0);
1111 if (sc->data.debug)
1136 device_printf(sc->dev, "setting mode to %d\n", mode);
1137 for(retry=0; retry<MCD_RETRYS; retry++)
1138 {
1112 device_printf(sc->dev, "setting mode to %d\n", mode);
1113 for(retry=0; retry<MCD_RETRYS; retry++)
1114 {
1139 cd->curr_mode = MCD_MD_UNKNOWN;
1115 sc->data.curr_mode = MCD_MD_UNKNOWN;
1140 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSETMODE);
1141 MCD_WRITE(sc, MCD_REG_COMMAND, mode);
1142 if ((st = mcd_getstat(sc, 0)) >= 0) {
1116 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSETMODE);
1117 MCD_WRITE(sc, MCD_REG_COMMAND, mode);
1118 if ((st = mcd_getstat(sc, 0)) >= 0) {
1143 cd->curr_mode = mode;
1144 return 0;
1119 sc->data.curr_mode = mode;
1120 return (0);
1145 }
1146 if (st == -2) {
1147 device_printf(sc->dev, "media changed\n");
1148 break;
1149 }
1150 }
1151
1121 }
1122 if (st == -2) {
1123 device_printf(sc->dev, "media changed\n");
1124 break;
1125 }
1126 }
1127
1152 return -1;
1128 return (-1);
1153}
1154
1155static int
1156mcd_toc_header(struct mcd_softc *sc, struct ioc_toc_header *th)
1157{
1129}
1130
1131static int
1132mcd_toc_header(struct mcd_softc *sc, struct ioc_toc_header *th)
1133{
1158 struct mcd_data *cd = &sc->data;
1159 int r;
1160
1161 if ((r = mcd_volinfo(sc)) != 0)
1134 int r;
1135
1136 if ((r = mcd_volinfo(sc)) != 0)
1162 return r;
1137 return (r);
1163
1138
1164 th->starting_track = bcd2bin(cd->volinfo.trk_low);
1165 th->ending_track = bcd2bin(cd->volinfo.trk_high);
1139 th->starting_track = bcd2bin(sc->data.volinfo.trk_low);
1140 th->ending_track = bcd2bin(sc->data.volinfo.trk_high);
1166 th->len = 2 * sizeof(u_char) /* start & end tracks */ +
1167 (th->ending_track + 1 - th->starting_track + 1) *
1168 sizeof(struct cd_toc_entry);
1169
1141 th->len = 2 * sizeof(u_char) /* start & end tracks */ +
1142 (th->ending_track + 1 - th->starting_track + 1) *
1143 sizeof(struct cd_toc_entry);
1144
1170 return 0;
1145 return (0);
1171}
1172
1173static int
1174mcd_read_toc(struct mcd_softc *sc)
1175{
1146}
1147
1148static int
1149mcd_read_toc(struct mcd_softc *sc)
1150{
1176 struct mcd_data *cd = &sc->data;
1177 struct ioc_toc_header th;
1178 struct mcd_qchninfo q;
1179 int rc, trk, idx, retry;
1180
1181 /* Only read TOC if needed */
1151 struct ioc_toc_header th;
1152 struct mcd_qchninfo q;
1153 int rc, trk, idx, retry;
1154
1155 /* Only read TOC if needed */
1182 if (cd->flags & MCDTOC)
1183 return 0;
1156 if (sc->data.flags & MCDTOC)
1157 return (0);
1184
1158
1185 if (cd->debug)
1159 if (sc->data.debug)
1186 device_printf(sc->dev, "reading toc header\n");
1187
1188 if ((rc = mcd_toc_header(sc, &th)) != 0)
1160 device_printf(sc->dev, "reading toc header\n");
1161
1162 if ((rc = mcd_toc_header(sc, &th)) != 0)
1189 return rc;
1163 return (rc);
1190
1191 if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0)
1164
1165 if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0)
1192 return EIO;
1166 return (EIO);
1193
1194 if (mcd_setmode(sc, MCD_MD_TOC) != 0)
1167
1168 if (mcd_setmode(sc, MCD_MD_TOC) != 0)
1195 return EIO;
1169 return (EIO);
1196
1170
1197 if (cd->debug)
1171 if (sc->data.debug)
1198 device_printf(sc->dev, "get_toc reading qchannel info\n");
1199
1200 for(trk=th.starting_track; trk<=th.ending_track; trk++)
1172 device_printf(sc->dev, "get_toc reading qchannel info\n");
1173
1174 for(trk=th.starting_track; trk<=th.ending_track; trk++)
1201 cd->toc[trk].idx_no = 0;
1175 sc->data.toc[trk].idx_no = 0;
1202 trk = th.ending_track - th.starting_track + 1;
1203 for(retry=0; retry<600 && trk>0; retry++)
1204 {
1205 if (mcd_getqchan(sc, &q) < 0) break;
1206 idx = bcd2bin(q.idx_no);
1207 if (idx>=th.starting_track && idx<=th.ending_track && q.trk_no==0) {
1176 trk = th.ending_track - th.starting_track + 1;
1177 for(retry=0; retry<600 && trk>0; retry++)
1178 {
1179 if (mcd_getqchan(sc, &q) < 0) break;
1180 idx = bcd2bin(q.idx_no);
1181 if (idx>=th.starting_track && idx<=th.ending_track && q.trk_no==0) {
1208 if (cd->toc[idx].idx_no == 0) {
1209 cd->toc[idx] = q;
1182 if (sc->data.toc[idx].idx_no == 0) {
1183 sc->data.toc[idx] = q;
1210 trk--;
1211 }
1212 }
1213 }
1214
1215 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1184 trk--;
1185 }
1186 }
1187 }
1188
1189 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1216 return EIO;
1190 return (EIO);
1217
1218 if (trk != 0)
1191
1192 if (trk != 0)
1219 return ENXIO;
1193 return (ENXIO);
1220
1221 /* add a fake last+1 */
1222 idx = th.ending_track + 1;
1194
1195 /* add a fake last+1 */
1196 idx = th.ending_track + 1;
1223 cd->toc[idx].control = cd->toc[idx-1].control;
1224 cd->toc[idx].addr_type = cd->toc[idx-1].addr_type;
1225 cd->toc[idx].trk_no = 0;
1226 cd->toc[idx].idx_no = MCD_LASTPLUS1;
1227 cd->toc[idx].hd_pos_msf[0] = cd->volinfo.vol_msf[0];
1228 cd->toc[idx].hd_pos_msf[1] = cd->volinfo.vol_msf[1];
1229 cd->toc[idx].hd_pos_msf[2] = cd->volinfo.vol_msf[2];
1197 sc->data.toc[idx].control = sc->data.toc[idx-1].control;
1198 sc->data.toc[idx].addr_type = sc->data.toc[idx-1].addr_type;
1199 sc->data.toc[idx].trk_no = 0;
1200 sc->data.toc[idx].idx_no = MCD_LASTPLUS1;
1201 sc->data.toc[idx].hd_pos_msf[0] = sc->data.volinfo.vol_msf[0];
1202 sc->data.toc[idx].hd_pos_msf[1] = sc->data.volinfo.vol_msf[1];
1203 sc->data.toc[idx].hd_pos_msf[2] = sc->data.volinfo.vol_msf[2];
1230
1204
1231 if (cd->debug)
1205 if (sc->data.debug)
1232 { int i;
1233 for (i = th.starting_track; i <= idx; i++)
1234 device_printf(sc->dev, "trk %d idx %d pos %d %d %d\n",
1235 i,
1206 { int i;
1207 for (i = th.starting_track; i <= idx; i++)
1208 device_printf(sc->dev, "trk %d idx %d pos %d %d %d\n",
1209 i,
1236 cd->toc[i].idx_no > 0x99 ? cd->toc[i].idx_no :
1237 bcd2bin(cd->toc[i].idx_no),
1238 bcd2bin(cd->toc[i].hd_pos_msf[0]),
1239 bcd2bin(cd->toc[i].hd_pos_msf[1]),
1240 bcd2bin(cd->toc[i].hd_pos_msf[2]));
1210 sc->data.toc[i].idx_no > 0x99 ? sc->data.toc[i].idx_no :
1211 bcd2bin(sc->data.toc[i].idx_no),
1212 bcd2bin(sc->data.toc[i].hd_pos_msf[0]),
1213 bcd2bin(sc->data.toc[i].hd_pos_msf[1]),
1214 bcd2bin(sc->data.toc[i].hd_pos_msf[2]));
1241 }
1242
1215 }
1216
1243 cd->flags |= MCDTOC;
1217 sc->data.flags |= MCDTOC;
1244
1218
1245 return 0;
1219 return (0);
1246}
1247
1248#if 0
1249static int
1250mcd_toc_entry(struct mcd_softc *sc, struct ioc_read_toc_single_entry *te)
1251{
1220}
1221
1222#if 0
1223static int
1224mcd_toc_entry(struct mcd_softc *sc, struct ioc_read_toc_single_entry *te)
1225{
1252 struct mcd_data *cd = &sc->data;
1253 struct ioc_toc_header th;
1254 int rc, trk;
1255
1256 if (te->address_format != CD_MSF_FORMAT
1257 && te->address_format != CD_LBA_FORMAT)
1226 struct ioc_toc_header th;
1227 int rc, trk;
1228
1229 if (te->address_format != CD_MSF_FORMAT
1230 && te->address_format != CD_LBA_FORMAT)
1258 return EINVAL;
1231 return (EINVAL);
1259
1260 /* Copy the toc header */
1261 if ((rc = mcd_toc_header(sc, &th)) != 0)
1232
1233 /* Copy the toc header */
1234 if ((rc = mcd_toc_header(sc, &th)) != 0)
1262 return rc;
1235 return (rc);
1263
1264 /* verify starting track */
1265 trk = te->track;
1266 if (trk == 0)
1267 trk = th.starting_track;
1268 else if (trk == MCD_LASTPLUS1)
1269 trk = th.ending_track + 1;
1270 else if (trk < th.starting_track || trk > th.ending_track + 1)
1236
1237 /* verify starting track */
1238 trk = te->track;
1239 if (trk == 0)
1240 trk = th.starting_track;
1241 else if (trk == MCD_LASTPLUS1)
1242 trk = th.ending_track + 1;
1243 else if (trk < th.starting_track || trk > th.ending_track + 1)
1271 return EINVAL;
1244 return (EINVAL);
1272
1273 /* Make sure we have a valid toc */
1274 if ((rc=mcd_read_toc(sc)) != 0)
1245
1246 /* Make sure we have a valid toc */
1247 if ((rc=mcd_read_toc(sc)) != 0)
1275 return rc;
1248 return (rc);
1276
1277 /* Copy the TOC data. */
1249
1250 /* Copy the TOC data. */
1278 if (cd->toc[trk].idx_no == 0)
1279 return EIO;
1251 if (sc->data.toc[trk].idx_no == 0)
1252 return (EIO);
1280
1253
1281 te->entry.control = cd->toc[trk].control;
1282 te->entry.addr_type = cd->toc[trk].addr_type;
1254 te->entry.control = sc->data.toc[trk].control;
1255 te->entry.addr_type = sc->data.toc[trk].addr_type;
1283 te->entry.track =
1256 te->entry.track =
1284 cd->toc[trk].idx_no > 0x99 ? cd->toc[trk].idx_no :
1285 bcd2bin(cd->toc[trk].idx_no);
1257 sc->data.toc[trk].idx_no > 0x99 ? sc->data.toc[trk].idx_no :
1258 bcd2bin(sc->data.toc[trk].idx_no);
1286 switch (te->address_format) {
1287 case CD_MSF_FORMAT:
1288 te->entry.addr.msf.unused = 0;
1259 switch (te->address_format) {
1260 case CD_MSF_FORMAT:
1261 te->entry.addr.msf.unused = 0;
1289 te->entry.addr.msf.minute = bcd2bin(cd->toc[trk].hd_pos_msf[0]);
1290 te->entry.addr.msf.second = bcd2bin(cd->toc[trk].hd_pos_msf[1]);
1291 te->entry.addr.msf.frame = bcd2bin(cd->toc[trk].hd_pos_msf[2]);
1262 te->entry.addr.msf.minute = bcd2bin(sc->data.toc[trk].hd_pos_msf[0]);
1263 te->entry.addr.msf.second = bcd2bin(sc->data.toc[trk].hd_pos_msf[1]);
1264 te->entry.addr.msf.frame = bcd2bin(sc->data.toc[trk].hd_pos_msf[2]);
1292 break;
1293 case CD_LBA_FORMAT:
1265 break;
1266 case CD_LBA_FORMAT:
1294 te->entry.addr.lba = htonl(msf2hsg(cd->toc[trk].hd_pos_msf, 0));
1267 te->entry.addr.lba = htonl(msf2hsg(sc->data.toc[trk].hd_pos_msf, 0));
1295 break;
1296 }
1268 break;
1269 }
1297 return 0;
1270 return (0);
1298}
1299#endif
1300
1301static int
1302mcd_toc_entrys(struct mcd_softc *sc, struct ioc_read_toc_entry *te)
1303{
1271}
1272#endif
1273
1274static int
1275mcd_toc_entrys(struct mcd_softc *sc, struct ioc_read_toc_entry *te)
1276{
1304 struct mcd_data *cd = &sc->data;
1305 struct cd_toc_entry entries[MCD_MAXTOCS];
1306 struct ioc_toc_header th;
1307 int rc, n, trk, len;
1308
1309 if ( te->data_len < sizeof(entries[0])
1310 || (te->data_len % sizeof(entries[0])) != 0
1311 || (te->address_format != CD_MSF_FORMAT
1312 && te->address_format != CD_LBA_FORMAT)
1313 )
1277 struct cd_toc_entry entries[MCD_MAXTOCS];
1278 struct ioc_toc_header th;
1279 int rc, n, trk, len;
1280
1281 if ( te->data_len < sizeof(entries[0])
1282 || (te->data_len % sizeof(entries[0])) != 0
1283 || (te->address_format != CD_MSF_FORMAT
1284 && te->address_format != CD_LBA_FORMAT)
1285 )
1314 return EINVAL;
1286 return (EINVAL);
1315
1316 /* Copy the toc header */
1317 if ((rc = mcd_toc_header(sc, &th)) != 0)
1287
1288 /* Copy the toc header */
1289 if ((rc = mcd_toc_header(sc, &th)) != 0)
1318 return rc;
1290 return (rc);
1319
1320 /* verify starting track */
1321 trk = te->starting_track;
1322 if (trk == 0)
1323 trk = th.starting_track;
1324 else if (trk == MCD_LASTPLUS1)
1325 trk = th.ending_track + 1;
1326 else if (trk < th.starting_track || trk > th.ending_track + 1)
1291
1292 /* verify starting track */
1293 trk = te->starting_track;
1294 if (trk == 0)
1295 trk = th.starting_track;
1296 else if (trk == MCD_LASTPLUS1)
1297 trk = th.ending_track + 1;
1298 else if (trk < th.starting_track || trk > th.ending_track + 1)
1327 return EINVAL;
1299 return (EINVAL);
1328
1329 len = ((th.ending_track + 1 - trk) + 1) *
1330 sizeof(entries[0]);
1331 if (te->data_len < len)
1332 len = te->data_len;
1333 if (len > sizeof(entries))
1300
1301 len = ((th.ending_track + 1 - trk) + 1) *
1302 sizeof(entries[0]);
1303 if (te->data_len < len)
1304 len = te->data_len;
1305 if (len > sizeof(entries))
1334 return EINVAL;
1306 return (EINVAL);
1335
1336 /* Make sure we have a valid toc */
1337 if ((rc=mcd_read_toc(sc)) != 0)
1307
1308 /* Make sure we have a valid toc */
1309 if ((rc=mcd_read_toc(sc)) != 0)
1338 return rc;
1310 return (rc);
1339
1340 /* Copy the TOC data. */
1341 for (n = 0; len > 0 && trk <= th.ending_track + 1; trk++) {
1311
1312 /* Copy the TOC data. */
1313 for (n = 0; len > 0 && trk <= th.ending_track + 1; trk++) {
1342 if (cd->toc[trk].idx_no == 0)
1314 if (sc->data.toc[trk].idx_no == 0)
1343 continue;
1315 continue;
1344 entries[n].control = cd->toc[trk].control;
1345 entries[n].addr_type = cd->toc[trk].addr_type;
1316 entries[n].control = sc->data.toc[trk].control;
1317 entries[n].addr_type = sc->data.toc[trk].addr_type;
1346 entries[n].track =
1318 entries[n].track =
1347 cd->toc[trk].idx_no > 0x99 ? cd->toc[trk].idx_no :
1348 bcd2bin(cd->toc[trk].idx_no);
1319 sc->data.toc[trk].idx_no > 0x99 ? sc->data.toc[trk].idx_no :
1320 bcd2bin(sc->data.toc[trk].idx_no);
1349 switch (te->address_format) {
1350 case CD_MSF_FORMAT:
1351 entries[n].addr.msf.unused = 0;
1321 switch (te->address_format) {
1322 case CD_MSF_FORMAT:
1323 entries[n].addr.msf.unused = 0;
1352 entries[n].addr.msf.minute = bcd2bin(cd->toc[trk].hd_pos_msf[0]);
1353 entries[n].addr.msf.second = bcd2bin(cd->toc[trk].hd_pos_msf[1]);
1354 entries[n].addr.msf.frame = bcd2bin(cd->toc[trk].hd_pos_msf[2]);
1324 entries[n].addr.msf.minute = bcd2bin(sc->data.toc[trk].hd_pos_msf[0]);
1325 entries[n].addr.msf.second = bcd2bin(sc->data.toc[trk].hd_pos_msf[1]);
1326 entries[n].addr.msf.frame = bcd2bin(sc->data.toc[trk].hd_pos_msf[2]);
1355 break;
1356 case CD_LBA_FORMAT:
1327 break;
1328 case CD_LBA_FORMAT:
1357 entries[n].addr.lba = htonl(msf2hsg(cd->toc[trk].hd_pos_msf, 0));
1329 entries[n].addr.lba = htonl(msf2hsg(sc->data.toc[trk].hd_pos_msf, 0));
1358 break;
1359 }
1360 len -= sizeof(struct cd_toc_entry);
1361 n++;
1362 }
1363
1364 /* copy the data back */
1365 return copyout(entries, te->data, n * sizeof(struct cd_toc_entry));
1366}
1367
1368static int
1369mcd_stop(struct mcd_softc *sc)
1370{
1330 break;
1331 }
1332 len -= sizeof(struct cd_toc_entry);
1333 n++;
1334 }
1335
1336 /* copy the data back */
1337 return copyout(entries, te->data, n * sizeof(struct cd_toc_entry));
1338}
1339
1340static int
1341mcd_stop(struct mcd_softc *sc)
1342{
1371 struct mcd_data *cd = &sc->data;
1372
1373 /* Verify current status */
1343
1344 /* Verify current status */
1374 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS &&
1375 cd->audio_status != CD_AS_PLAY_PAUSED &&
1376 cd->audio_status != CD_AS_PLAY_COMPLETED) {
1377 if (cd->debug)
1345 if (sc->data.audio_status != CD_AS_PLAY_IN_PROGRESS &&
1346 sc->data.audio_status != CD_AS_PLAY_PAUSED &&
1347 sc->data.audio_status != CD_AS_PLAY_COMPLETED) {
1348 if (sc->data.debug)
1378 device_printf(sc->dev,
1379 "stop attempted when not playing, audio status %d\n",
1349 device_printf(sc->dev,
1350 "stop attempted when not playing, audio status %d\n",
1380 cd->audio_status);
1381 return EINVAL;
1351 sc->data.audio_status);
1352 return (EINVAL);
1382 }
1353 }
1383 if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS)
1354 if (sc->data.audio_status == CD_AS_PLAY_IN_PROGRESS)
1384 if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0)
1355 if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0)
1385 return EIO;
1386 cd->audio_status = CD_AS_PLAY_COMPLETED;
1387 return 0;
1356 return (EIO);
1357 sc->data.audio_status = CD_AS_PLAY_COMPLETED;
1358 return (0);
1388}
1389
1390static int
1391mcd_getqchan(struct mcd_softc *sc, struct mcd_qchninfo *q)
1392{
1359}
1360
1361static int
1362mcd_getqchan(struct mcd_softc *sc, struct mcd_qchninfo *q)
1363{
1393 struct mcd_data *cd = &sc->data;
1394
1395 if (mcd_send(sc, MCD_CMDGETQCHN, MCD_RETRYS) < 0)
1364
1365 if (mcd_send(sc, MCD_CMDGETQCHN, MCD_RETRYS) < 0)
1396 return -1;
1366 return (-1);
1397 if (mcd_get(sc, (char *) q, sizeof(struct mcd_qchninfo)) < 0)
1367 if (mcd_get(sc, (char *) q, sizeof(struct mcd_qchninfo)) < 0)
1398 return -1;
1399 if (cd->debug) {
1368 return (-1);
1369 if (sc->data.debug) {
1400 device_printf(sc->dev,
1401 "getqchan control=0x%x addr_type=0x%x trk=%d ind=%d ttm=%d:%d.%d dtm=%d:%d.%d\n",
1402 q->control, q->addr_type,
1403 bcd2bin(q->trk_no),
1404 bcd2bin(q->idx_no),
1405 bcd2bin(q->trk_size_msf[0]),
1406 bcd2bin(q->trk_size_msf[1]),
1407 bcd2bin(q->trk_size_msf[2]),
1408 bcd2bin(q->hd_pos_msf[0]),
1409 bcd2bin(q->hd_pos_msf[1]),
1410 bcd2bin(q->hd_pos_msf[2]));
1411 }
1370 device_printf(sc->dev,
1371 "getqchan control=0x%x addr_type=0x%x trk=%d ind=%d ttm=%d:%d.%d dtm=%d:%d.%d\n",
1372 q->control, q->addr_type,
1373 bcd2bin(q->trk_no),
1374 bcd2bin(q->idx_no),
1375 bcd2bin(q->trk_size_msf[0]),
1376 bcd2bin(q->trk_size_msf[1]),
1377 bcd2bin(q->trk_size_msf[2]),
1378 bcd2bin(q->hd_pos_msf[0]),
1379 bcd2bin(q->hd_pos_msf[1]),
1380 bcd2bin(q->hd_pos_msf[2]));
1381 }
1412 return 0;
1382 return (0);
1413}
1414
1415static int
1416mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch)
1417{
1383}
1384
1385static int
1386mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch)
1387{
1418 struct mcd_data *cd = &sc->data;
1419 struct mcd_qchninfo q;
1420 struct cd_sub_channel_info data;
1421 int lba;
1422
1388 struct mcd_qchninfo q;
1389 struct cd_sub_channel_info data;
1390 int lba;
1391
1423 if (cd->debug)
1392 if (sc->data.debug)
1424 device_printf(sc->dev, "subchan af=%d, df=%d\n",
1425 sch->address_format,
1426 sch->data_format);
1427
1428 if (sch->address_format != CD_MSF_FORMAT &&
1429 sch->address_format != CD_LBA_FORMAT)
1393 device_printf(sc->dev, "subchan af=%d, df=%d\n",
1394 sch->address_format,
1395 sch->data_format);
1396
1397 if (sch->address_format != CD_MSF_FORMAT &&
1398 sch->address_format != CD_LBA_FORMAT)
1430 return EINVAL;
1399 return (EINVAL);
1431
1432 if (sch->data_format != CD_CURRENT_POSITION &&
1433 sch->data_format != CD_MEDIA_CATALOG)
1400
1401 if (sch->data_format != CD_CURRENT_POSITION &&
1402 sch->data_format != CD_MEDIA_CATALOG)
1434 return EINVAL;
1403 return (EINVAL);
1435
1436 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1404
1405 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1437 return EIO;
1406 return (EIO);
1438
1439 if (mcd_getqchan(sc, &q) < 0)
1407
1408 if (mcd_getqchan(sc, &q) < 0)
1440 return EIO;
1409 return (EIO);
1441
1410
1442 data.header.audio_status = cd->audio_status;
1411 data.header.audio_status = sc->data.audio_status;
1443 data.what.position.data_format = sch->data_format;
1444
1445 switch (sch->data_format) {
1446 case CD_MEDIA_CATALOG:
1447 data.what.media_catalog.mc_valid = 1;
1448 data.what.media_catalog.mc_number[0] = '\0';
1449 break;
1450

--- 30 unchanged lines hidden (view full) ---

1481 }
1482
1483 return copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len));
1484}
1485
1486static int
1487mcd_playmsf(struct mcd_softc *sc, struct ioc_play_msf *p)
1488{
1412 data.what.position.data_format = sch->data_format;
1413
1414 switch (sch->data_format) {
1415 case CD_MEDIA_CATALOG:
1416 data.what.media_catalog.mc_valid = 1;
1417 data.what.media_catalog.mc_number[0] = '\0';
1418 break;
1419

--- 30 unchanged lines hidden (view full) ---

1450 }
1451
1452 return copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len));
1453}
1454
1455static int
1456mcd_playmsf(struct mcd_softc *sc, struct ioc_play_msf *p)
1457{
1489 struct mcd_data *cd = &sc->data;
1490 struct mcd_read2 pb;
1491
1458 struct mcd_read2 pb;
1459
1492 if (cd->debug)
1460 if (sc->data.debug)
1493 device_printf(sc->dev, "playmsf: from %d:%d.%d to %d:%d.%d\n",
1494 p->start_m, p->start_s, p->start_f,
1495 p->end_m, p->end_s, p->end_f);
1496
1497 if ((p->start_m * 60 * 75 + p->start_s * 75 + p->start_f) >=
1498 (p->end_m * 60 * 75 + p->end_s * 75 + p->end_f) ||
1499 (p->end_m * 60 * 75 + p->end_s * 75 + p->end_f) >
1461 device_printf(sc->dev, "playmsf: from %d:%d.%d to %d:%d.%d\n",
1462 p->start_m, p->start_s, p->start_f,
1463 p->end_m, p->end_s, p->end_f);
1464
1465 if ((p->start_m * 60 * 75 + p->start_s * 75 + p->start_f) >=
1466 (p->end_m * 60 * 75 + p->end_s * 75 + p->end_f) ||
1467 (p->end_m * 60 * 75 + p->end_s * 75 + p->end_f) >
1500 M_msf(cd->volinfo.vol_msf) * 60 * 75 +
1501 S_msf(cd->volinfo.vol_msf) * 75 +
1502 F_msf(cd->volinfo.vol_msf))
1503 return EINVAL;
1468 M_msf(sc->data.volinfo.vol_msf) * 60 * 75 +
1469 S_msf(sc->data.volinfo.vol_msf) * 75 +
1470 F_msf(sc->data.volinfo.vol_msf))
1471 return (EINVAL);
1504
1505 pb.start_msf[0] = bin2bcd(p->start_m);
1506 pb.start_msf[1] = bin2bcd(p->start_s);
1507 pb.start_msf[2] = bin2bcd(p->start_f);
1508 pb.end_msf[0] = bin2bcd(p->end_m);
1509 pb.end_msf[1] = bin2bcd(p->end_s);
1510 pb.end_msf[2] = bin2bcd(p->end_f);
1511
1512 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1472
1473 pb.start_msf[0] = bin2bcd(p->start_m);
1474 pb.start_msf[1] = bin2bcd(p->start_s);
1475 pb.start_msf[2] = bin2bcd(p->start_f);
1476 pb.end_msf[0] = bin2bcd(p->end_m);
1477 pb.end_msf[1] = bin2bcd(p->end_s);
1478 pb.end_msf[2] = bin2bcd(p->end_f);
1479
1480 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1513 return EIO;
1481 return (EIO);
1514
1515 return mcd_play(sc, &pb);
1516}
1517
1518static int
1519mcd_playtracks(struct mcd_softc *sc, struct ioc_play_track *pt)
1520{
1482
1483 return mcd_play(sc, &pb);
1484}
1485
1486static int
1487mcd_playtracks(struct mcd_softc *sc, struct ioc_play_track *pt)
1488{
1521 struct mcd_data *cd = &sc->data;
1522 struct mcd_read2 pb;
1523 int a = pt->start_track;
1524 int z = pt->end_track;
1525 int rc, i;
1526
1527 if ((rc = mcd_read_toc(sc)) != 0)
1489 struct mcd_read2 pb;
1490 int a = pt->start_track;
1491 int z = pt->end_track;
1492 int rc, i;
1493
1494 if ((rc = mcd_read_toc(sc)) != 0)
1528 return rc;
1495 return (rc);
1529
1496
1530 if (cd->debug)
1497 if (sc->data.debug)
1531 device_printf(sc->dev, "playtracks from %d:%d to %d:%d\n",
1532 a, pt->start_index, z, pt->end_index);
1533
1498 device_printf(sc->dev, "playtracks from %d:%d to %d:%d\n",
1499 a, pt->start_index, z, pt->end_index);
1500
1534 if ( a < bcd2bin(cd->volinfo.trk_low)
1535 || a > bcd2bin(cd->volinfo.trk_high)
1501 if ( a < bcd2bin(sc->data.volinfo.trk_low)
1502 || a > bcd2bin(sc->data.volinfo.trk_high)
1536 || a > z
1503 || a > z
1537 || z < bcd2bin(cd->volinfo.trk_low)
1538 || z > bcd2bin(cd->volinfo.trk_high))
1539 return EINVAL;
1504 || z < bcd2bin(sc->data.volinfo.trk_low)
1505 || z > bcd2bin(sc->data.volinfo.trk_high))
1506 return (EINVAL);
1540
1541 for (i = 0; i < 3; i++) {
1507
1508 for (i = 0; i < 3; i++) {
1542 pb.start_msf[i] = cd->toc[a].hd_pos_msf[i];
1543 pb.end_msf[i] = cd->toc[z+1].hd_pos_msf[i];
1509 pb.start_msf[i] = sc->data.toc[a].hd_pos_msf[i];
1510 pb.end_msf[i] = sc->data.toc[z+1].hd_pos_msf[i];
1544 }
1545
1546 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1511 }
1512
1513 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1547 return EIO;
1514 return (EIO);
1548
1549 return mcd_play(sc, &pb);
1550}
1551
1552static int
1553mcd_playblocks(struct mcd_softc *sc, struct ioc_play_blocks *p)
1554{
1515
1516 return mcd_play(sc, &pb);
1517}
1518
1519static int
1520mcd_playblocks(struct mcd_softc *sc, struct ioc_play_blocks *p)
1521{
1555 struct mcd_data *cd = &sc->data;
1556 struct mcd_read2 pb;
1557
1522 struct mcd_read2 pb;
1523
1558 if (cd->debug)
1524 if (sc->data.debug)
1559 device_printf(sc->dev, "playblocks: blkno %d length %d\n",
1560 p->blk, p->len);
1561
1525 device_printf(sc->dev, "playblocks: blkno %d length %d\n",
1526 p->blk, p->len);
1527
1562 if (p->blk > cd->disksize || p->len > cd->disksize ||
1528 if (p->blk > sc->data.disksize || p->len > sc->data.disksize ||
1563 p->blk < 0 || p->len < 0 ||
1529 p->blk < 0 || p->len < 0 ||
1564 (p->blk + p->len) > cd->disksize)
1565 return EINVAL;
1530 (p->blk + p->len) > sc->data.disksize)
1531 return (EINVAL);
1566
1567 hsg2msf(p->blk, pb.start_msf);
1568 hsg2msf(p->blk + p->len, pb.end_msf);
1569
1570 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1532
1533 hsg2msf(p->blk, pb.start_msf);
1534 hsg2msf(p->blk + p->len, pb.end_msf);
1535
1536 if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
1571 return EIO;
1537 return (EIO);
1572
1573 return mcd_play(sc, &pb);
1574}
1575
1576static int
1577mcd_play(struct mcd_softc *sc, struct mcd_read2 *pb)
1578{
1538
1539 return mcd_play(sc, &pb);
1540}
1541
1542static int
1543mcd_play(struct mcd_softc *sc, struct mcd_read2 *pb)
1544{
1579 struct mcd_data *cd = &sc->data;
1580 int retry, st = -1, status;
1581
1545 int retry, st = -1, status;
1546
1582 cd->lastpb = *pb;
1547 sc->data.lastpb = *pb;
1583 for(retry=0; retry<MCD_RETRYS; retry++) {
1584
1585 disable_intr();
1586 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSINGLESPEEDREAD);
1587 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[0]);
1588 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[1]);
1589 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[2]);
1590 MCD_WRITE(sc, MCD_REG_COMMAND, pb->end_msf[0]);

--- 6 unchanged lines hidden (view full) ---

1597 continue;
1598 else if (status != -2)
1599 st = 0;
1600 break;
1601 }
1602
1603 if (status == -2) {
1604 device_printf(sc->dev, "media changed\n");
1548 for(retry=0; retry<MCD_RETRYS; retry++) {
1549
1550 disable_intr();
1551 MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDSINGLESPEEDREAD);
1552 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[0]);
1553 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[1]);
1554 MCD_WRITE(sc, MCD_REG_COMMAND, pb->start_msf[2]);
1555 MCD_WRITE(sc, MCD_REG_COMMAND, pb->end_msf[0]);

--- 6 unchanged lines hidden (view full) ---

1562 continue;
1563 else if (status != -2)
1564 st = 0;
1565 break;
1566 }
1567
1568 if (status == -2) {
1569 device_printf(sc->dev, "media changed\n");
1605 return ENXIO;
1570 return (ENXIO);
1606 }
1571 }
1607 if (cd->debug)
1572 if (sc->data.debug)
1608 device_printf(sc->dev,
1609 "mcd_play retry=%d, status=0x%02x\n", retry, status);
1610 if (st < 0)
1573 device_printf(sc->dev,
1574 "mcd_play retry=%d, status=0x%02x\n", retry, status);
1575 if (st < 0)
1611 return ENXIO;
1612 cd->audio_status = CD_AS_PLAY_IN_PROGRESS;
1613 return 0;
1576 return (ENXIO);
1577 sc->data.audio_status = CD_AS_PLAY_IN_PROGRESS;
1578 return (0);
1614}
1615
1616static int
1617mcd_pause(struct mcd_softc *sc)
1618{
1579}
1580
1581static int
1582mcd_pause(struct mcd_softc *sc)
1583{
1619 struct mcd_data *cd = &sc->data;
1620 struct mcd_qchninfo q;
1621 int rc;
1622
1623 /* Verify current status */
1584 struct mcd_qchninfo q;
1585 int rc;
1586
1587 /* Verify current status */
1624 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS &&
1625 cd->audio_status != CD_AS_PLAY_PAUSED) {
1626 if (cd->debug)
1588 if (sc->data.audio_status != CD_AS_PLAY_IN_PROGRESS &&
1589 sc->data.audio_status != CD_AS_PLAY_PAUSED) {
1590 if (sc->data.debug)
1627 device_printf(sc->dev,
1628 "pause attempted when not playing, audio status %d\n",
1591 device_printf(sc->dev,
1592 "pause attempted when not playing, audio status %d\n",
1629 cd->audio_status);
1630 return EINVAL;
1593 sc->data.audio_status);
1594 return (EINVAL);
1631 }
1632
1633 /* Get the current position */
1634 if (mcd_getqchan(sc, &q) < 0)
1595 }
1596
1597 /* Get the current position */
1598 if (mcd_getqchan(sc, &q) < 0)
1635 return EIO;
1599 return (EIO);
1636
1637 /* Copy it into lastpb */
1600
1601 /* Copy it into lastpb */
1638 cd->lastpb.start_msf[0] = q.hd_pos_msf[0];
1639 cd->lastpb.start_msf[1] = q.hd_pos_msf[1];
1640 cd->lastpb.start_msf[2] = q.hd_pos_msf[2];
1602 sc->data.lastpb.start_msf[0] = q.hd_pos_msf[0];
1603 sc->data.lastpb.start_msf[1] = q.hd_pos_msf[1];
1604 sc->data.lastpb.start_msf[2] = q.hd_pos_msf[2];
1641
1642 /* Stop playing */
1643 if ((rc=mcd_stop(sc)) != 0)
1605
1606 /* Stop playing */
1607 if ((rc=mcd_stop(sc)) != 0)
1644 return rc;
1608 return (rc);
1645
1646 /* Set the proper status and exit */
1609
1610 /* Set the proper status and exit */
1647 cd->audio_status = CD_AS_PLAY_PAUSED;
1648 return 0;
1611 sc->data.audio_status = CD_AS_PLAY_PAUSED;
1612 return (0);
1649}
1650
1651static int
1652mcd_resume(struct mcd_softc *sc)
1653{
1613}
1614
1615static int
1616mcd_resume(struct mcd_softc *sc)
1617{
1654 struct mcd_data *cd = &sc->data;
1655
1618
1656 if (cd->audio_status != CD_AS_PLAY_PAUSED)
1657 return EINVAL;
1658 return mcd_play(sc, &cd->lastpb);
1619 if (sc->data.audio_status != CD_AS_PLAY_PAUSED)
1620 return (EINVAL);
1621 return mcd_play(sc, &sc->data.lastpb);
1659}
1622}