File:  [DragonFly] / src / sys / dev / disk / ata / atapi-cd.c
Revision 1.12: download - view: text, annotated - select for diffs
Mon Mar 8 15:13:56 2004 UTC (10 years, 6 months ago) by joerg
Branches: MAIN
CVS tags: HEAD
Handle failure in atapi_queue_cmd correctly

    1: /*-
    2:  * Copyright (c) 1998,1999,2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer,
   10:  *    without modification, immediately at the beginning of the file.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  * 3. The name of the author may not be used to endorse or promote products
   15:  *    derived from this software without specific prior written permission.
   16:  *
   17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27:  *
   28:  * $FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.48.2.20 2002/11/25 05:30:31 njl Exp $
   29:  * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.12 2004/03/08 15:13:56 joerg Exp $
   30:  */
   31: 
   32: #include "opt_ata.h"
   33: #include <sys/param.h>
   34: #include <sys/systm.h>
   35: #include <sys/ata.h>
   36: #include <sys/kernel.h>
   37: #include <sys/malloc.h>
   38: #include <sys/proc.h>
   39: #include <sys/buf.h>
   40: #include <sys/bus.h>
   41: #include <sys/disklabel.h>
   42: #include <sys/devicestat.h>
   43: #include <sys/cdio.h>
   44: #include <sys/cdrio.h>
   45: #include <sys/dvdio.h>
   46: #include <sys/fcntl.h>
   47: #include <sys/conf.h>
   48: #include <sys/ctype.h>
   49: #include <machine/bus.h>
   50: #include <sys/buf2.h>
   51: #include "ata-all.h"
   52: #include "atapi-all.h"
   53: #include "atapi-cd.h"
   54: 
   55: /* device structures */
   56: static d_open_t		acdopen;
   57: static d_close_t	acdclose;
   58: static d_ioctl_t	acdioctl;
   59: static d_strategy_t	acdstrategy;
   60: 
   61: static struct cdevsw acd_cdevsw = {
   62: 	/* name */	"acd",
   63: 	/* maj */	117,
   64: 	/* flags */	D_DISK | D_TRACKCLOSE,
   65: 	/* port */      NULL,
   66: 	/* autoq */	0,
   67: 
   68: 	/* open */	acdopen,
   69: 	/* close */	acdclose,
   70: 	/* read */	physread,
   71: 	/* write */	physwrite,
   72: 	/* ioctl */	acdioctl,
   73: 	/* poll */	nopoll,
   74: 	/* mmap */	nommap,
   75: 	/* strategy */	acdstrategy,
   76: 	/* dump */	nodump,
   77: 	/* psize */	nopsize
   78: };
   79: 
   80: /* prototypes */
   81: static struct acd_softc *acd_init_lun(struct ata_device *);
   82: static void acd_make_dev(struct acd_softc *);
   83: static void acd_set_ioparm(struct acd_softc *);
   84: static void acd_describe(struct acd_softc *);
   85: static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
   86: static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
   87: static int acd_done(struct atapi_request *);
   88: static void acd_read_toc(struct acd_softc *);
   89: static int acd_play(struct acd_softc *, int, int);
   90: static int acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
   91: static void acd_select_slot(struct acd_softc *);
   92: static int acd_init_writer(struct acd_softc *, int);
   93: static int acd_fixate(struct acd_softc *, int);
   94: static int acd_init_track(struct acd_softc *, struct cdr_track *);
   95: static int acd_flush(struct acd_softc *);
   96: static int acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info *);
   97: static int acd_get_progress(struct acd_softc *, int *);
   98: static int acd_send_cue(struct acd_softc *, struct cdr_cuesheet *);
   99: static int acd_report_key(struct acd_softc *, struct dvd_authinfo *);
  100: static int acd_send_key(struct acd_softc *, struct dvd_authinfo *);
  101: static int acd_read_structure(struct acd_softc *, struct dvd_struct *);
  102: static int acd_eject(struct acd_softc *, int);
  103: static int acd_blank(struct acd_softc *, int);
  104: static int acd_prevent_allow(struct acd_softc *, int);
  105: static int acd_start_stop(struct acd_softc *, int);
  106: static int acd_pause_resume(struct acd_softc *, int);
  107: static int acd_mode_sense(struct acd_softc *, int, caddr_t, int);
  108: static int acd_mode_select(struct acd_softc *, caddr_t, int);
  109: static int acd_set_speed(struct acd_softc *, int, int);
  110: static void acd_get_cap(struct acd_softc *);
  111: 
  112: /* internal vars */
  113: static u_int32_t acd_lun_map = 0;
  114: static MALLOC_DEFINE(M_ACD, "ACD driver", "ATAPI CD driver buffers");
  115: 
  116: int
  117: acdattach(struct ata_device *atadev)
  118: {
  119:     struct acd_softc *cdp;
  120:     struct changer *chp;
  121: 
  122:     if ((cdp = acd_init_lun(atadev)) == NULL) {
  123: 	ata_prtdev(atadev, "acd: out of memory\n");
  124: 	return 0;
  125:     }
  126: 
  127:     ata_set_name(atadev, "acd", cdp->lun);
  128:     acd_get_cap(cdp);
  129: 
  130:     /* if this is a changer device, allocate the neeeded lun's */
  131:     if (cdp->cap.mech == MST_MECH_CHANGER) {
  132: 	int8_t ccb[16] = { ATAPI_MECH_STATUS, 0, 0, 0, 0, 0, 0, 0, 
  133: 			   sizeof(struct changer)>>8, sizeof(struct changer),
  134: 			   0, 0, 0, 0, 0, 0 };
  135: 
  136: 	chp = malloc(sizeof(struct changer), M_ACD, M_WAITOK | M_ZERO);
  137: 	if (chp == NULL) {
  138: 	    ata_prtdev(atadev, "out of memory\n");
  139: 	    free(cdp, M_ACD);
  140: 	    return 0;
  141: 	}
  142: 	if (!atapi_queue_cmd(cdp->device, ccb, (caddr_t)chp, 
  143: 			     sizeof(struct changer),
  144: 			     ATPR_F_READ, 60, NULL, NULL)) {
  145: 	    struct acd_softc *tmpcdp = cdp;
  146: 	    struct acd_softc **cdparr;
  147: 	    char *name;
  148: 	    int count;
  149: 
  150: 	    chp->table_length = htons(chp->table_length);
  151: 	    if (!(cdparr = malloc(sizeof(struct acd_softc) * chp->slots,
  152: 				  M_ACD, M_WAITOK))) {
  153: 		ata_prtdev(atadev, "out of memory\n");
  154: 		free(chp, M_ACD);
  155: 		free(cdp, M_ACD);
  156: 		return 0;
  157: 	    }
  158: 	    for (count = 0; count < chp->slots; count++) {
  159: 		if (count > 0) {
  160: 		    tmpcdp = acd_init_lun(atadev);
  161: 		    if (!tmpcdp) {
  162: 			ata_prtdev(atadev, "out of memory\n");
  163: 			break;
  164: 		    }
  165: 		}
  166: 		cdparr[count] = tmpcdp;
  167: 		tmpcdp->driver = cdparr;
  168: 		tmpcdp->slot = count;
  169: 		tmpcdp->changer_info = chp;
  170: 		acd_make_dev(tmpcdp);
  171: 		devstat_add_entry(tmpcdp->stats, "acd", tmpcdp->lun, DEV_BSIZE,
  172: 				  DEVSTAT_NO_ORDERED_TAGS,
  173: 				  DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
  174: 				  DEVSTAT_PRIORITY_CD);
  175: 	    }
  176: 	    name = malloc(strlen(atadev->name) + 2, M_ACD, M_WAITOK);
  177: 	    strcpy(name, atadev->name);
  178: 	    strcat(name, "-");
  179: 	    ata_free_name(atadev);
  180: 	    ata_set_name(atadev, name, cdp->lun + cdp->changer_info->slots - 1);
  181: 	    free(name, M_ACD);
  182: 	}
  183:     }
  184:     else {
  185: 	acd_make_dev(cdp);
  186: 	devstat_add_entry(cdp->stats, "acd", cdp->lun, DEV_BSIZE,
  187: 			  DEVSTAT_NO_ORDERED_TAGS,
  188: 			  DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
  189: 			  DEVSTAT_PRIORITY_CD);
  190:     }
  191:     acd_describe(cdp);
  192:     atadev->driver = cdp;
  193:     return 1;
  194: }
  195: 
  196: void
  197: acddetach(struct ata_device *atadev)
  198: {   
  199:     struct acd_softc *cdp = atadev->driver;
  200:     struct acd_devlist *entry;
  201:     struct buf *bp;
  202:     int subdev;
  203:     
  204:     if (cdp->changer_info) {
  205: 	for (subdev = 0; subdev < cdp->changer_info->slots; subdev++) {
  206: 	    if (cdp->driver[subdev] == cdp)
  207: 		continue;
  208: 	    while ((bp = bufq_first(&cdp->driver[subdev]->queue))) {
  209: 		bufq_remove(&cdp->driver[subdev]->queue, bp);
  210: 		bp->b_flags |= B_ERROR;
  211: 		bp->b_error = ENXIO;
  212: 		biodone(bp);
  213: 	    }
  214: 	    destroy_dev(cdp->driver[subdev]->dev);
  215: 	    while ((entry = TAILQ_FIRST(&cdp->driver[subdev]->dev_list))) {
  216: 		destroy_dev(entry->dev);
  217: 		TAILQ_REMOVE(&cdp->driver[subdev]->dev_list, entry, chain);
  218: 		free(entry, M_ACD);
  219: 	    }
  220: 	    devstat_remove_entry(cdp->driver[subdev]->stats);
  221: 	    free(cdp->driver[subdev]->stats, M_ACD);
  222: 	    ata_free_lun(&acd_lun_map, cdp->driver[subdev]->lun);
  223: 	    free(cdp->driver[subdev], M_ACD);
  224: 	}
  225: 	free(cdp->driver, M_ACD);
  226: 	free(cdp->changer_info, M_ACD);
  227:     }
  228:     while ((bp = bufq_first(&cdp->queue))) {
  229: 	bp->b_flags |= B_ERROR;
  230: 	bp->b_error = ENXIO;
  231: 	biodone(bp);
  232:     }
  233:     while ((entry = TAILQ_FIRST(&cdp->dev_list))) {
  234: 	destroy_dev(entry->dev);
  235: 	TAILQ_REMOVE(&cdp->dev_list, entry, chain);
  236: 	free(entry, M_ACD);
  237:     }
  238:     destroy_dev(cdp->dev);
  239:     devstat_remove_entry(cdp->stats);
  240:     free(cdp->stats, M_ACD);
  241:     ata_free_name(atadev);
  242:     ata_free_lun(&acd_lun_map, cdp->lun);
  243:     free(cdp, M_ACD);
  244:     atadev->driver = NULL;
  245: }
  246: 
  247: static struct acd_softc *
  248: acd_init_lun(struct ata_device *atadev)
  249: {
  250:     struct acd_softc *cdp;
  251: 
  252:     if (!(cdp = malloc(sizeof(struct acd_softc), M_ACD, M_WAITOK | M_ZERO)))
  253: 	return NULL;
  254:     TAILQ_INIT(&cdp->dev_list);
  255:     bufq_init(&cdp->queue);
  256:     cdp->device = atadev;
  257:     cdp->lun = ata_get_lun(&acd_lun_map);
  258:     cdp->block_size = 2048;
  259:     cdp->slot = -1;
  260:     cdp->changer_info = NULL;
  261:     if (!(cdp->stats = malloc(sizeof(struct devstat), M_ACD,
  262: 			      M_WAITOK | M_ZERO))) {
  263: 	free(cdp, M_ACD);
  264: 	return NULL;
  265:     }
  266:     return cdp;
  267: }
  268: 
  269: static void
  270: acd_make_dev(struct acd_softc *cdp)
  271: {
  272:     dev_t dev;
  273: 
  274:     dev = make_dev(&acd_cdevsw, dkmakeminor(cdp->lun, 0, 0),
  275: 		   UID_ROOT, GID_OPERATOR, 0644, "acd%d", cdp->lun);
  276:     dev->si_drv1 = cdp;
  277:     cdp->dev = dev;
  278:     cdp->device->flags |= ATA_D_MEDIA_CHANGED;
  279:     acd_set_ioparm(cdp);
  280: }
  281: 
  282: static void
  283: acd_set_ioparm(struct acd_softc *cdp)
  284: {
  285:      cdp->dev->si_iosize_max = ((256*DEV_BSIZE)/cdp->block_size)*cdp->block_size;
  286:      cdp->dev->si_bsize_phys = cdp->block_size;
  287: }
  288: 
  289: static void 
  290: acd_describe(struct acd_softc *cdp)
  291: {
  292:     int comma = 0;
  293:     char *mechanism;
  294: 
  295:     if (bootverbose) {
  296: 	ata_prtdev(cdp->device, "<%.40s/%.8s> %s drive at ata%d as %s\n",
  297: 		   cdp->device->param->model, cdp->device->param->revision,
  298: 		   (cdp->cap.write_dvdr) ? "DVD-R" : 
  299: 		    (cdp->cap.write_dvdram) ? "DVD-RAM" : 
  300: 		     (cdp->cap.write_cdrw) ? "CD-RW" :
  301: 		      (cdp->cap.write_cdr) ? "CD-R" : 
  302: 		       (cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM",
  303: 		   device_get_unit(cdp->device->channel->dev),
  304: 		   (cdp->device->unit == ATA_MASTER) ? "master" : "slave");
  305: 
  306: 	ata_prtdev(cdp->device, "%s", "");
  307: 	if (cdp->cap.cur_read_speed) {
  308: 	    printf("read %dKB/s", cdp->cap.cur_read_speed * 1000 / 1024);
  309: 	    if (cdp->cap.max_read_speed) 
  310: 		printf(" (%dKB/s)", cdp->cap.max_read_speed * 1000 / 1024);
  311: 	    if ((cdp->cap.cur_write_speed) &&
  312: 		(cdp->cap.write_cdr || cdp->cap.write_cdrw || 
  313: 		 cdp->cap.write_dvdr || cdp->cap.write_dvdram)) {
  314: 		printf(" write %dKB/s", cdp->cap.cur_write_speed * 1000 / 1024);
  315: 		if (cdp->cap.max_write_speed)
  316: 		    printf(" (%dKB/s)", cdp->cap.max_write_speed * 1000 / 1024);
  317: 	    }
  318: 	    comma = 1;
  319: 	}
  320: 	if (cdp->cap.buf_size) {
  321: 	    printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size);
  322: 	    comma = 1;
  323: 	}
  324: 	printf("%s %s\n", comma ? "," : "", ata_mode2str(cdp->device->mode));
  325: 
  326: 	ata_prtdev(cdp->device, "Reads:");
  327: 	comma = 0;
  328: 	if (cdp->cap.read_cdr) {
  329: 	    printf(" CD-R"); comma = 1;
  330: 	}
  331: 	if (cdp->cap.read_cdrw) {
  332: 	    printf("%s CD-RW", comma ? "," : ""); comma = 1;
  333: 	}
  334: 	if (cdp->cap.cd_da) {
  335: 	    if (cdp->cap.cd_da_stream)
  336: 		printf("%s CD-DA stream", comma ? "," : "");
  337: 	    else
  338: 		printf("%s CD-DA", comma ? "," : "");
  339: 	    comma = 1;
  340: 	}
  341: 	if (cdp->cap.read_dvdrom) {
  342: 	    printf("%s DVD-ROM", comma ? "," : ""); comma = 1;
  343: 	}
  344: 	if (cdp->cap.read_dvdr) {
  345: 	    printf("%s DVD-R", comma ? "," : ""); comma = 1;
  346: 	}
  347: 	if (cdp->cap.read_dvdram) {
  348: 	    printf("%s DVD-RAM", comma ? "," : ""); comma = 1;
  349: 	}
  350: 	if (cdp->cap.read_packet)
  351: 	    printf("%s packet", comma ? "," : "");
  352: 
  353: 	printf("\n");
  354: 	ata_prtdev(cdp->device, "Writes:");
  355: 	if (cdp->cap.write_cdr || cdp->cap.write_cdrw || 
  356: 	    cdp->cap.write_dvdr || cdp->cap.write_dvdram) {
  357: 	    comma = 0;
  358: 	    if (cdp->cap.write_cdr) {
  359: 		printf(" CD-R" ); comma = 1;
  360: 	    }
  361: 	    if (cdp->cap.write_cdrw) {
  362: 		printf("%s CD-RW", comma ? "," : ""); comma = 1;
  363: 	    }
  364: 	    if (cdp->cap.write_dvdr) {
  365: 		printf("%s DVD-R", comma ? "," : ""); comma = 1;
  366: 	    }
  367: 	    if (cdp->cap.write_dvdram) {
  368: 		printf("%s DVD-RAM", comma ? "," : ""); comma = 1; 
  369: 	    }
  370: 	    if (cdp->cap.test_write) {
  371: 		printf("%s test write", comma ? "," : ""); comma = 1;
  372: 	    }
  373: 	    if (cdp->cap.burnproof)
  374: 		printf("%s burnproof", comma ? "," : "");
  375: 	}
  376: 	printf("\n");
  377: 	if (cdp->cap.audio_play) {
  378: 	    ata_prtdev(cdp->device, "Audio: ");
  379: 	    if (cdp->cap.audio_play)
  380: 		printf("play");
  381: 	    if (cdp->cap.max_vol_levels)
  382: 		printf(", %d volume levels", cdp->cap.max_vol_levels);
  383: 	    printf("\n");
  384: 	}
  385: 	ata_prtdev(cdp->device, "Mechanism: ");
  386: 	switch (cdp->cap.mech) {
  387: 	case MST_MECH_CADDY:
  388: 	    mechanism = "caddy"; break;
  389: 	case MST_MECH_TRAY:
  390: 	    mechanism = "tray"; break;
  391: 	case MST_MECH_POPUP:
  392: 	    mechanism = "popup"; break;
  393: 	case MST_MECH_CHANGER:
  394: 	    mechanism = "changer"; break;
  395: 	case MST_MECH_CARTRIDGE:
  396: 	    mechanism = "cartridge"; break;
  397: 	default:
  398: 	    mechanism = 0; break;
  399: 	}
  400: 	if (mechanism)
  401: 	    printf("%s%s", cdp->cap.eject ? "ejectable " : "", mechanism);
  402: 	else if (cdp->cap.eject)
  403: 	    printf("ejectable");
  404: 
  405: 	if (cdp->cap.lock)
  406: 	    printf(cdp->cap.locked ? ", locked" : ", unlocked");
  407: 	if (cdp->cap.prevent)
  408: 	    printf(", lock protected");
  409: 	printf("\n");
  410: 
  411: 	if (cdp->cap.mech != MST_MECH_CHANGER) {
  412: 	    ata_prtdev(cdp->device, "Medium: ");
  413: 	    switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) {
  414: 	    case MST_CDROM:
  415: 		printf("CD-ROM "); break;
  416: 	    case MST_CDR:
  417: 		printf("CD-R "); break;
  418: 	    case MST_CDRW:
  419: 		printf("CD-RW "); break;
  420: 	    case MST_DOOR_OPEN:
  421: 		printf("door open"); break;
  422: 	    case MST_NO_DISC:
  423: 		printf("no/blank disc"); break;
  424: 	    case MST_FMT_ERROR:
  425: 		printf("medium format error"); break;
  426: 	    }
  427: 	    if ((cdp->cap.medium_type & MST_TYPE_MASK_HIGH)<MST_TYPE_MASK_HIGH){
  428: 		switch (cdp->cap.medium_type & MST_TYPE_MASK_LOW) {
  429: 		case MST_DATA_120:
  430: 		    printf("120mm data disc"); break;
  431: 		case MST_AUDIO_120:
  432: 		    printf("120mm audio disc"); break;
  433: 		case MST_COMB_120:
  434: 		    printf("120mm data/audio disc"); break;
  435: 		case MST_PHOTO_120:
  436: 		    printf("120mm photo disc"); break;
  437: 		case MST_DATA_80:
  438: 		    printf("80mm data disc"); break;
  439: 		case MST_AUDIO_80:
  440: 		    printf("80mm audio disc"); break;
  441: 		case MST_COMB_80:
  442: 		    printf("80mm data/audio disc"); break;
  443: 		case MST_PHOTO_80:
  444: 		    printf("80mm photo disc"); break;
  445: 		case MST_FMT_NONE:
  446: 		    switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) {
  447: 		    case MST_CDROM:
  448: 			printf("unknown"); break;
  449: 		    case MST_CDR:
  450: 		    case MST_CDRW:
  451: 			printf("blank"); break;
  452: 		    }
  453: 		    break;
  454: 		default:
  455: 		    printf("unknown (0x%x)", cdp->cap.medium_type); break;
  456: 		}
  457: 	    }
  458: 	    printf("\n");
  459: 	}
  460:     }
  461:     else {
  462: 	ata_prtdev(cdp->device, "%s ",
  463: 		   (cdp->cap.write_dvdr) ? "DVD-R" : 
  464: 		    (cdp->cap.write_dvdram) ? "DVD-RAM" : 
  465: 		     (cdp->cap.write_cdrw) ? "CD-RW" :
  466: 		      (cdp->cap.write_cdr) ? "CD-R" : 
  467: 		       (cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM");
  468: 
  469: 	if (cdp->changer_info)
  470: 	    printf("with %d CD changer ", cdp->changer_info->slots);
  471: 
  472: 	printf("<%.40s> at ata%d-%s %s\n", cdp->device->param->model,
  473: 	       device_get_unit(cdp->device->channel->dev),
  474: 	       (cdp->device->unit == ATA_MASTER) ? "master" : "slave",
  475: 	       ata_mode2str(cdp->device->mode) );
  476:     }
  477: }
  478: 
  479: static __inline void 
  480: lba2msf(u_int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
  481: {
  482:     lba += 150;
  483:     lba &= 0xffffff;
  484:     *m = lba / (60 * 75);
  485:     lba %= (60 * 75);
  486:     *s = lba / 75;
  487:     *f = lba % 75;
  488: }
  489: 
  490: static __inline u_int32_t 
  491: msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
  492: {
  493:     return (m * 60 + s) * 75 + f - 150;
  494: }
  495: 
  496: static int
  497: acdopen(dev_t dev, int flags, int fmt, struct thread *td)
  498: {
  499:     struct acd_softc *cdp = dev->si_drv1;
  500:     int timeout = 60;
  501:     
  502:     if (!cdp)
  503: 	return ENXIO;
  504: 
  505:     if (flags & FWRITE) {
  506: 	if (count_dev(dev) > 1)
  507: 	    return EBUSY;
  508:     }
  509: 
  510:     /* wait if drive is not finished loading the medium */
  511:     while (timeout--) {
  512: 	struct atapi_reqsense *sense = cdp->device->result;
  513: 
  514: 	if (!atapi_test_ready(cdp->device))
  515: 	    break;
  516: 	if (sense->sense_key == 2  && sense->asc == 4 && sense->ascq == 1)
  517: 	    tsleep(&timeout, 0, "acdld", hz / 2);
  518: 	else
  519: 	    break;
  520:     }
  521: 
  522:     if (count_dev(dev) == 1) {
  523: 	if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  524: 	    acd_select_slot(cdp);
  525: 	    tsleep(&cdp->changer_info, 0, "acdopn", 0);
  526: 	}
  527: 	acd_prevent_allow(cdp, 1);
  528: 	cdp->flags |= F_LOCKED;
  529: 	acd_read_toc(cdp);
  530:     }
  531:     return 0;
  532: }
  533: 
  534: static int 
  535: acdclose(dev_t dev, int flags, int fmt, struct thread *td)
  536: {
  537:     struct acd_softc *cdp = dev->si_drv1;
  538:     
  539:     if (!cdp)
  540: 	return ENXIO;
  541: 
  542:     if (count_dev(dev) == 1) {
  543: 	if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  544: 	    acd_select_slot(cdp);
  545: 	    tsleep(&cdp->changer_info, 0, "acdclo", 0);
  546: 	}
  547: 	acd_prevent_allow(cdp, 0);
  548: 	cdp->flags &= ~F_LOCKED;
  549:     }
  550:     return 0;
  551: }
  552: 
  553: static int 
  554: acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
  555: {
  556:     struct acd_softc *cdp = dev->si_drv1;
  557:     int error = 0;
  558: 
  559:     if (!cdp)
  560: 	return ENXIO;
  561: 
  562:     if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  563: 	acd_select_slot(cdp);
  564: 	tsleep(&cdp->changer_info, 0, "acdctl", 0);
  565:     }
  566:     if (cdp->device->flags & ATA_D_MEDIA_CHANGED)
  567: 	switch (cmd) {
  568: 	case CDIOCRESET:
  569: 	    atapi_test_ready(cdp->device);
  570: 	    break;
  571: 	   
  572: 	default:
  573: 	    acd_read_toc(cdp);
  574: 	    acd_prevent_allow(cdp, 1);
  575: 	    cdp->flags |= F_LOCKED;
  576: 	    break;
  577: 	}
  578:     switch (cmd) {
  579: 
  580:     case CDIOCRESUME:
  581: 	error = acd_pause_resume(cdp, 1);
  582: 	break;
  583: 
  584:     case CDIOCPAUSE:
  585: 	error = acd_pause_resume(cdp, 0);
  586: 	break;
  587: 
  588:     case CDIOCSTART:
  589: 	error = acd_start_stop(cdp, 1);
  590: 	break;
  591: 
  592:     case CDIOCSTOP:
  593: 	error = acd_start_stop(cdp, 0);
  594: 	break;
  595: 
  596:     case CDIOCALLOW:
  597: 	error = acd_prevent_allow(cdp, 0);
  598: 	cdp->flags &= ~F_LOCKED;
  599: 	break;
  600: 
  601:     case CDIOCPREVENT:
  602: 	error = acd_prevent_allow(cdp, 1);
  603: 	cdp->flags |= F_LOCKED;
  604: 	break;
  605: 
  606:     case CDIOCRESET:
  607: 	error = suser(td);	/* note: if no proc EPERM will be returned */
  608: 	if (error)
  609: 	    break;
  610: 	error = atapi_test_ready(cdp->device);
  611: 	break;
  612: 
  613:     case CDIOCEJECT:
  614: 	if (count_dev(dev) > 1) {
  615: 	    error = EBUSY;
  616: 	    break;
  617: 	}
  618: 	error = acd_eject(cdp, 0);
  619: 	break;
  620: 
  621:     case CDIOCCLOSE:
  622: 	if (count_dev(dev) > 1)
  623: 	    break;
  624: 	error = acd_eject(cdp, 1);
  625: 	break;
  626: 
  627:     case CDIOREADTOCHEADER:
  628: 	if (!cdp->toc.hdr.ending_track) {
  629: 	    error = EIO;
  630: 	    break;
  631: 	}
  632: 	bcopy(&cdp->toc.hdr, addr, sizeof(cdp->toc.hdr));
  633: 	break;
  634: 
  635:     case CDIOREADTOCENTRYS:
  636: 	{
  637: 	    struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr;
  638: 	    struct toc *toc = &cdp->toc;
  639: 	    int starting_track = te->starting_track;
  640: 	    int len;
  641: 
  642: 	    if (!toc->hdr.ending_track) {
  643: 		error = EIO;
  644: 		break;
  645: 	    }
  646: 
  647: 	    if (te->data_len < sizeof(toc->tab[0]) || 
  648: 		(te->data_len % sizeof(toc->tab[0])) != 0 || 
  649: 		(te->address_format != CD_MSF_FORMAT &&
  650: 		te->address_format != CD_LBA_FORMAT)) {
  651: 		error = EINVAL;
  652: 		break;
  653: 	    }
  654: 
  655: 	    if (!starting_track)
  656: 		starting_track = toc->hdr.starting_track;
  657: 	    else if (starting_track == 170) 
  658: 		starting_track = toc->hdr.ending_track + 1;
  659: 	    else if (starting_track < toc->hdr.starting_track ||
  660: 		     starting_track > toc->hdr.ending_track + 1) {
  661: 		error = EINVAL;
  662: 		break;
  663: 	    }
  664: 
  665: 	    len = ((toc->hdr.ending_track + 1 - starting_track) + 1) *
  666: 		  sizeof(toc->tab[0]);
  667: 	    if (te->data_len < len)
  668: 		len = te->data_len;
  669: 	    if (len > sizeof(toc->tab)) {
  670: 		error = EINVAL;
  671: 		break;
  672: 	    }
  673: 
  674: 	    if (te->address_format == CD_MSF_FORMAT) {
  675: 		struct cd_toc_entry *entry;
  676: 
  677: 		toc = malloc(sizeof(struct toc), M_ACD, M_WAITOK | M_ZERO);
  678: 		bcopy(&cdp->toc, toc, sizeof(struct toc));
  679: 		entry = toc->tab + (toc->hdr.ending_track + 1 -
  680: 			toc->hdr.starting_track) + 1;
  681: 		while (--entry >= toc->tab)
  682: 		    lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute,
  683: 			    &entry->addr.msf.second, &entry->addr.msf.frame);
  684: 	    }
  685: 	    error = copyout(toc->tab + starting_track - toc->hdr.starting_track,
  686: 			    te->data, len);
  687: 	    if (te->address_format == CD_MSF_FORMAT)
  688: 		free(toc, M_ACD);
  689: 	    break;
  690: 	}
  691:     case CDIOREADTOCENTRY:
  692: 	{
  693: 	    struct ioc_read_toc_single_entry *te =
  694: 		(struct ioc_read_toc_single_entry *)addr;
  695: 	    struct toc *toc = &cdp->toc;
  696: 	    u_char track = te->track;
  697: 
  698: 	    if (!toc->hdr.ending_track) {
  699: 		error = EIO;
  700: 		break;
  701: 	    }
  702: 
  703: 	    if (te->address_format != CD_MSF_FORMAT && 
  704: 		te->address_format != CD_LBA_FORMAT) {
  705: 		error = EINVAL;
  706: 		break;
  707: 	    }
  708: 
  709: 	    if (!track)
  710: 		track = toc->hdr.starting_track;
  711: 	    else if (track == 170)
  712: 		track = toc->hdr.ending_track + 1;
  713: 	    else if (track < toc->hdr.starting_track ||
  714: 		     track > toc->hdr.ending_track + 1) {
  715: 		error = EINVAL;
  716: 		break;
  717: 	    }
  718: 
  719: 	    if (te->address_format == CD_MSF_FORMAT) {
  720: 		struct cd_toc_entry *entry;
  721: 
  722: 		toc = malloc(sizeof(struct toc), M_ACD, M_WAITOK | M_ZERO);
  723: 		bcopy(&cdp->toc, toc, sizeof(struct toc));
  724: 
  725: 		entry = toc->tab + (track - toc->hdr.starting_track);
  726: 		lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute,
  727: 			&entry->addr.msf.second, &entry->addr.msf.frame);
  728: 	    }
  729: 	    bcopy(toc->tab + track - toc->hdr.starting_track,
  730: 		  &te->entry, sizeof(struct cd_toc_entry));
  731: 	    if (te->address_format == CD_MSF_FORMAT)
  732: 		free(toc, M_ACD);
  733: 	}
  734: 	break;
  735: 
  736:     case CDIOCREADSUBCHANNEL:
  737: 	{
  738: 	    struct ioc_read_subchannel *args =
  739: 		(struct ioc_read_subchannel *)addr;
  740: 	    u_int8_t format;
  741: 	    int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0,
  742: 			       sizeof(cdp->subchan)>>8, sizeof(cdp->subchan),
  743: 			       0, 0, 0, 0, 0, 0, 0 };
  744: 
  745: 	    if (args->data_len > sizeof(struct cd_sub_channel_info) ||
  746: 		args->data_len < sizeof(struct cd_sub_channel_header)) {
  747: 		error = EINVAL;
  748: 		break;
  749: 	    }
  750: 
  751: 	    format=args->data_format;
  752: 	    if ((format != CD_CURRENT_POSITION) &&
  753: 		(format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) {
  754: 		error = EINVAL;
  755: 		break;
  756: 	    }
  757: 
  758: 	    ccb[1] = args->address_format & CD_MSF_FORMAT;
  759: 
  760: 	    if ((error = atapi_queue_cmd(cdp->device,ccb,(caddr_t)&cdp->subchan,
  761: 					 sizeof(cdp->subchan), ATPR_F_READ, 10,
  762: 					 NULL, NULL)))
  763: 		break;
  764: 
  765: 	    if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) {
  766: 		if (cdp->subchan.header.audio_status == 0x11) {
  767: 		    error = EINVAL;
  768: 		    break;
  769: 		}
  770: 
  771: 		ccb[3] = format;
  772: 		if (format == CD_TRACK_INFO)
  773: 		    ccb[6] = args->track;
  774: 
  775: 		if ((error = atapi_queue_cmd(cdp->device, ccb,
  776: 					     (caddr_t)&cdp->subchan, 
  777: 					     sizeof(cdp->subchan), ATPR_F_READ,
  778: 					     10, NULL, NULL))) {
  779: 		    break;
  780: 		}
  781: 	    }
  782: 	    error = copyout(&cdp->subchan, args->data, args->data_len);
  783: 	    break;
  784: 	}
  785: 
  786:     case CDIOCPLAYMSF:
  787: 	{
  788: 	    struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
  789: 
  790: 	    error = 
  791: 		acd_play(cdp, 
  792: 			 msf2lba(args->start_m, args->start_s, args->start_f),
  793: 			 msf2lba(args->end_m, args->end_s, args->end_f));
  794: 	    break;
  795: 	}
  796: 
  797:     case CDIOCPLAYBLOCKS:
  798: 	{
  799: 	    struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
  800: 
  801: 	    error = acd_play(cdp, args->blk, args->blk + args->len);
  802: 	    break;
  803: 	}
  804: 
  805:     case CDIOCPLAYTRACKS:
  806: 	{
  807: 	    struct ioc_play_track *args = (struct ioc_play_track *)addr;
  808: 	    int t1, t2;
  809: 
  810: 	    if (!cdp->toc.hdr.ending_track) {
  811: 		error = EIO;
  812: 		break;
  813: 	    }
  814: 	    if (args->end_track < cdp->toc.hdr.ending_track + 1)
  815: 		++args->end_track;
  816: 	    if (args->end_track > cdp->toc.hdr.ending_track + 1)
  817: 		args->end_track = cdp->toc.hdr.ending_track + 1;
  818: 	    t1 = args->start_track - cdp->toc.hdr.starting_track;
  819: 	    t2 = args->end_track - cdp->toc.hdr.starting_track;
  820: 	    if (t1 < 0 || t2 < 0 ||
  821: 		t1 > (cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track)) {
  822: 		error = EINVAL;
  823: 		break;
  824: 	    }
  825: 	    error = acd_play(cdp, ntohl(cdp->toc.tab[t1].addr.lba),
  826: 			     ntohl(cdp->toc.tab[t2].addr.lba));
  827: 	    break;
  828: 	}
  829: 
  830:     case CDIOCREADAUDIO:
  831: 	{
  832: 	    struct ioc_read_audio *args = (struct ioc_read_audio *)addr;
  833: 	    int32_t lba;
  834: 	    caddr_t buffer, ubuf = args->buffer;
  835: 	    int8_t ccb[16];
  836: 	    int frames;
  837: 
  838: 	    if (!cdp->toc.hdr.ending_track) {
  839: 		error = EIO;
  840: 		break;
  841: 	    }
  842: 		
  843: 	    if ((frames = args->nframes) < 0) {
  844: 		error = EINVAL;
  845: 		break;
  846: 	    }
  847: 
  848: 	    if (args->address_format == CD_LBA_FORMAT)
  849: 		lba = args->address.lba;
  850: 	    else if (args->address_format == CD_MSF_FORMAT)
  851: 		lba = msf2lba(args->address.msf.minute,
  852: 			     args->address.msf.second,
  853: 			     args->address.msf.frame);
  854: 	    else {
  855: 		error = EINVAL;
  856: 		break;
  857: 	    }
  858: 
  859: #ifndef CD_BUFFER_BLOCKS
  860: #define CD_BUFFER_BLOCKS 13
  861: #endif
  862: 	    if (!(buffer = malloc(CD_BUFFER_BLOCKS * 2352, M_ACD, M_WAITOK))){
  863: 		error = ENOMEM;
  864: 		break;
  865: 	    }
  866: 	    bzero(ccb, sizeof(ccb));
  867: 	    while (frames > 0) {
  868: 		int8_t blocks;
  869: 		int size;
  870: 
  871: 		blocks = (frames>CD_BUFFER_BLOCKS) ? CD_BUFFER_BLOCKS : frames;
  872: 		size = blocks * 2352;
  873: 
  874: 		ccb[0] = ATAPI_READ_CD;
  875: 		ccb[1] = 4;
  876: 		ccb[2] = lba>>24;
  877: 		ccb[3] = lba>>16;
  878: 		ccb[4] = lba>>8;
  879: 		ccb[5] = lba;
  880: 		ccb[8] = blocks;
  881: 		ccb[9] = 0xf0;
  882: 		if ((error = atapi_queue_cmd(cdp->device, ccb, buffer, size, 
  883: 					     ATPR_F_READ, 30, NULL,NULL)))
  884: 		    break;
  885: 
  886: 		if ((error = copyout(buffer, ubuf, size)))
  887: 		    break;
  888: 		    
  889: 		ubuf += size;
  890: 		frames -= blocks;
  891: 		lba += blocks;
  892: 	    }
  893: 	    free(buffer, M_ACD);
  894: 	    if (args->address_format == CD_LBA_FORMAT)
  895: 		args->address.lba = lba;
  896: 	    else if (args->address_format == CD_MSF_FORMAT)
  897: 		lba2msf(lba, &args->address.msf.minute,
  898: 			     &args->address.msf.second,
  899: 			     &args->address.msf.frame);
  900: 	    break;
  901: 	}
  902: 
  903:     case CDIOCGETVOL:
  904: 	{
  905: 	    struct ioc_vol *arg = (struct ioc_vol *)addr;
  906: 
  907: 	    if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
  908: 					(caddr_t)&cdp->au, sizeof(cdp->au))))
  909: 		break;
  910: 
  911: 	    if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
  912: 		error = EIO;
  913: 		break;
  914: 	    }
  915: 	    arg->vol[0] = cdp->au.port[0].volume;
  916: 	    arg->vol[1] = cdp->au.port[1].volume;
  917: 	    arg->vol[2] = cdp->au.port[2].volume;
  918: 	    arg->vol[3] = cdp->au.port[3].volume;
  919: 	    break;
  920: 	}
  921: 
  922:     case CDIOCSETVOL:
  923: 	{
  924: 	    struct ioc_vol *arg = (struct ioc_vol *)addr;
  925: 
  926: 	    if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
  927: 					(caddr_t)&cdp->au, sizeof(cdp->au))))
  928: 		break;
  929: 	    if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
  930: 		error = EIO;
  931: 		break;
  932: 	    }
  933: 	    if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE_MASK,
  934: 					(caddr_t)&cdp->aumask,
  935: 					sizeof(cdp->aumask))))
  936: 		break;
  937: 	    cdp->au.data_length = 0;
  938: 	    cdp->au.port[0].channels = CHANNEL_0;
  939: 	    cdp->au.port[1].channels = CHANNEL_1;
  940: 	    cdp->au.port[0].volume = arg->vol[0] & cdp->aumask.port[0].volume;
  941: 	    cdp->au.port[1].volume = arg->vol[1] & cdp->aumask.port[1].volume;
  942: 	    cdp->au.port[2].volume = arg->vol[2] & cdp->aumask.port[2].volume;
  943: 	    cdp->au.port[3].volume = arg->vol[3] & cdp->aumask.port[3].volume;
  944: 	    error =  acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
  945: 	    break;
  946: 	}
  947:     case CDIOCSETPATCH:
  948: 	{
  949: 	    struct ioc_patch *arg = (struct ioc_patch *)addr;
  950: 
  951: 	    error = acd_setchan(cdp, arg->patch[0], arg->patch[1],
  952: 				arg->patch[2], arg->patch[3]);
  953: 	    break;
  954: 	}
  955: 
  956:     case CDIOCSETMONO:
  957: 	error = acd_setchan(cdp, CHANNEL_0|CHANNEL_1, CHANNEL_0|CHANNEL_1, 0,0);
  958: 	break;
  959: 
  960:     case CDIOCSETSTEREO:
  961: 	error = acd_setchan(cdp, CHANNEL_0, CHANNEL_1, 0, 0);
  962: 	break;
  963: 
  964:     case CDIOCSETMUTE:
  965: 	error = acd_setchan(cdp, 0, 0, 0, 0);
  966: 	break;
  967: 
  968:     case CDIOCSETLEFT:
  969: 	error = acd_setchan(cdp, CHANNEL_0, CHANNEL_0, 0, 0);
  970: 	break;
  971: 
  972:     case CDIOCSETRIGHT:
  973: 	error = acd_setchan(cdp, CHANNEL_1, CHANNEL_1, 0, 0);
  974: 	break;
  975: 
  976:     case CDRIOCBLANK:
  977: 	error = acd_blank(cdp, (*(int *)addr));
  978: 	break;
  979: 
  980:     case CDRIOCNEXTWRITEABLEADDR:
  981: 	{
  982: 	    struct acd_track_info track_info;
  983: 
  984: 	    if ((error = acd_read_track_info(cdp, 0xff, &track_info)))
  985: 		break;
  986: 
  987: 	    if (!track_info.nwa_valid) {
  988: 		error = EINVAL;
  989: 		break;
  990: 	    }
  991: 	    *(int*)addr = track_info.next_writeable_addr;
  992: 	}
  993: 	break;
  994:  
  995:     case CDRIOCINITWRITER:
  996: 	error = acd_init_writer(cdp, (*(int *)addr));
  997: 	break;
  998: 
  999:     case CDRIOCINITTRACK:
 1000: 	error = acd_init_track(cdp, (struct cdr_track *)addr);
 1001: 	break;
 1002: 
 1003:     case CDRIOCFLUSH:
 1004: 	error = acd_flush(cdp);
 1005: 	break;
 1006: 
 1007:     case CDRIOCFIXATE:
 1008: 	error = acd_fixate(cdp, (*(int *)addr));
 1009: 	break;
 1010: 
 1011:     case CDRIOCREADSPEED:
 1012: 	{
 1013: 	    int speed = *(int *)addr;
 1014: 
 1015: 	    /* Preserve old behavior: units in multiples of CDROM speed */
 1016: 	    if (speed < 177)
 1017: 		speed *= 177;
 1018: 	    error = acd_set_speed(cdp, speed, CDR_MAX_SPEED);
 1019: 	}
 1020: 	break;
 1021: 
 1022:     case CDRIOCWRITESPEED:
 1023:     	{
 1024: 	    int speed = *(int *)addr;
 1025: 
 1026: 	    if (speed < 177)
 1027: 		speed *= 177;
 1028: 	    error = acd_set_speed(cdp, CDR_MAX_SPEED, speed);
 1029: 	}
 1030: 	break;
 1031: 
 1032:     case CDRIOCGETBLOCKSIZE:
 1033: 	*(int *)addr = cdp->block_size;
 1034: 	break;
 1035: 
 1036:     case CDRIOCSETBLOCKSIZE:
 1037: 	cdp->block_size = *(int *)addr;
 1038: 	acd_set_ioparm(cdp);
 1039: 	break;
 1040: 
 1041:     case CDRIOCGETPROGRESS:
 1042: 	error = acd_get_progress(cdp, (int *)addr);
 1043: 	break;
 1044: 
 1045:     case CDRIOCSENDCUE:
 1046: 	error = acd_send_cue(cdp, (struct cdr_cuesheet *)addr);
 1047: 	break;
 1048: 
 1049:     case DVDIOCREPORTKEY:
 1050: 	if (!cdp->cap.read_dvdrom)
 1051: 	    error = EINVAL;
 1052: 	else
 1053: 	    error = acd_report_key(cdp, (struct dvd_authinfo *)addr);
 1054: 	break;
 1055: 
 1056:     case DVDIOCSENDKEY:
 1057: 	if (!cdp->cap.read_dvdrom)
 1058: 	    error = EINVAL;
 1059: 	else
 1060: 	    error = acd_send_key(cdp, (struct dvd_authinfo *)addr);
 1061: 	break;
 1062: 
 1063:     case DVDIOCREADSTRUCTURE:
 1064: 	if (!cdp->cap.read_dvdrom)
 1065: 	    error = EINVAL;
 1066: 	else
 1067: 	    error = acd_read_structure(cdp, (struct dvd_struct *)addr);
 1068: 	break;
 1069: 
 1070:     case DIOCGDINFO:
 1071: 	*(struct disklabel *)addr = cdp->disklabel;
 1072: 	break;
 1073: 
 1074:     case DIOCWDINFO:
 1075:     case DIOCSDINFO:
 1076: 	if ((flags & FWRITE) == 0)
 1077: 	    error = EBADF;
 1078: 	else
 1079: 	    error = setdisklabel(&cdp->disklabel, (struct disklabel *)addr, 0);
 1080: 	break;
 1081: 
 1082:     case DIOCWLABEL:
 1083: 	error = EBADF;
 1084: 	break;
 1085: 
 1086:     case DIOCGPART:
 1087: 	((struct partinfo *)addr)->disklab = &cdp->disklabel;
 1088: 	((struct partinfo *)addr)->part = &cdp->disklabel.d_partitions[0];
 1089: 	break;
 1090: 
 1091:     default:
 1092: 	error = ENOTTY;
 1093:     }
 1094:     return error;
 1095: }
 1096: 
 1097: static void 
 1098: acdstrategy(struct buf *bp)
 1099: {
 1100:     struct acd_softc *cdp = bp->b_dev->si_drv1;
 1101:     int s;
 1102: 
 1103:     if (cdp->device->flags & ATA_D_DETACHING) {
 1104: 	bp->b_flags |= B_ERROR;
 1105: 	bp->b_error = ENXIO;
 1106: 	biodone(bp);
 1107: 	return;
 1108:     }
 1109: 
 1110:     /* if it's a null transfer, return immediatly. */
 1111:     if (bp->b_bcount == 0) {
 1112: 	bp->b_resid = 0;
 1113: 	biodone(bp);
 1114: 	return;
 1115:     }
 1116:     
 1117:     bp->b_pblkno = bp->b_blkno;
 1118:     bp->b_resid = bp->b_bcount;
 1119: 
 1120:     s = splbio();
 1121:     bufqdisksort(&cdp->queue, bp);
 1122:     splx(s);
 1123:     ata_start(cdp->device->channel);
 1124: }
 1125: 
 1126: void 
 1127: acd_start(struct ata_device *atadev)
 1128: {
 1129:     struct acd_softc *cdp = atadev->driver;
 1130:     struct buf *bp = bufq_first(&cdp->queue);
 1131:     u_int32_t lba, lastlba, count;
 1132:     int8_t ccb[16];
 1133:     int track, blocksize;
 1134: 
 1135:     if (cdp->changer_info) {
 1136: 	int i;
 1137: 
 1138: 	cdp = cdp->driver[cdp->changer_info->current_slot];
 1139: 	bp = bufq_first(&cdp->queue);
 1140: 
 1141: 	/* check for work pending on any other slot */
 1142: 	for (i = 0; i < cdp->changer_info->slots; i++) {
 1143: 	    if (i == cdp->changer_info->current_slot)
 1144: 		continue;
 1145: 	    if (bufq_first(&(cdp->driver[i]->queue))) {
 1146: 		if (!bp || time_second > (cdp->timestamp + 10)) {
 1147: 		    acd_select_slot(cdp->driver[i]);
 1148: 		    return;
 1149: 		}
 1150: 	    }
 1151: 	}
 1152:     }
 1153:     if (!bp)
 1154: 	return;
 1155:     bufq_remove(&cdp->queue, bp);
 1156: 
 1157:     /* reject all queued entries if media changed */
 1158:     if (cdp->device->flags & ATA_D_MEDIA_CHANGED) {
 1159: 	bp->b_flags |= B_ERROR;
 1160: 	bp->b_error = EIO;
 1161: 	biodone(bp);
 1162: 	return;
 1163:     }
 1164: 
 1165:     bzero(ccb, sizeof(ccb));
 1166: 
 1167:     track = (bp->b_dev->si_udev & 0x00ff0000) >> 16;
 1168: 
 1169:     if (track) {
 1170: 	blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
 1171: 	lastlba = ntohl(cdp->toc.tab[track].addr.lba);
 1172: 	if (bp->b_flags & B_PHYS)
 1173: 	    lba = bp->b_offset / blocksize;
 1174: 	else
 1175: 	    lba = bp->b_blkno / (blocksize / DEV_BSIZE);
 1176: 	lba += ntohl(cdp->toc.tab[track - 1].addr.lba);
 1177:     }
 1178:     else {
 1179: 	blocksize = cdp->block_size;
 1180: 	lastlba = cdp->disk_size;
 1181: 	if (bp->b_flags & B_PHYS)
 1182: 	    lba = bp->b_offset / blocksize;
 1183: 	else
 1184: 	    lba = bp->b_blkno / (blocksize / DEV_BSIZE);
 1185:     }
 1186: 
 1187:     if (bp->b_bcount % blocksize != 0) {
 1188: 	bp->b_flags |= B_ERROR;
 1189: 	bp->b_error = EINVAL;
 1190: 	biodone(bp);
 1191: 	return;
 1192:     }
 1193:     count = bp->b_bcount / blocksize;
 1194: 
 1195:     if (bp->b_flags & B_READ) {
 1196: 	/* if transfer goes beyond range adjust it to be within limits */
 1197: 	if (lba + count > lastlba) {
 1198: 	    /* if we are entirely beyond EOM return EOF */
 1199: 	    if (lastlba <= lba) {
 1200: 		bp->b_resid = bp->b_bcount;
 1201: 		biodone(bp);
 1202: 		return;
 1203: 	    }
 1204: 	    count = lastlba - lba;
 1205: 	}
 1206: 	switch (blocksize) {
 1207: 	case 2048:
 1208: 	    ccb[0] = ATAPI_READ_BIG;
 1209: 	    break;
 1210: 
 1211: 	case 2352: 
 1212: 	    ccb[0] = ATAPI_READ_CD;
 1213: 	    ccb[9] = 0xf8;
 1214: 	    break;
 1215: 
 1216: 	default:
 1217: 	    ccb[0] = ATAPI_READ_CD;
 1218: 	    ccb[9] = 0x10;
 1219: 	}
 1220:     }
 1221:     else 
 1222: 	ccb[0] = ATAPI_WRITE_BIG;
 1223:     
 1224:     ccb[1] = 0;
 1225:     ccb[2] = lba>>24;
 1226:     ccb[3] = lba>>16;
 1227:     ccb[4] = lba>>8;
 1228:     ccb[5] = lba;
 1229:     ccb[6] = count>>16;
 1230:     ccb[7] = count>>8;
 1231:     ccb[8] = count;
 1232: 
 1233:     devstat_start_transaction(cdp->stats);
 1234:     bp->b_caller1 = cdp;
 1235:     atapi_queue_cmd(cdp->device, ccb, bp->b_data, count * blocksize,
 1236: 		    bp->b_flags & B_READ ? ATPR_F_READ : 0, 
 1237: 		    (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30, acd_done, bp);
 1238: }
 1239: 
 1240: static int 
 1241: acd_done(struct atapi_request *request)
 1242: {
 1243:     struct buf *bp = request->driver;
 1244:     struct acd_softc *cdp = bp->b_caller1;
 1245:     
 1246:     if (request->error) {
 1247: 	bp->b_error = request->error;
 1248: 	bp->b_flags |= B_ERROR;
 1249:     }	
 1250:     else
 1251: 	bp->b_resid = bp->b_bcount - request->donecount;
 1252:     devstat_end_transaction_buf(cdp->stats, bp);
 1253:     biodone(bp);
 1254:     return 0;
 1255: }
 1256: 
 1257: static void 
 1258: acd_read_toc(struct acd_softc *cdp)
 1259: {
 1260:     struct acd_devlist *entry;
 1261:     int track, ntracks, len;
 1262:     u_int32_t sizes[2];
 1263:     int8_t ccb[16];
 1264: 
 1265:     bzero(&cdp->toc, sizeof(cdp->toc));
 1266:     bzero(ccb, sizeof(ccb));
 1267: 
 1268:     if (atapi_test_ready(cdp->device) != 0)
 1269: 	return;
 1270: 
 1271:     cdp->device->flags &= ~ATA_D_MEDIA_CHANGED;
 1272: 
 1273:     len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry);
 1274:     ccb[0] = ATAPI_READ_TOC;
 1275:     ccb[7] = len>>8;
 1276:     ccb[8] = len;
 1277:     if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
 1278: 			ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
 1279: 	bzero(&cdp->toc, sizeof(cdp->toc));
 1280: 	return;
 1281:     }
 1282:     ntracks = cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1;
 1283:     if (ntracks <= 0 || ntracks > MAXTRK) {
 1284: 	bzero(&cdp->toc, sizeof(cdp->toc));
 1285: 	return;
 1286:     }
 1287: 
 1288:     len = sizeof(struct ioc_toc_header)+(ntracks+1)*sizeof(struct cd_toc_entry);
 1289:     bzero(ccb, sizeof(ccb));
 1290:     ccb[0] = ATAPI_READ_TOC;
 1291:     ccb[7] = len>>8;
 1292:     ccb[8] = len;
 1293:     if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
 1294: 			ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
 1295: 	bzero(&cdp->toc, sizeof(cdp->toc));
 1296: 	return;
 1297:     }
 1298:     cdp->toc.hdr.len = ntohs(cdp->toc.hdr.len);
 1299: 
 1300:     cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352;
 1301:     acd_set_ioparm(cdp);
 1302:     bzero(ccb, sizeof(ccb));
 1303:     ccb[0] = ATAPI_READ_CAPACITY;
 1304:     if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)sizes, sizeof(sizes),
 1305: 			ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
 1306: 	bzero(&cdp->toc, sizeof(cdp->toc));
 1307: 	return;
 1308:     }
 1309:     cdp->disk_size = ntohl(sizes[0]) + 1;
 1310: 
 1311:     bzero(&cdp->disklabel, sizeof(struct disklabel));
 1312:     strncpy(cdp->disklabel.d_typename, "	       ", 
 1313: 	    sizeof(cdp->disklabel.d_typename));
 1314:     strncpy(cdp->disklabel.d_typename, cdp->device->name, 
 1315: 	    min(strlen(cdp->device->name),sizeof(cdp->disklabel.d_typename)-1));
 1316:     strncpy(cdp->disklabel.d_packname, "unknown	       ", 
 1317: 	    sizeof(cdp->disklabel.d_packname));
 1318:     cdp->disklabel.d_secsize = cdp->block_size;
 1319:     cdp->disklabel.d_nsectors = 100;
 1320:     cdp->disklabel.d_ntracks = 1;
 1321:     cdp->disklabel.d_ncylinders = (cdp->disk_size / 100) + 1;
 1322:     cdp->disklabel.d_secpercyl = 100;
 1323:     cdp->disklabel.d_secperunit = cdp->disk_size;
 1324:     cdp->disklabel.d_rpm = 300;
 1325:     cdp->disklabel.d_interleave = 1;
 1326:     cdp->disklabel.d_flags = D_REMOVABLE;
 1327:     cdp->disklabel.d_npartitions = 1;
 1328:     cdp->disklabel.d_partitions[0].p_offset = 0;
 1329:     cdp->disklabel.d_partitions[0].p_size = cdp->disk_size;
 1330:     cdp->disklabel.d_partitions[0].p_fstype = FS_BSDFFS;
 1331:     cdp->disklabel.d_magic = DISKMAGIC;
 1332:     cdp->disklabel.d_magic2 = DISKMAGIC;
 1333:     cdp->disklabel.d_checksum = dkcksum(&cdp->disklabel);
 1334: 
 1335:     while ((entry = TAILQ_FIRST(&cdp->dev_list))) {
 1336: 	destroy_dev(entry->dev);
 1337: 	TAILQ_REMOVE(&cdp->dev_list, entry, chain);
 1338: 	free(entry, M_ACD);
 1339:     }
 1340:     for (track = 1; track <= ntracks; track ++) {
 1341: 	char name[16];
 1342: 
 1343: 	sprintf(name, "acd%dt%d", cdp->lun, track);
 1344: 	entry = malloc(sizeof(struct acd_devlist), M_ACD, M_WAITOK | M_ZERO);
 1345: 	entry->dev = make_dev(&acd_cdevsw, (cdp->lun << 3) | (track << 16),
 1346: 			      0, 0, 0644, name, NULL);
 1347: 	entry->dev->si_drv1 = cdp->dev->si_drv1;
 1348: 	TAILQ_INSERT_TAIL(&cdp->dev_list, entry, chain);
 1349:     }
 1350: 
 1351: #ifdef ACD_DEBUG
 1352:     if (cdp->disk_size && cdp->toc.hdr.ending_track) {
 1353: 	ata_prtdev(cdp->device, "(%d sectors (%d bytes)), %d tracks ", 
 1354: 		   cdp->disk_size, cdp->block_size,
 1355: 		   cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1);
 1356: 	if (cdp->toc.tab[0].control & 4)
 1357: 	    printf("%dMB\n", cdp->disk_size / 512);
 1358: 	else
 1359: 	    printf("%d:%d audio\n",
 1360: 		   cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60);
 1361:     }
 1362: #endif
 1363: }
 1364: 
 1365: static int
 1366: acd_play(struct acd_softc *cdp, int start, int end)
 1367: {
 1368:     int8_t ccb[16];
 1369: 
 1370:     bzero(ccb, sizeof(ccb));
 1371:     ccb[0] = ATAPI_PLAY_MSF;
 1372:     lba2msf(start, &ccb[3], &ccb[4], &ccb[5]);
 1373:     lba2msf(end, &ccb[6], &ccb[7], &ccb[8]);
 1374:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
 1375: }
 1376: 
 1377: static int 
 1378: acd_setchan(struct acd_softc *cdp,
 1379: 	    u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)
 1380: {
 1381:     int error;
 1382: 
 1383:     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE, (caddr_t)&cdp->au, 
 1384: 				sizeof(cdp->au))))
 1385: 	return error;
 1386:     if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE)
 1387: 	return EIO;
 1388:     cdp->au.data_length = 0;
 1389:     cdp->au.port[0].channels = c0;
 1390:     cdp->au.port[1].channels = c1;
 1391:     cdp->au.port[2].channels = c2;
 1392:     cdp->au.port[3].channels = c3;
 1393:     return acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
 1394: }
 1395: 
 1396: static int 
 1397: acd_select_done1(struct atapi_request *request)
 1398: {
 1399:     struct acd_softc *cdp = request->driver;
 1400: 
 1401:     cdp->changer_info->current_slot = cdp->slot;
 1402:     cdp->driver[cdp->changer_info->current_slot]->timestamp = time_second;
 1403:     wakeup(&cdp->changer_info);
 1404:     return 0;
 1405: }
 1406: 
 1407: static int 
 1408: acd_select_done(struct atapi_request *request)
 1409: {
 1410:     struct acd_softc *cdp = request->driver;
 1411:     int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 3, 0, 0, 0, 
 1412: 		       cdp->slot, 0, 0, 0, 0, 0, 0, 0 };
 1413: 
 1414:     /* load the wanted slot */
 1415:     atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, 
 1416: 		    acd_select_done1, cdp);
 1417:     return 0;
 1418: }
 1419: 
 1420: static void 
 1421: acd_select_slot(struct acd_softc *cdp)
 1422: {
 1423:     int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 2, 0, 0, 0, 
 1424: 		       cdp->changer_info->current_slot, 0, 0, 0, 0, 0, 0, 0 };
 1425: 
 1426:     /* unload the current media from player */
 1427:     atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, 
 1428: 		    acd_select_done, cdp);
 1429: }
 1430: 
 1431: static int
 1432: acd_init_writer(struct acd_softc *cdp, int test_write)
 1433: {
 1434:     int8_t ccb[16];
 1435: 
 1436:     bzero(ccb, sizeof(ccb));
 1437:     ccb[0] = ATAPI_REZERO;
 1438:     atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL);
 1439:     ccb[0] = ATAPI_SEND_OPC_INFO;
 1440:     ccb[1] = 0x01;
 1441:     atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL);
 1442:     return 0;
 1443: }
 1444: 
 1445: static int
 1446: acd_fixate(struct acd_softc *cdp, int multisession)
 1447: {
 1448:     int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0x01, 0x02, 0, 0, 0, 0, 0, 
 1449: 		       0, 0, 0, 0, 0, 0, 0, 0 };
 1450:     int timeout = 5*60*2;
 1451:     int error;
 1452:     struct write_param param;
 1453: 
 1454:     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1455: 				(caddr_t)&param, sizeof(param))))
 1456: 	return error;
 1457: 
 1458:     param.data_length = 0;
 1459:     if (multisession)
 1460: 	param.session_type = CDR_SESS_MULTI;
 1461:     else
 1462: 	param.session_type = CDR_SESS_NONE;
 1463: 
 1464:     if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
 1465: 	return error;
 1466:   
 1467:     error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 1468:     if (error)
 1469: 	return error;
 1470: 
 1471:     /* some drives just return ready, wait for the expected fixate time */
 1472:     if ((error = atapi_test_ready(cdp->device)) != EBUSY) {
 1473: 	timeout = timeout / (cdp->cap.cur_write_speed / 177);
 1474: 	tsleep(&error, 0, "acdfix", timeout * hz / 2);
 1475: 	return atapi_test_ready(cdp->device);
 1476:     }
 1477: 
 1478:     while (timeout-- > 0) {
 1479: 	if ((error = atapi_test_ready(cdp->device)) != EBUSY)
 1480: 	    return error;
 1481: 	tsleep(&error, 0, "acdcld", hz/2);
 1482:     }
 1483:     return EIO;
 1484: }
 1485: 
 1486: static int
 1487: acd_init_track(struct acd_softc *cdp, struct cdr_track *track)
 1488: {
 1489:     struct write_param param;
 1490:     int error;
 1491: 
 1492:     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1493: 				(caddr_t)&param, sizeof(param))))
 1494: 	return error;
 1495: 
 1496:     param.data_length = 0;
 1497:     param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE;
 1498:     param.page_length = 0x32;
 1499:     param.test_write = track->test_write ? 1 : 0;
 1500:     param.write_type = CDR_WTYPE_TRACK;
 1501:     param.session_type = CDR_SESS_NONE;
 1502:     param.fp = 0;
 1503:     param.packet_size = 0;
 1504: 
 1505:     if (cdp->cap.burnproof) 
 1506: 	param.burnproof = 1;
 1507: 
 1508:     switch (track->datablock_type) {
 1509: 
 1510:     case CDR_DB_RAW:
 1511: 	if (track->preemp)
 1512: 	    param.track_mode = CDR_TMODE_AUDIO_PREEMP;
 1513: 	else
 1514: 	    param.track_mode = CDR_TMODE_AUDIO;
 1515: 	cdp->block_size = 2352;
 1516: 	param.datablock_type = CDR_DB_RAW;
 1517: 	param.session_format = CDR_SESS_CDROM;
 1518: 	break;
 1519: 
 1520:     case CDR_DB_ROM_MODE1:
 1521: 	cdp->block_size = 2048;
 1522: 	param.track_mode = CDR_TMODE_DATA;
 1523: 	param.datablock_type = CDR_DB_ROM_MODE1;
 1524: 	param.session_format = CDR_SESS_CDROM;
 1525: 	break;
 1526: 
 1527:     case CDR_DB_ROM_MODE2:
 1528: 	cdp->block_size = 2336;
 1529: 	param.track_mode = CDR_TMODE_DATA;
 1530: 	param.datablock_type = CDR_DB_ROM_MODE2;
 1531: 	param.session_format = CDR_SESS_CDROM;
 1532: 	break;
 1533: 
 1534:     case CDR_DB_XA_MODE1:
 1535: 	cdp->block_size = 2048;
 1536: 	param.track_mode = CDR_TMODE_DATA;
 1537: 	param.datablock_type = CDR_DB_XA_MODE1;
 1538: 	param.session_format = CDR_SESS_CDROM_XA;
 1539: 	break;
 1540: 
 1541:     case CDR_DB_XA_MODE2_F1:
 1542: 	cdp->block_size = 2056;
 1543: 	param.track_mode = CDR_TMODE_DATA;
 1544: 	param.datablock_type = CDR_DB_XA_MODE2_F1;
 1545: 	param.session_format = CDR_SESS_CDROM_XA;
 1546: 	break;
 1547: 
 1548:     case CDR_DB_XA_MODE2_F2:
 1549: 	cdp->block_size = 2324;
 1550: 	param.track_mode = CDR_TMODE_DATA;
 1551: 	param.datablock_type = CDR_DB_XA_MODE2_F2;
 1552: 	param.session_format = CDR_SESS_CDROM_XA;
 1553: 	break;
 1554: 
 1555:     case CDR_DB_XA_MODE2_MIX:
 1556: 	cdp->block_size = 2332;
 1557: 	param.track_mode = CDR_TMODE_DATA;
 1558: 	param.datablock_type = CDR_DB_XA_MODE2_MIX;
 1559: 	param.session_format = CDR_SESS_CDROM_XA;
 1560: 	break;
 1561:     }
 1562:     acd_set_ioparm(cdp);
 1563:     return acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10);
 1564: }
 1565: 
 1566: static int
 1567: acd_flush(struct acd_softc *cdp)
 1568: {
 1569:     int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0,
 1570: 		       0, 0, 0, 0, 0, 0, 0, 0 };
 1571: 
 1572:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60,
 1573: 			   NULL, NULL);
 1574: }
 1575: 
 1576: static int
 1577: acd_read_track_info(struct acd_softc *cdp,
 1578: 		    int32_t lba, struct acd_track_info *info)
 1579: {
 1580:     int8_t ccb[16] = { ATAPI_READ_TRACK_INFO, 1,
 1581: 		     lba>>24, lba>>16, lba>>8, lba,
 1582: 		     0,
 1583: 		     sizeof(*info)>>8, sizeof(*info),
 1584: 		     0, 0, 0, 0, 0, 0, 0 };
 1585:     int error;
 1586: 
 1587:     if ((error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)info, sizeof(*info),
 1588: 				 ATPR_F_READ, 30, NULL, NULL)))
 1589: 	return error;
 1590:     info->track_start_addr = ntohl(info->track_start_addr);
 1591:     info->next_writeable_addr = ntohl(info->next_writeable_addr);
 1592:     info->free_blocks = ntohl(info->free_blocks);
 1593:     info->fixed_packet_size = ntohl(info->fixed_packet_size);
 1594:     info->track_length = ntohl(info->track_length);
 1595:     return 0;
 1596: }
 1597: 
 1598: static int
 1599: acd_get_progress(struct acd_softc *cdp, int *finished)
 1600: {
 1601:     int8_t ccb[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0,  
 1602: 		       0, 0, 0, 0, 0, 0, 0, 0 };
 1603:     struct atapi_reqsense *sense = cdp->device->result;
 1604:     char tmp[8];
 1605: 
 1606:     if (atapi_test_ready(cdp->device) != EBUSY) {
 1607: 	if (atapi_queue_cmd(cdp->device, ccb, tmp, sizeof(tmp),
 1608: 			    ATPR_F_READ, 30, NULL, NULL) != EBUSY) {
 1609: 	    *finished = 100;
 1610: 	    return 0;
 1611: 	}
 1612:     }
 1613:     if (sense->sksv)
 1614: 	*finished = 
 1615: 	    ((sense->sk_specific2 | (sense->sk_specific1 << 8)) * 100) / 65535;
 1616:     else
 1617: 	*finished = 0;
 1618:     return 0;
 1619: }
 1620: 
 1621: static int
 1622: acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet)
 1623: {
 1624:     struct write_param param;
 1625:     int8_t ccb[16] = { ATAPI_SEND_CUE_SHEET, 0, 0, 0, 0, 0, 
 1626: 		       cuesheet->len>>16, cuesheet->len>>8, cuesheet->len,
 1627: 		       0, 0, 0, 0, 0, 0, 0 };
 1628:     int8_t *buffer;
 1629:     int32_t error;
 1630: #ifdef ACD_DEBUG
 1631:     int i;
 1632: #endif
 1633: 
 1634:     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1635: 				(caddr_t)&param, sizeof(param))))
 1636: 	return error;
 1637:     param.data_length = 0;
 1638:     param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE;
 1639:     param.page_length = 0x32;
 1640:     param.test_write = cuesheet->test_write ? 1 : 0;
 1641:     param.write_type = CDR_WTYPE_SESSION;
 1642:     param.session_type = cuesheet->session_type;
 1643:     param.fp = 0;
 1644:     param.packet_size = 0;
 1645:     param.track_mode = CDR_TMODE_AUDIO;
 1646:     param.datablock_type = CDR_DB_RAW;
 1647:     param.session_format = cuesheet->session_format;
 1648:     if (cdp->cap.burnproof) 
 1649: 	param.burnproof = 1;
 1650:     if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
 1651: 	return error;
 1652: 
 1653:     buffer = malloc(cuesheet->len, M_ACD, M_WAITOK);
 1654:     if (!buffer)
 1655: 	return ENOMEM;
 1656:     if ((error = copyin(cuesheet->entries, buffer, cuesheet->len)))
 1657: 	return error;
 1658: #ifdef ACD_DEBUG
 1659:     printf("acd: cuesheet lenght = %d\n", cuesheet->len);
 1660:     for (i=0; i<cuesheet->len; i++)
 1661: 	if (i%8)
 1662: 	    printf(" %02x", buffer[i]);
 1663: 	else
 1664: 	    printf("\n%02x", buffer[i]);
 1665:     printf("\n");
 1666: #endif
 1667:     error = atapi_queue_cmd(cdp->device, ccb, buffer, cuesheet->len, 0,
 1668: 			    30, NULL, NULL);
 1669:     free(buffer, M_ACD);
 1670:     return error;
 1671: }
 1672: 
 1673: static int
 1674: acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
 1675: {
 1676:     struct dvd_miscauth *d = NULL;
 1677:     u_int32_t lba = 0;
 1678:     int16_t length;
 1679:     int8_t ccb[16];
 1680:     int error;
 1681: 
 1682:     switch (ai->format) {
 1683:     case DVD_REPORT_AGID:
 1684:     case DVD_REPORT_ASF:
 1685:     case DVD_REPORT_RPC:
 1686: 	length = 8;
 1687: 	break;
 1688:     case DVD_REPORT_KEY1:
 1689: 	length = 12;
 1690: 	break;
 1691:     case DVD_REPORT_TITLE_KEY:
 1692: 	length = 12;
 1693: 	lba = ai->lba;
 1694: 	break;
 1695:     case DVD_REPORT_CHALLENGE:
 1696: 	length = 16;
 1697: 	break;
 1698:     case DVD_INVALIDATE_AGID:
 1699: 	length = 0;
 1700: 	break;
 1701:     default:
 1702: 	return EINVAL;
 1703:     }
 1704: 
 1705:     bzero(ccb, sizeof(ccb));
 1706:     ccb[0] = ATAPI_REPORT_KEY;
 1707:     ccb[2] = (lba >> 24) & 0xff;
 1708:     ccb[3] = (lba >> 16) & 0xff;
 1709:     ccb[4] = (lba >> 8) & 0xff;
 1710:     ccb[5] = lba & 0xff;
 1711:     ccb[8] = (length >> 8) & 0xff;
 1712:     ccb[9] = length & 0xff;
 1713:     ccb[10] = (ai->agid << 6) | ai->format;
 1714: 
 1715:     if (length) {
 1716: 	d = malloc(length, M_ACD, M_WAITOK | M_ZERO);
 1717: 	d->length = htons(length - 2);
 1718:     }
 1719: 
 1720:     error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length,
 1721: 			    ai->format == DVD_INVALIDATE_AGID ? 0 : ATPR_F_READ,
 1722: 			    10, NULL, NULL);
 1723:     if (error) {
 1724: 	free(d, M_ACD);
 1725: 	return error;
 1726:     }
 1727: 
 1728:     switch (ai->format) {
 1729:     case DVD_REPORT_AGID:
 1730: 	ai->agid = d->data[3] >> 6;
 1731: 	break;
 1732:     
 1733:     case DVD_REPORT_CHALLENGE:
 1734: 	bcopy(&d->data[0], &ai->keychal[0], 10);
 1735: 	break;
 1736:     
 1737:     case DVD_REPORT_KEY1:
 1738: 	bcopy(&d->data[0], &ai->keychal[0], 5);
 1739: 	break;
 1740:     
 1741:     case DVD_REPORT_TITLE_KEY:
 1742: 	ai->cpm = (d->data[0] >> 7);
 1743: 	ai->cp_sec = (d->data[0] >> 6) & 0x1;
 1744: 	ai->cgms = (d->data[0] >> 4) & 0x3;
 1745: 	bcopy(&d->data[1], &ai->keychal[0], 5);
 1746: 	break;
 1747:     
 1748:     case DVD_REPORT_ASF:
 1749: 	ai->asf = d->data[3] & 1;
 1750: 	break;
 1751:     
 1752:     case DVD_REPORT_RPC:
 1753: 	ai->reg_type = (d->data[0] >> 6);
 1754: 	ai->vend_rsts = (d->data[0] >> 3) & 0x7;
 1755: 	ai->user_rsts = d->data[0] & 0x7;
 1756: 	ai->region = d->data[1];
 1757: 	ai->rpc_scheme = d->data[2];
 1758: 	break;
 1759:     
 1760:     case DVD_INVALIDATE_AGID:
 1761: 	break;
 1762: 
 1763:     default:
 1764: 	error = EINVAL;
 1765:     }
 1766:     free(d, M_ACD);
 1767:     return error;
 1768: }
 1769: 
 1770: static int
 1771: acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
 1772: {
 1773:     struct dvd_miscauth *d;
 1774:     int16_t length;
 1775:     int8_t ccb[16];
 1776:     int error;
 1777: 
 1778:     switch (ai->format) {
 1779:     case DVD_SEND_CHALLENGE:
 1780: 	length = 16;
 1781: 	d = malloc(length, M_ACD, M_WAITOK | M_ZERO);
 1782: 	bcopy(ai->keychal, &d->data[0], 10);
 1783: 	break;
 1784: 
 1785:     case DVD_SEND_KEY2:
 1786: 	length = 12;
 1787: 	d = malloc(length, M_ACD, M_WAITOK | M_ZERO);
 1788: 	bcopy(&ai->keychal[0], &d->data[0], 5);
 1789: 	break;
 1790:     
 1791:     case DVD_SEND_RPC:
 1792: 	length = 8;
 1793: 	d = malloc(length, M_ACD, M_WAITOK | M_ZERO);
 1794: 	d->data[0] = ai->region;
 1795: 	break;
 1796: 
 1797:     default:
 1798: 	return EINVAL;
 1799:     }
 1800: 
 1801:     bzero(ccb, sizeof(ccb));
 1802:     ccb[0] = ATAPI_SEND_KEY;
 1803:     ccb[8] = (length >> 8) & 0xff;
 1804:     ccb[9] = length & 0xff;
 1805:     ccb[10] = (ai->agid << 6) | ai->format;
 1806:     d->length = htons(length - 2);
 1807:     error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, 0,
 1808: 			    10, NULL, NULL);
 1809:     free(d, M_ACD);
 1810:     return error;
 1811: }
 1812: 
 1813: static int
 1814: acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
 1815: {
 1816:     struct dvd_miscauth *d;
 1817:     u_int16_t length;
 1818:     int8_t ccb[16];
 1819:     int error = 0;
 1820: 
 1821:     switch(s->format) {
 1822:     case DVD_STRUCT_PHYSICAL:
 1823: 	length = 21;
 1824: 	break;
 1825: 
 1826:     case DVD_STRUCT_COPYRIGHT:
 1827: 	length = 8;
 1828: 	break;
 1829: 
 1830:     case DVD_STRUCT_DISCKEY:
 1831: 	length = 2052;
 1832: 	break;
 1833: 
 1834:     case DVD_STRUCT_BCA:
 1835: 	length = 192;
 1836: 	break;
 1837: 
 1838:     case DVD_STRUCT_MANUFACT:
 1839: 	length = 2052;
 1840: 	break;
 1841: 
 1842:     case DVD_STRUCT_DDS:
 1843:     case DVD_STRUCT_PRERECORDED:
 1844:     case DVD_STRUCT_UNIQUEID:
 1845:     case DVD_STRUCT_LIST:
 1846:     case DVD_STRUCT_CMI:
 1847:     case DVD_STRUCT_RMD_LAST:
 1848:     case DVD_STRUCT_RMD_RMA:
 1849:     case DVD_STRUCT_DCB:
 1850: 	return ENOSYS;
 1851: 
 1852:     default:
 1853: 	return EINVAL;
 1854:     }
 1855: 
 1856:     d = malloc(length, M_ACD, M_WAITOK | M_ZERO);
 1857:     d->length = htons(length - 2);
 1858: 	
 1859:     bzero(ccb, sizeof(ccb));
 1860:     ccb[0] = ATAPI_READ_STRUCTURE;
 1861:     ccb[6] = s->layer_num;
 1862:     ccb[7] = s->format;
 1863:     ccb[8] = (length >> 8) & 0xff;
 1864:     ccb[9] = length & 0xff;
 1865:     ccb[10] = s->agid << 6;
 1866:     error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, ATPR_F_READ,
 1867: 			    30, NULL, NULL);
 1868:     if (error) {
 1869: 	free(d, M_ACD);
 1870: 	return error;
 1871:     }
 1872: 
 1873:     switch (s->format) {
 1874:     case DVD_STRUCT_PHYSICAL: {
 1875: 	struct dvd_layer *layer = (struct dvd_layer *)&s->data[0];
 1876: 
 1877: 	layer->book_type = d->data[0] >> 4;
 1878: 	layer->book_version = d->data[0] & 0xf;
 1879: 	layer->disc_size = d->data[1] >> 4;
 1880: 	layer->max_rate = d->data[1] & 0xf;
 1881: 	layer->nlayers = (d->data[2] >> 5) & 3;
 1882: 	layer->track_path = (d->data[2] >> 4) & 1;
 1883: 	layer->layer_type = d->data[2] & 0xf;
 1884: 	layer->linear_density = d->data[3] >> 4;
 1885: 	layer->track_density = d->data[3] & 0xf;
 1886: 	layer->start_sector = d->data[5] << 16 | d->data[6] << 8 | d->data[7];
 1887: 	layer->end_sector = d->data[9] << 16 | d->data[10] << 8 | d->data[11];
 1888: 	layer->end_sector_l0 = d->data[13] << 16 | d->data[14] << 8|d->data[15];
 1889: 	layer->bca = d->data[16] >> 7;
 1890: 	break;
 1891:     }
 1892: 
 1893:     case DVD_STRUCT_COPYRIGHT:
 1894: 	s->cpst = d->data[0];
 1895: 	s->rmi = d->data[0];
 1896: 	break;
 1897: 
 1898:     case DVD_STRUCT_DISCKEY:
 1899: 	bcopy(&d->data[0], &s->data[0], 2048);
 1900: 	break;
 1901: 
 1902:     case DVD_STRUCT_BCA:
 1903: 	s->length = ntohs(d->length);
 1904: 	bcopy(&d->data[0], &s->data[0], s->length);
 1905: 	break;
 1906: 
 1907:     case DVD_STRUCT_MANUFACT:
 1908: 	s->length = ntohs(d->length);
 1909: 	bcopy(&d->data[0], &s->data[0], s->length);
 1910: 	break;
 1911: 		
 1912:     default:
 1913: 	error = EINVAL;
 1914:     }
 1915:     free(d, M_ACD);
 1916:     return error;
 1917: }
 1918: 
 1919: static int 
 1920: acd_eject(struct acd_softc *cdp, int close)
 1921: {
 1922:     int error;
 1923: 
 1924:     if ((error = acd_start_stop(cdp, 0)) == EBUSY) {
 1925: 	if (!close)
 1926: 	    return 0;
 1927: 	if ((error = acd_start_stop(cdp, 3)))
 1928: 	    return error;
 1929: 	acd_read_toc(cdp);
 1930: 	acd_prevent_allow(cdp, 1);
 1931: 	cdp->flags |= F_LOCKED;
 1932: 	return 0;
 1933:     }
 1934:     if (error)
 1935: 	return error;
 1936:     if (close)
 1937: 	return 0;
 1938:     acd_prevent_allow(cdp, 0);
 1939:     cdp->flags &= ~F_LOCKED;
 1940:     cdp->device->flags |= ATA_D_MEDIA_CHANGED;
 1941:     return acd_start_stop(cdp, 2);
 1942: }
 1943: 
 1944: static int
 1945: acd_blank(struct acd_softc *cdp, int blanktype)
 1946: {
 1947:     int8_t ccb[16] = { ATAPI_BLANK, 0x10 | (blanktype & 0x7), 0, 0, 0, 0, 0, 0, 
 1948: 		       0, 0, 0, 0, 0, 0, 0, 0 };
 1949: 
 1950:     cdp->device->flags |= ATA_D_MEDIA_CHANGED;
 1951:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 1952: }
 1953: 
 1954: static int
 1955: acd_prevent_allow(struct acd_softc *cdp, int lock)
 1956: {
 1957:     int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
 1958: 		       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 1959: 
 1960:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 1961: }
 1962: 
 1963: static int
 1964: acd_start_stop(struct acd_softc *cdp, int start)
 1965: {
 1966:     int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start,
 1967: 		       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 1968: 
 1969:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 1970: }
 1971: 
 1972: static int
 1973: acd_pause_resume(struct acd_softc *cdp, int pause)
 1974: {
 1975:     int8_t ccb[16] = { ATAPI_PAUSE, 0, 0, 0, 0, 0, 0, 0, pause,
 1976: 		       0, 0, 0, 0, 0, 0, 0 };
 1977: 
 1978:     return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 1979: }
 1980: 
 1981: static int
 1982: acd_mode_sense(struct acd_softc *cdp, int page, caddr_t pagebuf, int pagesize)
 1983: {
 1984:     int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, page, 0, 0, 0, 0,
 1985: 		       pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
 1986:     int error;
 1987: 
 1988:     error = atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, ATPR_F_READ,
 1989: 			    10, NULL, NULL);
 1990: #ifdef ACD_DEBUG
 1991:     atapi_dump("acd: mode sense ", pagebuf, pagesize);
 1992: #endif
 1993:     return error;
 1994: }
 1995: 
 1996: static int
 1997: acd_mode_select(struct acd_softc *cdp, caddr_t pagebuf, int pagesize)
 1998: {
 1999:     int8_t ccb[16] = { ATAPI_MODE_SELECT_BIG, 0x10, 0, 0, 0, 0, 0,
 2000: 		     pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
 2001: 
 2002: #ifdef ACD_DEBUG
 2003:     ata_prtdev(cdp->device,
 2004: 	       "modeselect pagesize=%d\n", pagesize);
 2005:     atapi_dump("mode select ", pagebuf, pagesize);
 2006: #endif
 2007:     return atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, 0,
 2008: 			   30, NULL, NULL);
 2009: }
 2010: 
 2011: static int
 2012: acd_set_speed(struct acd_softc *cdp, int rdspeed, int wrspeed)
 2013: {
 2014:     int8_t ccb[16] = { ATAPI_SET_SPEED, 0, rdspeed >> 8, rdspeed, 
 2015: 		       wrspeed >> 8, wrspeed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 2016:     int error;
 2017: 
 2018:     error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
 2019:     if (!error)
 2020: 	acd_get_cap(cdp);
 2021:     return error;
 2022: }
 2023: 
 2024: static void
 2025: acd_get_cap(struct acd_softc *cdp)
 2026: {
 2027:     int retry = 5;
 2028: 
 2029:     /* get drive capabilities, some drives needs this repeated */
 2030:     while (retry-- && acd_mode_sense(cdp, ATAPI_CDROM_CAP_PAGE,
 2031: 				     (caddr_t)&cdp->cap, sizeof(cdp->cap)))
 2032: 
 2033:     cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed);
 2034:     cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed);
 2035:     cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed);
 2036:     cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed), 177);
 2037:     cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels);
 2038:     cdp->cap.buf_size = ntohs(cdp->cap.buf_size);
 2039: }