示例#1
0
int
cd_setchan(struct cd_softc *cd, int p0, int p1, int p2, int p3, int flags)
{
	union scsi_mode_sense_buf *data;
	struct cd_audio_page *audio = NULL;
	int error, big;

	data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
	if (data == NULL)
		return (ENOMEM);

	error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
	    (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
	if (error == 0 && audio == NULL)
		error = EIO;

	if (error == 0) {
		audio->port[LEFT_PORT].channels = p0;
		audio->port[RIGHT_PORT].channels = p1;
		audio->port[2].channels = p2;
		audio->port[3].channels = p3;
		if (big)
			error = scsi_mode_select_big(cd->sc_link, SMS_PF,
			    &data->hdr_big, flags, 20000);
		else
			error = scsi_mode_select(cd->sc_link, SMS_PF,
			    &data->hdr, flags, 20000);
	}

	free(data, M_TEMP);
	return (error);
}
示例#2
0
int
cd_setvol(struct cd_softc *cd, const struct ioc_vol *arg, int flags)
{
	union scsi_mode_sense_buf *data;
	struct cd_audio_page *audio = NULL;
	u_int8_t mask_volume[4];
	int error, big;

	data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
	if (data == NULL)
		return (ENOMEM);

	error = scsi_do_mode_sense(cd->sc_link,
	    AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, data, (void **)&audio, NULL,
	    NULL, NULL, sizeof(*audio), flags, NULL);
	if (error == 0 && audio == NULL)
		error = EIO;
	if (error != 0) {
		free(data, M_TEMP);
		return (error);
	}

	mask_volume[0] = audio->port[0].volume;
	mask_volume[1] = audio->port[1].volume;
	mask_volume[2] = audio->port[2].volume;
	mask_volume[3] = audio->port[3].volume;

	error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
	    (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
	if (error == 0 && audio == NULL)
		error = EIO;
	if (error != 0) {
		free(data, M_TEMP);
		return (error);
	}

	audio->port[0].volume = arg->vol[0] & mask_volume[0];
	audio->port[1].volume = arg->vol[1] & mask_volume[1];
	audio->port[2].volume = arg->vol[2] & mask_volume[2];
	audio->port[3].volume = arg->vol[3] & mask_volume[3];

	if (big)
		error = scsi_mode_select_big(cd->sc_link, SMS_PF,
		    &data->hdr_big, flags, 20000);
	else
		error = scsi_mode_select(cd->sc_link, SMS_PF,
		    &data->hdr, flags, 20000);

	free(data, M_TEMP);
	return (error);
}
示例#3
0
int
cd_set_pa_immed(struct cd_softc *cd, int flags)
{
	union scsi_mode_sense_buf *data;
	struct cd_audio_page *audio = NULL;
	int error, oflags, big;

	if (cd->sc_link->flags & SDEV_ATAPI)
		/* XXX Noop? */
		return (0);

	data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
	if (data == NULL)
		return (ENOMEM);

	error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
	    (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
	if (error == 0 && audio == NULL)
		error = EIO;

	if (error == 0) {
		oflags = audio->flags;
		audio->flags &= ~CD_PA_SOTC;
		audio->flags |= CD_PA_IMMED;
		if (audio->flags != oflags) {
			if (big)
				error = scsi_mode_select_big(cd->sc_link,
				    SMS_PF, &data->hdr_big, flags,
				    20000);
			else
				error = scsi_mode_select(cd->sc_link, SMS_PF,
				    &data->hdr, flags, 20000);
		}
	}

	free(data, M_TEMP);
	return (error);
}
示例#4
0
int
sd_ioctl_cache(struct sd_softc *sc, long cmd, struct dk_cache *dkc)
{
	union scsi_mode_sense_buf *buf;
	struct page_caching_mode *mode = NULL;
	u_int wrcache, rdcache;
	int big;
	int rv;

	if (ISSET(sc->sc_link->flags, SDEV_UMASS))
		return (EOPNOTSUPP);

	/* see if the adapter has special handling */
	rv = scsi_do_ioctl(sc->sc_link, cmd, (caddr_t)dkc, 0);
	if (rv != ENOTTY)
		return (rv);

	buf = dma_alloc(sizeof(*buf), PR_WAITOK);
	if (buf == NULL)
		return (ENOMEM);

	rv = scsi_do_mode_sense(sc->sc_link, PAGE_CACHING_MODE,
	    buf, (void **)&mode, NULL, NULL, NULL,
	    sizeof(*mode) - 4, scsi_autoconf | SCSI_SILENT, &big);
	if (rv != 0)
		goto done;

	if ((mode == NULL) || (!DISK_PGCODE(mode, PAGE_CACHING_MODE))) {
		rv = EIO;
		goto done;
	}

	wrcache = (ISSET(mode->flags, PG_CACHE_FL_WCE) ? 1 : 0);
	rdcache = (ISSET(mode->flags, PG_CACHE_FL_RCD) ? 0 : 1);

	switch (cmd) {
	case DIOCGCACHE:
		dkc->wrcache = wrcache;
		dkc->rdcache = rdcache;
		break;

	case DIOCSCACHE:
		if (dkc->wrcache == wrcache && dkc->rdcache == rdcache)
			break;

		if (dkc->wrcache)
			SET(mode->flags, PG_CACHE_FL_WCE);
		else
			CLR(mode->flags, PG_CACHE_FL_WCE);

		if (dkc->rdcache)
			CLR(mode->flags, PG_CACHE_FL_RCD);
		else
			SET(mode->flags, PG_CACHE_FL_RCD);

		if (big) {
			rv = scsi_mode_select_big(sc->sc_link, SMS_PF,
			    &buf->hdr_big, scsi_autoconf | SCSI_SILENT, 20000);
		} else {
			rv = scsi_mode_select(sc->sc_link, SMS_PF,
			    &buf->hdr, scsi_autoconf | SCSI_SILENT, 20000);
		}
		break;
	}

done:
	dma_free(buf, sizeof(*buf));
	return (rv);
}