Set PQUIRK_ONLYBIG in the wdc-atapi frontend, obviating the need to ever test
the "bus type" for this. Merge all the code in the SCSI and ATAPI backends for "cd" devices. All of the mode page handling and whatnot is general to SCSI MMC devices, and should never have been separated to begin with. This fixes a variety of problems, and adds load/unload support for SCSI-attached devices.
This commit is contained in:
parent
ce112dfc4f
commit
b6e043eed2
@ -1,136 +0,0 @@
|
||||
/* $NetBSD: atapi_cd.h,v 1.10 2001/05/14 20:35:27 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Manuel Bouyer. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Manuel Bouyer.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define ATAPI_LOAD_UNLOAD 0xa6
|
||||
struct atapi_load_unload {
|
||||
u_int8_t opcode;
|
||||
u_int8_t unused1[3];
|
||||
u_int8_t options;
|
||||
u_int8_t unused2[3];
|
||||
u_int8_t slot;
|
||||
u_int8_t unused3[3];
|
||||
};
|
||||
|
||||
struct atapi_cdrom_page {
|
||||
u_int8_t page;
|
||||
u_int8_t length;
|
||||
u_int8_t reserved;
|
||||
u_int8_t inact_mult;
|
||||
u_int8_t spm[2];
|
||||
u_int8_t fps[2];
|
||||
};
|
||||
|
||||
struct atapi_cap_page {
|
||||
/* Capabilities page */
|
||||
u_int8_t page_code;
|
||||
u_int8_t param_len;
|
||||
u_int8_t reserved1[2];
|
||||
|
||||
u_int8_t cap1;
|
||||
#define AUDIO_PLAY 0x01 /* audio play supported */
|
||||
#define AV_COMPOSITE /* composite audio/video supported */
|
||||
#define DA_PORT1 /* digital audio on port 1 */
|
||||
#define DA_PORT2 /* digital audio on port 2 */
|
||||
#define M2F1 /* mode 2 form 1 (XA) read */
|
||||
#define M2F2 /* mode 2 form 2 format */
|
||||
#define CD_MULTISESSION /* multi-session photo-CD */
|
||||
u_int8_t cap2;
|
||||
#define CD_DA 0x01 /* audio-CD read supported */
|
||||
#define CD_DA_STREAM 0x02 /* CD-DA streaming */
|
||||
#define RW_SUB 0x04 /* combined R-W subchannels */
|
||||
#define RW_SUB_CORR 0x08 /* R-W subchannel data corrected */
|
||||
#define C2_ERRP 0x10 /* C2 error pointers supported */
|
||||
#define ISRC 0x20 /* can return the ISRC */
|
||||
#define UPC 0x40 /* can return the catalog number UPC */
|
||||
u_int8_t m_status;
|
||||
#define CANLOCK 0x01 /* could be locked */
|
||||
#define LOCK_STATE 0x02 /* current lock state */
|
||||
#define PREVENT_JUMP 0x04 /* prevent jumper installed */
|
||||
#define CANEJECT 0x08 /* can eject */
|
||||
#define MECH_MASK 0xe0 /* loading mechanism type */
|
||||
#define MECH_CADDY 0x00
|
||||
#define MECH_TRAY 0x20
|
||||
#define MECH_POPUP 0x40
|
||||
#define MECH_CHANGER_INDIV 0x80
|
||||
#define MECH_CHANGER_CARTRIDGE 0xa0
|
||||
u_int8_t cap3;
|
||||
#define SEPARATE_VOL 0x01 /* independent volume of channels */
|
||||
#define SEPARATE_MUTE 0x02 /* independent mute of channels */
|
||||
#define SUPP_DISK_PRESENT 0x04 /* changer can report contents of slots */
|
||||
#define SSS 0x08 /* software slot selection */
|
||||
u_int8_t max_speed[2]; /* max raw data rate in bytes/1000 */
|
||||
u_int8_t max_vol_levels[2]; /* number of discrete volume levels */
|
||||
u_int8_t buf_size[2]; /* internal buffer size in bytes/1024 */
|
||||
u_int8_t cur_speed[2]; /* current data rate in bytes/1000 */
|
||||
/* Digital drive output format description (optional?) */
|
||||
u_int8_t reserved2;
|
||||
u_int8_t dig_output; /* Digital drive output format description */
|
||||
u_int8_t reserved3[2];
|
||||
};
|
||||
|
||||
#define ATAPI_CDROM_PAGE 0x0d
|
||||
#define ATAPI_AUDIO_PAGE 0x0e
|
||||
#define ATAPI_AUDIO_PAGE_MASK 0x4e
|
||||
#define ATAPI_CAP_PAGE 0x2a
|
||||
|
||||
union atapi_cd_pages {
|
||||
u_int8_t page_code;
|
||||
struct atapi_cdrom_page cdrom;
|
||||
struct atapi_cap_page cap;
|
||||
struct cd_audio_page audio;
|
||||
};
|
||||
|
||||
struct atapi_cd_mode_data {
|
||||
struct scsipi_mode_header_big header;
|
||||
union atapi_cd_pages pages;
|
||||
};
|
||||
|
||||
/* medium type in scsipi_mode_header_big */
|
||||
#define MDT_UNKNOWN 0x00
|
||||
#define MDT_DATA_120 0x01
|
||||
#define MDT_AUDIO_120 0x02
|
||||
#define MDT_COMB_120 0x03
|
||||
#define MDT_PHOTO_120 0x04
|
||||
#define MDT_DATA_80 0x05
|
||||
#define MDT_AUDIO_80 0x06
|
||||
#define MDT_COMB_80 0x07
|
||||
#define MDT_PHOTO_80 0x08
|
||||
#define MDT_NO_DISC 0x70
|
||||
#define MDT_DOOR_OPEN 0x71
|
||||
#define MDT_FMT_ERROR 0x72
|
||||
|
||||
|
||||
#define AUDIOPAGESIZE \
|
||||
(sizeof(struct scsipi_mode_header_big) + sizeof(struct cd_audio_page))
|
||||
#define CDROMPAGESIZE \
|
||||
(sizeof(struct scsipi_mode_header_big) + sizeof(struct atapi_cdrom_page))
|
||||
#define CAPPAGESIZE \
|
||||
(sizeof(struct scsipi_mode_header_big) + sizeof(struct atapi_cap_page))
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: atapi_wdc.c,v 1.55 2002/09/27 15:37:33 provos Exp $ */
|
||||
/* $NetBSD: atapi_wdc.c,v 1.56 2003/09/07 22:11:22 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Manuel Bouyer.
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.55 2002/09/27 15:37:33 provos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.56 2003/09/07 22:11:22 mycroft Exp $");
|
||||
|
||||
#ifndef WDCDEBUG
|
||||
#define WDCDEBUG
|
||||
@ -277,6 +277,7 @@ wdc_atapi_probe_device(sc, target)
|
||||
periph->periph_switch = &atapi_probe_periphsw;
|
||||
periph->periph_target = target;
|
||||
periph->periph_lun = 0;
|
||||
periph->periph_quirks = PQUIRK_ONLYBIG;
|
||||
|
||||
#ifdef SCSIPI_DEBUG
|
||||
if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI &&
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: cd.c,v 1.187 2003/07/18 14:33:54 wiz Exp $ */
|
||||
/* $NetBSD: cd.c,v 1.188 2003/09/07 22:11:23 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 2001, 2003 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -54,7 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.187 2003/07/18 14:33:54 wiz Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.188 2003/09/07 22:11:23 mycroft Exp $");
|
||||
|
||||
#include "rnd.h"
|
||||
|
||||
@ -84,6 +84,7 @@ __KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.187 2003/07/18 14:33:54 wiz Exp $");
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsipi_cd.h>
|
||||
#include <dev/scsipi/scsipi_disk.h> /* rw_big and start_stop come */
|
||||
#include <dev/scsipi/scsi_all.h>
|
||||
/* from there */
|
||||
#include <dev/scsipi/scsi_disk.h> /* rw comes from there */
|
||||
#include <dev/scsipi/scsipiconf.h>
|
||||
@ -130,6 +131,7 @@ int cd_read_toc __P((struct cd_softc *, int, int, void *, int, int, int));
|
||||
int cd_get_parms __P((struct cd_softc *, int));
|
||||
int cd_load_toc __P((struct cd_softc *, struct cd_toc *, int));
|
||||
int cdreadmsaddr __P((struct cd_softc *, int *));
|
||||
|
||||
int dvd_auth __P((struct cd_softc *, dvd_authinfo *));
|
||||
int dvd_read_physical __P((struct cd_softc *, dvd_struct *));
|
||||
int dvd_read_copyright __P((struct cd_softc *, dvd_struct *));
|
||||
@ -138,6 +140,15 @@ int dvd_read_bca __P((struct cd_softc *, dvd_struct *));
|
||||
int dvd_read_manufact __P((struct cd_softc *, dvd_struct *));
|
||||
int dvd_read_struct __P((struct cd_softc *, dvd_struct *));
|
||||
|
||||
static int cd_mode_sense __P((struct cd_softc *, u_int8_t, void *, size_t, int,
|
||||
int, int *));
|
||||
int cd_setchan __P((struct cd_softc *, int, int, int, int, int));
|
||||
int cd_getvol __P((struct cd_softc *, struct ioc_vol *, int));
|
||||
int cd_setvol __P((struct cd_softc *, const struct ioc_vol *, int));
|
||||
int cd_set_pa_immed __P((struct cd_softc *, int));
|
||||
int cd_load_unload __P((struct cd_softc *, struct ioc_load_unload *));
|
||||
int cd_setblksize __P((struct cd_softc *));
|
||||
|
||||
extern struct cfdriver cd_cd;
|
||||
|
||||
dev_type_open(cdopen);
|
||||
@ -172,11 +183,10 @@ const struct scsipi_periphsw cd_switch = {
|
||||
* A device suitable for this driver
|
||||
*/
|
||||
void
|
||||
cdattach(parent, cd, periph, ops)
|
||||
cdattach(parent, cd, periph)
|
||||
struct device *parent;
|
||||
struct cd_softc *cd;
|
||||
struct scsipi_periph *periph;
|
||||
const struct cd_ops *ops;
|
||||
{
|
||||
SC_DEBUG(periph, SCSIPI_DB2, ("cdattach: "));
|
||||
|
||||
@ -186,7 +196,6 @@ cdattach(parent, cd, periph, ops)
|
||||
* Store information needed to contact our base driver
|
||||
*/
|
||||
cd->sc_periph = periph;
|
||||
cd->sc_ops = ops;
|
||||
|
||||
periph->periph_dev = &cd->sc_dev;
|
||||
periph->periph_switch = &cd_switch;
|
||||
@ -784,8 +793,7 @@ cdstart(periph)
|
||||
*/
|
||||
if (((bp->b_rawblkno & 0x1fffff) == bp->b_rawblkno) &&
|
||||
((nblks & 0xff) == nblks) &&
|
||||
!(periph->periph_quirks & PQUIRK_ONLYBIG) &&
|
||||
scsipi_periph_bustype(periph) == SCSIPI_BUSTYPE_SCSI) {
|
||||
!(periph->periph_quirks & PQUIRK_ONLYBIG)) {
|
||||
/*
|
||||
* We can fit in a small cdb.
|
||||
*/
|
||||
@ -1246,7 +1254,7 @@ bad:
|
||||
case CDIOCPLAYTRACKS: {
|
||||
struct ioc_play_track *args = (struct ioc_play_track *)addr;
|
||||
|
||||
if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
|
||||
if ((error = cd_set_pa_immed(cd, 0)) != 0)
|
||||
return (error);
|
||||
return (cd_play_tracks(cd, args->start_track,
|
||||
args->start_index, args->end_track, args->end_index));
|
||||
@ -1254,7 +1262,7 @@ bad:
|
||||
case CDIOCPLAYMSF: {
|
||||
struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
|
||||
|
||||
if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
|
||||
if ((error = cd_set_pa_immed(cd, 0)) != 0)
|
||||
return (error);
|
||||
return (cd_play_msf(cd, args->start_m, args->start_s,
|
||||
args->start_f, args->end_m, args->end_s, args->end_f));
|
||||
@ -1262,7 +1270,7 @@ bad:
|
||||
case CDIOCPLAYBLOCKS: {
|
||||
struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
|
||||
|
||||
if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
|
||||
if ((error = cd_set_pa_immed(cd, 0)) != 0)
|
||||
return (error);
|
||||
return (cd_play(cd, args->blk, args->len));
|
||||
}
|
||||
@ -1346,39 +1354,39 @@ bad:
|
||||
case CDIOCSETPATCH: {
|
||||
struct ioc_patch *arg = (struct ioc_patch *)addr;
|
||||
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, arg->patch[0],
|
||||
arg->patch[1], arg->patch[2], arg->patch[3], 0));
|
||||
return (cd_setchan(cd, arg->patch[0], arg->patch[1],
|
||||
arg->patch[2], arg->patch[3], 0));
|
||||
}
|
||||
case CDIOCGETVOL: {
|
||||
struct ioc_vol *arg = (struct ioc_vol *)addr;
|
||||
|
||||
return ((*cd->sc_ops->cdo_getvol)(cd, arg, 0));
|
||||
return (cd_getvol(cd, arg, 0));
|
||||
}
|
||||
case CDIOCSETVOL: {
|
||||
struct ioc_vol *arg = (struct ioc_vol *)addr;
|
||||
|
||||
return ((*cd->sc_ops->cdo_setvol)(cd, arg, 0));
|
||||
return (cd_setvol(cd, arg, 0));
|
||||
}
|
||||
|
||||
case CDIOCSETMONO:
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, BOTH_CHANNEL,
|
||||
BOTH_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
return (cd_setchan(cd, BOTH_CHANNEL, BOTH_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
|
||||
case CDIOCSETSTEREO:
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
|
||||
RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
return (cd_setchan(cd, LEFT_CHANNEL, RIGHT_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
|
||||
case CDIOCSETMUTE:
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, MUTE_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
return (cd_setchan(cd, MUTE_CHANNEL, MUTE_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
|
||||
case CDIOCSETLEFT:
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
|
||||
LEFT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
return (cd_setchan(cd, LEFT_CHANNEL, LEFT_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
|
||||
case CDIOCSETRIGHT:
|
||||
return ((*cd->sc_ops->cdo_setchan)(cd, RIGHT_CHANNEL,
|
||||
RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
return (cd_setchan(cd, RIGHT_CHANNEL, RIGHT_CHANNEL,
|
||||
MUTE_CHANNEL, MUTE_CHANNEL, 0));
|
||||
|
||||
case CDIOCRESUME:
|
||||
return (cd_pause(cd, PA_RESUME));
|
||||
@ -1428,16 +1436,12 @@ bad:
|
||||
case CDIOCRESET:
|
||||
case SCIOCRESET:
|
||||
return (cd_reset(cd));
|
||||
case CDIOCLOADUNLOAD: {
|
||||
struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
|
||||
|
||||
return ((*cd->sc_ops->cdo_load_unload)(cd, args->options,
|
||||
args->slot));
|
||||
case CDIOCLOADUNLOAD:
|
||||
return (cd_load_unload(cd, (struct ioc_load_unload *)addr));
|
||||
case DVD_AUTH:
|
||||
return (dvd_auth(cd, (dvd_authinfo *)addr));
|
||||
case DVD_READ_STRUCT:
|
||||
return (dvd_read_struct(cd, (dvd_struct *)addr));
|
||||
}
|
||||
|
||||
default:
|
||||
if (part != RAW_PART)
|
||||
@ -1591,17 +1595,11 @@ cd_size(cd, flags)
|
||||
blksize = _4btol(rdcap.length);
|
||||
if ((blksize < 512) || ((blksize & 511) != 0))
|
||||
blksize = 2048; /* some drives lie ! */
|
||||
cd->params.blksize = blksize;
|
||||
|
||||
if (cd->params.blksize != 2048 && cd->sc_ops->cdo_setblksize != NULL) {
|
||||
(*cd->sc_ops->cdo_setblksize)(cd);
|
||||
if (scsipi_command(cd->sc_periph,
|
||||
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
|
||||
(u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 30000, NULL,
|
||||
flags | XS_CTL_DATA_IN | XS_CTL_DATA_IN) != 0)
|
||||
return (0);
|
||||
blksize = _4btol(rdcap.length);
|
||||
if (blksize != 2048) {
|
||||
if (cd_setblksize(cd) == 0)
|
||||
blksize = 2048;
|
||||
}
|
||||
cd->params.blksize = blksize;
|
||||
|
||||
size = _4btol(rdcap.addr) + 1;
|
||||
if (size < 100)
|
||||
@ -2164,3 +2162,288 @@ dvd_read_struct(cd, s)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cd_mode_sense(cd, byte2, sense, size, page, flags, big)
|
||||
struct cd_softc *cd;
|
||||
u_int8_t byte2;
|
||||
void *sense;
|
||||
size_t size;
|
||||
int page, flags;
|
||||
int *big;
|
||||
{
|
||||
|
||||
if (cd->sc_periph->periph_quirks & PQUIRK_ONLYBIG) {
|
||||
*big = 1;
|
||||
return scsipi_mode_sense_big(cd->sc_periph, byte2, page, sense,
|
||||
size, flags | XS_CTL_SILENT | XS_CTL_DATA_ONSTACK,
|
||||
CDRETRIES, 20000);
|
||||
} else {
|
||||
*big = 0;
|
||||
return scsipi_mode_sense(cd->sc_periph, byte2, page, sense,
|
||||
size, flags | XS_CTL_SILENT | XS_CTL_DATA_ONSTACK,
|
||||
CDRETRIES, 20000);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cd_set_pa_immed(cd, flags)
|
||||
struct cd_softc *cd;
|
||||
int flags;
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
struct scsipi_mode_header small;
|
||||
struct scsipi_mode_header_big big;
|
||||
} header;
|
||||
struct cd_audio_page page;
|
||||
} data;
|
||||
int error;
|
||||
uint8_t oflags;
|
||||
int big;
|
||||
struct cd_audio_page *page;
|
||||
|
||||
if ((error = cd_mode_sense(cd, SMS_DBD, &data, sizeof(data),
|
||||
AUDIO_PAGE, flags, &big)) != 0)
|
||||
return (error);
|
||||
|
||||
if (big)
|
||||
page = (void *)(&data.header.big + 1);
|
||||
else
|
||||
page = (void *)(&data.header.small + 1);
|
||||
|
||||
oflags = page->flags;
|
||||
page->flags &= ~CD_PA_SOTC;
|
||||
page->flags |= CD_PA_IMMED;
|
||||
if (oflags == page->flags) {
|
||||
printf("flags are same; punting\n");
|
||||
return (0);
|
||||
} else {
|
||||
printf("flags are not same; changing\n");
|
||||
}
|
||||
|
||||
if (big) {
|
||||
_lto2b(0, data.header.big.data_length);
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.big) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
} else {
|
||||
data.header.small.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.small) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cd_setchan(cd, p0, p1, p2, p3, flags)
|
||||
struct cd_softc *cd;
|
||||
int p0, p1, p2, p3;
|
||||
int flags;
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
struct scsipi_mode_header small;
|
||||
struct scsipi_mode_header_big big;
|
||||
} header;
|
||||
struct cd_audio_page page;
|
||||
} data;
|
||||
int error;
|
||||
int big;
|
||||
struct cd_audio_page *page;
|
||||
|
||||
if ((error = cd_mode_sense(cd, SMS_DBD, &data, sizeof(data),
|
||||
AUDIO_PAGE, flags, &big)) != 0)
|
||||
return (error);
|
||||
|
||||
if (big)
|
||||
page = (void *)(&data.header.big + 1);
|
||||
else
|
||||
page = (void *)(&data.header.small + 1);
|
||||
|
||||
page->port[0].channels = p0;
|
||||
page->port[1].channels = p1;
|
||||
page->port[2].channels = p2;
|
||||
page->port[3].channels = p3;
|
||||
|
||||
if (big) {
|
||||
_lto2b(0, data.header.big.data_length);
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.big) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
} else {
|
||||
data.header.small.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.small) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cd_getvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
struct scsipi_mode_header small;
|
||||
struct scsipi_mode_header_big big;
|
||||
} header;
|
||||
struct cd_audio_page page;
|
||||
} data;
|
||||
int error;
|
||||
int big;
|
||||
struct cd_audio_page *page;
|
||||
|
||||
if ((error = cd_mode_sense(cd, SMS_DBD, &data, sizeof(data),
|
||||
AUDIO_PAGE, flags, &big)) != 0)
|
||||
return (error);
|
||||
|
||||
if (big)
|
||||
page = (void *)(&data.header.big + 1);
|
||||
else
|
||||
page = (void *)(&data.header.small + 1);
|
||||
|
||||
arg->vol[0] = page->port[0].volume;
|
||||
arg->vol[1] = page->port[1].volume;
|
||||
arg->vol[2] = page->port[2].volume;
|
||||
arg->vol[3] = page->port[3].volume;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cd_setvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
const struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
struct scsipi_mode_header small;
|
||||
struct scsipi_mode_header_big big;
|
||||
} header;
|
||||
struct cd_audio_page page;
|
||||
} data, mask;
|
||||
int error;
|
||||
int big;
|
||||
struct cd_audio_page *page, *page2;
|
||||
|
||||
if ((error = cd_mode_sense(cd, SMS_DBD, &data, sizeof(data),
|
||||
AUDIO_PAGE, flags, &big)) != 0)
|
||||
return (error);
|
||||
if ((error = cd_mode_sense(cd, SMS_DBD, &mask, sizeof(mask),
|
||||
AUDIO_PAGE|SMS_PAGE_CTRL_CHANGEABLE, flags, &big)) != 0)
|
||||
return (error);
|
||||
|
||||
if (big) {
|
||||
page = (void *)(&data.header.big + 1);
|
||||
page2 = (void *)(&mask.header.big + 1);
|
||||
} else {
|
||||
page = (void *)(&data.header.small + 1);
|
||||
page2 = (void *)(&mask.header.small + 1);
|
||||
}
|
||||
|
||||
page->port[0].volume = arg->vol[0] & page2->port[0].volume;
|
||||
page->port[1].volume = arg->vol[1] & page2->port[1].volume;
|
||||
page->port[2].volume = arg->vol[2] & page2->port[2].volume;
|
||||
page->port[3].volume = arg->vol[3] & page2->port[3].volume;
|
||||
|
||||
page->port[0].channels = CHANNEL_0;
|
||||
page->port[1].channels = CHANNEL_1;
|
||||
|
||||
if (big) {
|
||||
_lto2b(0, data.header.big.data_length);
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.big) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
} else {
|
||||
data.header.small.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.small) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
page->pg_length,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cd_load_unload(cd, args)
|
||||
struct cd_softc *cd;
|
||||
struct ioc_load_unload *args;
|
||||
{
|
||||
struct scsipi_load_unload scsipi_cmd;
|
||||
|
||||
memset(&scsipi_cmd, 0, sizeof(scsipi_cmd));
|
||||
scsipi_cmd.opcode = LOAD_UNLOAD;
|
||||
scsipi_cmd.options = args->options; /* ioctl uses MMC values */
|
||||
scsipi_cmd.slot = args->slot;
|
||||
|
||||
return (scsipi_command(cd->sc_periph,
|
||||
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
|
||||
0, 0, CDRETRIES, 200000, NULL, 0));
|
||||
}
|
||||
|
||||
int
|
||||
cd_setblksize(cd)
|
||||
struct cd_softc *cd;
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
struct scsipi_mode_header small;
|
||||
struct scsipi_mode_header_big big;
|
||||
} header;
|
||||
struct scsi_blk_desc blk_desc;
|
||||
} data;
|
||||
int error;
|
||||
int big, bsize;
|
||||
struct scsi_blk_desc *bdesc;
|
||||
|
||||
if ((error = cd_mode_sense(cd, 0, &data, sizeof(data), 0, 0,
|
||||
&big)) != 0)
|
||||
return (error);
|
||||
|
||||
if (big) {
|
||||
bdesc = (void *)(&data.header.big + 1);
|
||||
bsize = _2btol(data.header.big.blk_desc_len);
|
||||
} else {
|
||||
bdesc = (void *)(&data.header.small + 1);
|
||||
bsize = data.header.small.blk_desc_len;
|
||||
}
|
||||
|
||||
if (bsize == 0) {
|
||||
printf("trying to change bsize, but no blk_desc\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (_3btol(bdesc->blklen) == 2048) {
|
||||
printf("trying to change bsize, but blk_desc is correct\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
_lto3b(2048, bdesc->blklen);
|
||||
|
||||
if (big) {
|
||||
_lto2b(0, data.header.big.data_length);
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.big) +
|
||||
sizeof(struct scsi_blk_desc),
|
||||
XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
} else {
|
||||
data.header.small.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
(void *)&data, sizeof(data.header.small) +
|
||||
sizeof(struct scsi_blk_desc),
|
||||
XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd_atapi.c,v 1.25 2003/09/05 09:04:26 mycroft Exp $ */
|
||||
/* $NetBSD: cd_atapi.c,v 1.26 2003/09/07 22:11:23 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
|
||||
@ -29,25 +29,8 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Originally written by Julian Elischer (julian@tfs.com)
|
||||
* for TRW Financial Systems for use under the MACH(2.5) operating system.
|
||||
*
|
||||
* TRW Financial Systems, in accordance with their agreement with Carnegie
|
||||
* Mellon University, makes this software available to CMU to distribute
|
||||
* or use in any manner that they see fit as long as this message is kept with
|
||||
* the software. For this reason TFS also grants any other persons or
|
||||
* organisations permission to use or modify this software.
|
||||
*
|
||||
* TFS supplies this software to be publicly redistributed
|
||||
* on the understanding that TFS is not responsible for the correct
|
||||
* functioning of this software in any circumstances.
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd_atapi.c,v 1.25 2003/09/05 09:04:26 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd_atapi.c,v 1.26 2003/09/07 22:11:23 mycroft Exp $");
|
||||
|
||||
#include "rnd.h"
|
||||
|
||||
@ -62,11 +45,8 @@ __KERNEL_RCSID(0, "$NetBSD: cd_atapi.c,v 1.25 2003/09/05 09:04:26 mycroft Exp $"
|
||||
#include <sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/cdio.h>
|
||||
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsipi_cd.h>
|
||||
#include <dev/scsipi/atapi_cd.h>
|
||||
#include <dev/scsipi/atapiconf.h>
|
||||
#include <dev/scsipi/cdvar.h>
|
||||
|
||||
@ -85,22 +65,6 @@ struct scsipi_inquiry_pattern cd_atapibus_patterns[] = {
|
||||
"NEC CD-ROM DRIVE:260", "", ""},
|
||||
};
|
||||
|
||||
int cd_atapibus_setchan __P((struct cd_softc *, int, int, int, int, int));
|
||||
int cd_atapibus_getvol __P((struct cd_softc *, struct ioc_vol *, int));
|
||||
int cd_atapibus_setvol __P((struct cd_softc *, const struct ioc_vol *,
|
||||
int));
|
||||
int cd_atapibus_set_pa_immed __P((struct cd_softc *, int));
|
||||
int cd_atapibus_load_unload __P((struct cd_softc *, int, int));
|
||||
|
||||
const struct cd_ops cd_atapibus_ops = {
|
||||
cd_atapibus_setchan,
|
||||
cd_atapibus_getvol,
|
||||
cd_atapibus_setvol,
|
||||
cd_atapibus_set_pa_immed,
|
||||
cd_atapibus_load_unload,
|
||||
NULL, /* no cdo_setblksize */
|
||||
};
|
||||
|
||||
int
|
||||
cd_atapibus_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
@ -137,106 +101,7 @@ cd_atapibus_attach(parent, self, aux)
|
||||
|
||||
strncpy(cd->name, sa->sa_inqbuf.vendor, 16);
|
||||
|
||||
cdattach(parent, cd, periph, &cd_atapibus_ops);
|
||||
cdattach(parent, cd, periph);
|
||||
|
||||
/* XXX should I get the ATAPI_CAP_PAGE here ? */
|
||||
}
|
||||
|
||||
int
|
||||
cd_atapibus_setchan(cd, p0, p1, p2, p3, flags)
|
||||
struct cd_softc *cd;
|
||||
int p0, p1, p2, p3, flags;
|
||||
{
|
||||
struct atapi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense_big(cd->sc_periph, SMS_DBD,
|
||||
ATAPI_AUDIO_PAGE, &data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
data.pages.audio.port[LEFT_PORT].channels = p0;
|
||||
data.pages.audio.port[RIGHT_PORT].channels = p1;
|
||||
data.pages.audio.port[2].channels = p2;
|
||||
data.pages.audio.port[3].channels = p3;
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
||||
int
|
||||
cd_atapibus_getvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
struct atapi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense_big(cd->sc_periph, SMS_DBD,
|
||||
ATAPI_AUDIO_PAGE, &data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
arg->vol[0] = data.pages.audio.port[0].volume;
|
||||
arg->vol[1] = data.pages.audio.port[1].volume;
|
||||
arg->vol[2] = data.pages.audio.port[2].volume;
|
||||
arg->vol[3] = data.pages.audio.port[3].volume;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cd_atapibus_setvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
const struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
struct atapi_cd_mode_data data, mask;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense_big(cd->sc_periph, SMS_DBD,
|
||||
ATAPI_AUDIO_PAGE, &data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
if ((error = scsipi_mode_sense_big(cd->sc_periph, SMS_DBD,
|
||||
ATAPI_AUDIO_PAGE_MASK, &mask.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
|
||||
data.pages.audio.port[0].volume = arg->vol[0] &
|
||||
mask.pages.audio.port[0].volume;
|
||||
data.pages.audio.port[1].volume = arg->vol[1] &
|
||||
mask.pages.audio.port[1].volume;
|
||||
data.pages.audio.port[2].volume = arg->vol[2] &
|
||||
mask.pages.audio.port[2].volume;
|
||||
data.pages.audio.port[3].volume = arg->vol[3] &
|
||||
mask.pages.audio.port[3].volume;
|
||||
|
||||
return (scsipi_mode_select_big(cd->sc_periph, SMS_PF,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
||||
int
|
||||
cd_atapibus_set_pa_immed(cd, flags)
|
||||
struct cd_softc *cd;
|
||||
int flags;
|
||||
{
|
||||
|
||||
/* Noop. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cd_atapibus_load_unload(cd, options, slot)
|
||||
struct cd_softc *cd;
|
||||
int options, slot;
|
||||
{
|
||||
struct atapi_load_unload atapi_cmd;
|
||||
|
||||
memset(&atapi_cmd, 0, sizeof(atapi_cmd));
|
||||
atapi_cmd.opcode = ATAPI_LOAD_UNLOAD;
|
||||
atapi_cmd.options = options; /* ioctl uses ATAPI values */
|
||||
atapi_cmd.slot = slot;
|
||||
return (scsipi_command(cd->sc_periph,
|
||||
(struct scsipi_generic *)&atapi_cmd, sizeof(atapi_cmd),
|
||||
0, 0, CDRETRIES, 200000, NULL, 0));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd_scsi.c,v 1.29 2003/09/05 09:04:26 mycroft Exp $ */
|
||||
/* $NetBSD: cd_scsi.c,v 1.30 2003/09/07 22:11:23 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
|
||||
@ -36,25 +36,8 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Originally written by Julian Elischer (julian@tfs.com)
|
||||
* for TRW Financial Systems for use under the MACH(2.5) operating system.
|
||||
*
|
||||
* TRW Financial Systems, in accordance with their agreement with Carnegie
|
||||
* Mellon University, makes this software available to CMU to distribute
|
||||
* or use in any manner that they see fit as long as this message is kept with
|
||||
* the software. For this reason TFS also grants any other persons or
|
||||
* organisations permission to use or modify this software.
|
||||
*
|
||||
* TFS supplies this software to be publicly redistributed
|
||||
* on the understanding that TFS is not responsible for the correct
|
||||
* functioning of this software in any circumstances.
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd_scsi.c,v 1.29 2003/09/05 09:04:26 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd_scsi.c,v 1.30 2003/09/07 22:11:23 mycroft Exp $");
|
||||
|
||||
#include "rnd.h"
|
||||
|
||||
@ -69,12 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: cd_scsi.c,v 1.29 2003/09/05 09:04:26 mycroft Exp $")
|
||||
#include <sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/cdio.h>
|
||||
|
||||
#include <dev/scsipi/scsi_all.h>
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsipi_cd.h>
|
||||
#include <dev/scsipi/scsi_cd.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
#include <dev/scsipi/cdvar.h>
|
||||
|
||||
@ -95,23 +74,6 @@ struct scsipi_inquiry_pattern cd_scsibus_patterns[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
int cd_scsibus_setchan __P((struct cd_softc *, int, int, int, int, int));
|
||||
int cd_scsibus_getvol __P((struct cd_softc *, struct ioc_vol *, int));
|
||||
int cd_scsibus_setvol __P((struct cd_softc *, const struct ioc_vol *,
|
||||
int));
|
||||
int cd_scsibus_set_pa_immed __P((struct cd_softc *, int));
|
||||
int cd_scsibus_load_unload __P((struct cd_softc *, int, int));
|
||||
int cd_scsibus_setblksize __P((struct cd_softc *));
|
||||
|
||||
const struct cd_ops cd_scsibus_ops = {
|
||||
cd_scsibus_setchan,
|
||||
cd_scsibus_getvol,
|
||||
cd_scsibus_setvol,
|
||||
cd_scsibus_set_pa_immed,
|
||||
cd_scsibus_load_unload,
|
||||
cd_scsibus_setblksize,
|
||||
};
|
||||
|
||||
int
|
||||
cd_scsibus_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
@ -148,7 +110,7 @@ cd_scsibus_attach(parent, self, aux)
|
||||
|
||||
scsipi_strvis(cd->name, 16, sa->sa_inqbuf.product, 16);
|
||||
|
||||
cdattach(parent, cd, periph, &cd_scsibus_ops);
|
||||
cdattach(parent, cd, periph);
|
||||
|
||||
/*
|
||||
* Note if this device is ancient. This is used in cdminphys().
|
||||
@ -158,125 +120,3 @@ cd_scsibus_attach(parent, self, aux)
|
||||
|
||||
/* should I get the SCSI_CAP_PAGE here ? */
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_set_pa_immed(cd, flags)
|
||||
struct cd_softc *cd;
|
||||
int flags;
|
||||
{
|
||||
struct scsi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense(cd->sc_periph, SMS_DBD, AUDIO_PAGE,
|
||||
&data.header, AUDIOPAGESIZE, flags | XS_CTL_DATA_ONSTACK,
|
||||
CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
data.page.audio.flags &= ~CD_PA_SOTC;
|
||||
data.page.audio.flags |= CD_PA_IMMED;
|
||||
data.header.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_setchan(cd, p0, p1, p2, p3, flags)
|
||||
struct cd_softc *cd;
|
||||
int p0, p1, p2, p3;
|
||||
int flags;
|
||||
{
|
||||
struct scsi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense(cd->sc_periph, SMS_DBD, AUDIO_PAGE,
|
||||
&data.header, AUDIOPAGESIZE, flags | XS_CTL_DATA_ONSTACK,
|
||||
CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
data.page.audio.port[LEFT_PORT].channels = p0;
|
||||
data.page.audio.port[RIGHT_PORT].channels = p1;
|
||||
data.page.audio.port[2].channels = p2;
|
||||
data.page.audio.port[3].channels = p3;
|
||||
data.header.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_getvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
|
||||
struct scsi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense(cd->sc_periph, SMS_DBD, AUDIO_PAGE,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
|
||||
arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
|
||||
arg->vol[2] = data.page.audio.port[2].volume;
|
||||
arg->vol[3] = data.page.audio.port[3].volume;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_setvol(cd, arg, flags)
|
||||
struct cd_softc *cd;
|
||||
const struct ioc_vol *arg;
|
||||
int flags;
|
||||
{
|
||||
struct scsi_cd_mode_data data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense(cd->sc_periph, SMS_DBD, AUDIO_PAGE,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
|
||||
return (error);
|
||||
data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
|
||||
data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
|
||||
data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
|
||||
data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
|
||||
data.page.audio.port[2].volume = arg->vol[2];
|
||||
data.page.audio.port[3].volume = arg->vol[3];
|
||||
data.header.data_length = 0;
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF,
|
||||
&data.header, AUDIOPAGESIZE,
|
||||
flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_load_unload(cd, options, slot)
|
||||
struct cd_softc *cd;
|
||||
int options, slot;
|
||||
{
|
||||
/*
|
||||
* Not supported on SCSI CDs that we know of (but we'll leave
|
||||
* the hook here Just In Case).
|
||||
*/
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
int
|
||||
cd_scsibus_setblksize(cd)
|
||||
struct cd_softc *cd;
|
||||
{
|
||||
struct {
|
||||
struct scsipi_mode_header header;
|
||||
struct scsi_blk_desc blk_desc;
|
||||
} data;
|
||||
int error;
|
||||
|
||||
if ((error = scsipi_mode_sense(cd->sc_periph, 0, 0, &data.header,
|
||||
sizeof(data), XS_CTL_DATA_ONSTACK, CDRETRIES,20000)) != 0)
|
||||
return (error);
|
||||
|
||||
_lto3b(2048, data.blk_desc.blklen);
|
||||
data.header.data_length = 0;
|
||||
|
||||
return (scsipi_mode_select(cd->sc_periph, SMS_PF, &data.header,
|
||||
sizeof(data), XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cdvar.h,v 1.18 2003/07/10 18:18:41 martin Exp $ */
|
||||
/* $NetBSD: cdvar.h,v 1.19 2003/09/07 22:11:24 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
|
||||
@ -31,8 +31,6 @@
|
||||
|
||||
#define CDRETRIES 4
|
||||
|
||||
struct cd_ops;
|
||||
|
||||
struct cd_softc {
|
||||
struct device sc_dev;
|
||||
struct disk sc_dk;
|
||||
@ -54,25 +52,12 @@ struct cd_softc {
|
||||
|
||||
struct bufq_state buf_queue;
|
||||
char name[16]; /* product name, for default disklabel */
|
||||
const struct cd_ops *sc_ops; /* our bus-dependent ops vector */
|
||||
|
||||
#if NRND > 0
|
||||
rndsource_element_t rnd_source;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cd_ops {
|
||||
int (*cdo_setchan) __P((struct cd_softc *, int, int, int, int,
|
||||
int));
|
||||
int (*cdo_getvol) __P((struct cd_softc *, struct ioc_vol *, int));
|
||||
int (*cdo_setvol) __P((struct cd_softc *, const struct ioc_vol *,
|
||||
int));
|
||||
int (*cdo_set_pa_immed) __P((struct cd_softc *, int));
|
||||
int (*cdo_load_unload) __P((struct cd_softc *, int, int));
|
||||
int (*cdo_setblksize) __P((struct cd_softc *));
|
||||
};
|
||||
|
||||
void cdattach __P((struct device *, struct cd_softc *, struct scsipi_periph *,
|
||||
const struct cd_ops *));
|
||||
void cdattach __P((struct device *, struct cd_softc *, struct scsipi_periph *));
|
||||
int cdactivate __P((struct device *, enum devact));
|
||||
int cddetach __P((struct device *, int));
|
||||
|
@ -1,80 +0,0 @@
|
||||
/* $NetBSD: scsi_cd.h,v 1.16 2003/09/05 09:04:26 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Written by Julian Elischer (julian@tfs.com)
|
||||
* for TRW Financial Systems.
|
||||
*
|
||||
* TRW Financial Systems, in accordance with their agreement with Carnegie
|
||||
* Mellon University, makes this software available to CMU to distribute
|
||||
* or use in any manner that they see fit as long as this message is kept with
|
||||
* the software. For this reason TFS also grants any other persons or
|
||||
* organisations permission to use or modify this software.
|
||||
*
|
||||
* TFS supplies this software to be publicly redistributed
|
||||
* on the understanding that TFS is not responsible for the correct
|
||||
* functioning of this software in any circumstances.
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*/
|
||||
|
||||
/*
|
||||
* SCSI specific command format
|
||||
*/
|
||||
|
||||
#define PLAY_TRACK 0x48 /* cdrom play track/index mode */
|
||||
struct scsi_play_track {
|
||||
u_int8_t opcode;
|
||||
u_int8_t byte2;
|
||||
u_int8_t unused[2];
|
||||
u_int8_t start_track;
|
||||
u_int8_t start_index;
|
||||
u_int8_t unused1;
|
||||
u_int8_t end_track;
|
||||
u_int8_t end_index;
|
||||
u_int8_t control;
|
||||
};
|
||||
|
||||
#define SCSI_CD_WRITE_PARAMS_PAGE 0x05
|
||||
#define SCSI_CD_WRITE_PARAMS_PAGE_LEN 0x32
|
||||
struct scsi_cd_write_params_page {
|
||||
u_int8_t page_code;
|
||||
u_int8_t page_len;
|
||||
u_int8_t write_type;
|
||||
#define WRITE_TYPE_DUMMY 0x10 /* do not actually write blocks */
|
||||
#define WRITE_TYPE_MASK 0x0f /* session write type */
|
||||
u_int8_t track_mode;
|
||||
#define TRACK_MODE_MULTI_SESS 0xc0 /* multisession write type */
|
||||
#define TRACK_MODE_FP 0x20 /* fixed packet (if in packet mode) */
|
||||
#define TRACK_MODE_COPY 0x10 /* 1st higher gen of copy prot track */
|
||||
#define TRACK_MODE_PREEPMPASIS 0x01 /* audio w/ preemphasis (audio) */
|
||||
#define TRACK_MODE_INCREMENTAL 0x01 /* incremental data track (data) */
|
||||
#define TRACK_MODE_ALLOW_COPY 0x02 /* digital copy is permitted */
|
||||
#define TRACK_MODE_DATA 0x04 /* this is a data track */
|
||||
#define TRACK_MODE_4CHAN 0x08 /* four channel audio */
|
||||
u_int8_t dbtype;
|
||||
#define DBTYPE_MASK 0x0f /* data block type */
|
||||
u_int8_t reserved1[2];
|
||||
u_int8_t host_appl_code;
|
||||
#define HOST_APPL_CODE_MASK 0x3f /* host application code of disk */
|
||||
u_int8_t session_format;
|
||||
u_int8_t reserved2;
|
||||
u_int8_t packet_size[4];
|
||||
u_int8_t audio_pause_len[2];
|
||||
u_int8_t media_cat_number[16];
|
||||
u_int8_t isrc[14];
|
||||
u_int8_t sub_header[4];
|
||||
u_int8_t vendir_unique[4];
|
||||
};
|
||||
|
||||
union scsi_cd_pages {
|
||||
struct scsi_cd_write_params_page write_params;
|
||||
struct cd_audio_page audio;
|
||||
};
|
||||
|
||||
struct scsi_cd_mode_data {
|
||||
struct scsipi_mode_header header;
|
||||
union scsi_cd_pages page;
|
||||
};
|
||||
|
||||
#define AUDIOPAGESIZE \
|
||||
(sizeof(struct scsipi_mode_header) + sizeof(struct cd_audio_page))
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: scsipi_cd.h,v 1.6 2001/09/02 19:35:21 thorpej Exp $ */
|
||||
/* $NetBSD: scsipi_cd.h,v 1.7 2003/09/07 22:11:24 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Written by Julian Elischer (julian@tfs.com)
|
||||
@ -27,6 +27,16 @@
|
||||
* SCSI and SCSI-like command format
|
||||
*/
|
||||
|
||||
#define LOAD_UNLOAD 0xa6
|
||||
struct scsipi_load_unload {
|
||||
u_int8_t opcode;
|
||||
u_int8_t unused1[3];
|
||||
u_int8_t options;
|
||||
u_int8_t unused2[3];
|
||||
u_int8_t slot;
|
||||
u_int8_t unused3[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define PAUSE 0x4b /* cdrom pause in 'play audio' mode */
|
||||
struct scsipi_pause {
|
||||
u_int8_t opcode;
|
||||
@ -34,7 +44,7 @@ struct scsipi_pause {
|
||||
u_int8_t unused[6];
|
||||
u_int8_t resume;
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
#define PA_PAUSE 0x00
|
||||
#define PA_RESUME 0x01
|
||||
|
||||
@ -50,7 +60,7 @@ struct scsipi_play_msf {
|
||||
u_int8_t end_s;
|
||||
u_int8_t end_f;
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
#define PLAY 0x45 /* cdrom play 'play audio' mode */
|
||||
struct scsipi_play {
|
||||
@ -60,7 +70,7 @@ struct scsipi_play {
|
||||
u_int8_t unused;
|
||||
u_int8_t xfer_len[2];
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
#define READ_HEADER 0x44 /* cdrom read header */
|
||||
struct scsipi_read_header {
|
||||
@ -70,7 +80,7 @@ struct scsipi_read_header {
|
||||
u_int8_t unused;
|
||||
u_int8_t data_len[2];
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
#define READ_SUBCHANNEL 0x42 /* cdrom read Subchannel */
|
||||
struct scsipi_read_subchannel {
|
||||
@ -83,7 +93,7 @@ struct scsipi_read_subchannel {
|
||||
u_int8_t track;
|
||||
u_int8_t data_len[2];
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
#define READ_TOC 0x43 /* cdrom read TOC */
|
||||
struct scsipi_read_toc {
|
||||
@ -93,8 +103,7 @@ struct scsipi_read_toc {
|
||||
u_int8_t from_track;
|
||||
u_int8_t data_len[2];
|
||||
u_int8_t control;
|
||||
};
|
||||
;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define READ_CD_CAPACITY 0x25 /* slightly different from disk */
|
||||
struct scsipi_read_cd_capacity {
|
||||
@ -103,18 +112,18 @@ struct scsipi_read_cd_capacity {
|
||||
u_int8_t addr[4];
|
||||
u_int8_t unused[3];
|
||||
u_int8_t control;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
struct scsipi_read_cd_cap_data {
|
||||
u_int8_t addr[4];
|
||||
u_int8_t length[4];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
/* mod pages common to scsi and atapi */
|
||||
struct cd_audio_page {
|
||||
u_int8_t page_code;
|
||||
u_int8_t pg_code;
|
||||
#define AUDIO_PAGE 0x0e
|
||||
u_int8_t param_len;
|
||||
u_int8_t pg_length;
|
||||
u_int8_t flags;
|
||||
#define CD_PA_SOTC 0x02
|
||||
#define CD_PA_IMMED 0x04
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sd.c,v 1.202 2003/06/29 22:30:42 fvdl Exp $ */
|
||||
/* $NetBSD: sd.c,v 1.203 2003/09/07 22:11:24 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -54,7 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.202 2003/06/29 22:30:42 fvdl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.203 2003/09/07 22:11:24 mycroft Exp $");
|
||||
|
||||
#include "opt_scsi.h"
|
||||
#include "opt_bufq.h"
|
||||
@ -768,8 +768,7 @@ sdstart(periph)
|
||||
*/
|
||||
if (((bp->b_rawblkno & 0x1fffff) == bp->b_rawblkno) &&
|
||||
((nblks & 0xff) == nblks) &&
|
||||
!(periph->periph_quirks & PQUIRK_ONLYBIG) &&
|
||||
scsipi_periph_bustype(periph) == SCSIPI_BUSTYPE_SCSI) {
|
||||
!(periph->periph_quirks & PQUIRK_ONLYBIG)) {
|
||||
/*
|
||||
* We can fit in a small cdb.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sd_scsi.c,v 1.30 2003/09/05 08:12:09 mycroft Exp $ */
|
||||
/* $NetBSD: sd_scsi.c,v 1.31 2003/09/07 22:11:24 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
|
||||
@ -54,7 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sd_scsi.c,v 1.30 2003/09/05 08:12:09 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sd_scsi.c,v 1.31 2003/09/07 22:11:24 mycroft Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -623,21 +623,19 @@ sd_scsibus_setcache(sd, bits)
|
||||
|
||||
if (big) {
|
||||
_lto2b(0, scsipi_sense.header.big.data_length);
|
||||
error = scsipi_mode_select_big(sd->sc_periph, byte2|SMS_PF,
|
||||
return (scsipi_mode_select_big(sd->sc_periph, byte2|SMS_PF,
|
||||
(void *)&scsipi_sense, sizeof(scsipi_sense.header.big) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
pages->caching_params.pg_length,
|
||||
/* XS_CTL_SILENT | */ XS_CTL_DATA_ONSTACK,
|
||||
SDRETRIES, 10000);
|
||||
SDRETRIES, 10000));
|
||||
} else {
|
||||
scsipi_sense.header.small.data_length = 0;
|
||||
error = scsipi_mode_select(sd->sc_periph, byte2|SMS_PF,
|
||||
return (scsipi_mode_select(sd->sc_periph, byte2|SMS_PF,
|
||||
(void *)&scsipi_sense, sizeof(scsipi_sense.header.small) +
|
||||
sizeof(struct scsipi_mode_page_header) +
|
||||
pages->caching_params.pg_length,
|
||||
/* XS_CTL_SILENT | */ XS_CTL_DATA_ONSTACK,
|
||||
SDRETRIES, 10000);
|
||||
SDRETRIES, 10000));
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user