summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2005-05-27 16:07:52 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2005-05-27 16:07:52 +0000
commitee8be2b25bcabffe3484761b00235942d56a45dc (patch)
tree5451883d4cfc0ce54bfe8fde409f0ed78c531e1a
parentc8ee3703553b31aac2e402b374242f4d18d28832 (diff)
Convert cd code to new mode sense framework. Merge cd_scsi and
cd_atapi into cd since code is now almost identical, and only affects volume adjusting ioctl's. Minor side effect of allowing cd_load_unload() attempts to scsi cd's as NetBSD does.
-rw-r--r--sys/scsi/cd.c210
-rw-r--r--sys/scsi/cd.h26
-rw-r--r--sys/scsi/cdvar.h13
-rw-r--r--sys/scsi/files.scsi4
4 files changed, 199 insertions, 54 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index bf9c8925571..c0adb320f62 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd.c,v 1.79 2005/05/01 19:29:17 krw Exp $ */
+/* $OpenBSD: cd.c,v 1.80 2005/05/27 16:07:51 krw Exp $ */
/* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
/*
@@ -70,7 +70,6 @@
#include <scsi/scsi_all.h>
#include <scsi/cd.h>
-#include <scsi/scsi_cd.h>
#include <scsi/scsi_disk.h> /* rw_big and start_stop come from there */
#include <scsi/scsiconf.h>
@@ -124,6 +123,11 @@ void cddone(struct scsi_xfer *);
u_long cd_size(struct cd_softc *, int);
void lba2msf(u_long, u_char *, u_char *, u_char *);
u_long msf2lba(u_char, u_char, u_char);
+int cd_setchan(struct cd_softc *, int, int, int, int, int);
+int cd_getvol(struct cd_softc *cd, struct ioc_vol *, int);
+int cd_setvol(struct cd_softc *, const struct ioc_vol *, int);
+int cd_load_unload(struct cd_softc *, int, int);
+int cd_set_pa_immed(struct cd_softc *, int);
int cd_play(struct cd_softc *, int, int);
int cd_play_tracks(struct cd_softc *, int, int, int, int);
int cd_play_msf(struct cd_softc *, int, int, int, int, int, int);
@@ -175,9 +179,6 @@ const struct scsi_inquiry_pattern cd_patterns[] = {
#endif
};
-extern struct cd_ops cd_atapibus_ops;
-extern struct cd_ops cd_scsibus_ops;
-
#define cdlock(softc) disk_lock(&(softc)->sc_dk)
#define cdunlock(softc) disk_unlock(&(softc)->sc_dk)
#define cdlookup(unit) (struct cd_softc *)device_lookup(&cd_cd, (unit))
@@ -236,12 +237,6 @@ cdattach(parent, self, aux)
(sa->sa_inqbuf->version & SID_ANSII) == 0)
cd->flags |= CDF_ANCIENT;
- if (sc_link->flags & SDEV_ATAPI) {
- cd->sc_ops = &cd_atapibus_ops;
- } else {
- cd->sc_ops = &cd_scsibus_ops;
- }
-
printf("\n");
}
@@ -896,7 +891,7 @@ cdioctl(dev, cmd, addr, flag, p)
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)
break;
error = cd_play_tracks(cd, args->start_track,
args->start_index, args->end_track, args->end_index);
@@ -905,7 +900,7 @@ cdioctl(dev, cmd, addr, flag, p)
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)
break;
error = cd_play_msf(cd, args->start_m, args->start_s,
args->start_f, args->end_m, args->end_s, args->end_f);
@@ -914,7 +909,7 @@ cdioctl(dev, cmd, addr, flag, p)
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)
break;
error = cd_play(cd, args->blk, args->len);
break;
@@ -1045,46 +1040,46 @@ cdioctl(dev, cmd, addr, flag, p)
case CDIOCSETPATCH: {
struct ioc_patch *arg = (struct ioc_patch *)addr;
- error = (*cd->sc_ops->cdo_setchan)(cd, arg->patch[0],
- arg->patch[1], arg->patch[2], arg->patch[3], 0);
+ error = cd_setchan(cd, arg->patch[0], arg->patch[1],
+ arg->patch[2], arg->patch[3], 0);
break;
}
case CDIOCGETVOL: {
struct ioc_vol *arg = (struct ioc_vol *)addr;
- error = (*cd->sc_ops->cdo_getvol)(cd, arg, 0);
+ error = cd_getvol(cd, arg, 0);
break;
}
case CDIOCSETVOL: {
struct ioc_vol *arg = (struct ioc_vol *)addr;
- error = (*cd->sc_ops->cdo_setvol)(cd, arg, 0);
+ error = cd_setvol(cd, arg, 0);
break;
}
case CDIOCSETMONO:
- error = (*cd->sc_ops->cdo_setchan)(cd, BOTH_CHANNEL,
- BOTH_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0);
+ error = cd_setchan(cd, BOTH_CHANNEL, BOTH_CHANNEL, MUTE_CHANNEL,
+ MUTE_CHANNEL, 0);
break;
case CDIOCSETSTEREO:
- error = (*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
- RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0);
+ error = cd_setchan(cd, LEFT_CHANNEL, RIGHT_CHANNEL,
+ MUTE_CHANNEL, MUTE_CHANNEL, 0);
break;
case CDIOCSETMUTE:
- error = (*cd->sc_ops->cdo_setchan)(cd, MUTE_CHANNEL,
- MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0);
+ error = cd_setchan(cd, MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL,
+ MUTE_CHANNEL, 0);
break;
case CDIOCSETLEFT:
- error = (*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
- LEFT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0);
+ error = cd_setchan(cd, LEFT_CHANNEL, LEFT_CHANNEL, MUTE_CHANNEL,
+ MUTE_CHANNEL, 0);
break;
case CDIOCSETRIGHT:
- error = (*cd->sc_ops->cdo_setchan)(cd, RIGHT_CHANNEL,
- RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0);
+ error = cd_setchan(cd, RIGHT_CHANNEL, RIGHT_CHANNEL,
+ MUTE_CHANNEL, MUTE_CHANNEL, 0);
break;
case CDIOCRESUME:
@@ -1143,8 +1138,7 @@ cdioctl(dev, cmd, addr, flag, p)
case CDIOCLOADUNLOAD: {
struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
- error = (*cd->sc_ops->cdo_load_unload)(cd, args->options,
- args->slot);
+ error = cd_load_unload(cd, args->options, args->slot);
break;
}
@@ -1367,6 +1361,162 @@ cd_size(cd, flags)
return (cd->params.disksize);
}
+int
+cd_setchan(cd, p0, p1, p2, p3, flags)
+ struct cd_softc *cd;
+ int p0, p1, p2, p3, flags;
+{
+ struct scsi_mode_sense_buf data;
+ struct cd_audio_page *audio = NULL;
+ int error;
+
+ error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data,
+ (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags);
+ if (error != 0)
+ return (error);
+ if (audio == NULL)
+ return (EIO);
+
+ audio->port[LEFT_PORT].channels = p0;
+ audio->port[RIGHT_PORT].channels = p1;
+ audio->port[2].channels = p2;
+ audio->port[3].channels = p3;
+
+ if (MODE_HEADER_IS_BIG(&data, audio))
+ error = scsi_mode_select_big(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header_big *)&data, sizeof(data), flags,
+ 20000);
+ else
+ error = scsi_mode_select(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header *)&data, sizeof(data), flags,
+ 20000);
+
+ return (error);
+}
+
+int
+cd_getvol(cd, arg, flags)
+ struct cd_softc *cd;
+ struct ioc_vol *arg;
+ int flags;
+{
+ struct scsi_mode_sense_buf data;
+ struct cd_audio_page *audio = NULL;
+ int error;
+
+ error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data,
+ (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags);
+ if (error != 0)
+ return (error);
+ if (audio == NULL)
+ return (EIO);
+
+ arg->vol[0] = audio->port[0].volume;
+ arg->vol[1] = audio->port[1].volume;
+ arg->vol[2] = audio->port[2].volume;
+ arg->vol[3] = audio->port[3].volume;
+
+ return (0);
+}
+
+int
+cd_setvol(cd, arg, flags)
+ struct cd_softc *cd;
+ const struct ioc_vol *arg;
+ int flags;
+{
+ struct scsi_mode_sense_buf data;
+ struct cd_audio_page *audio = NULL;
+ u_int8_t mask_volume[4];
+ int error;
+
+ error = scsi_do_mode_sense(cd->sc_link,
+ AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, &data, (void **)&audio, NULL,
+ NULL, NULL, sizeof(*audio), flags);
+ if (error != 0)
+ return (error);
+ if (audio == NULL)
+ return (EIO);
+
+ 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);
+ if (error != 0)
+ return (error);
+ if (audio == NULL)
+ return (EIO);
+
+ 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 (MODE_HEADER_IS_BIG(&data, audio))
+ error = scsi_mode_select_big(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header_big *)&data, sizeof(data), flags,
+ 20000);
+ else
+ error = scsi_mode_select(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header *)&data, sizeof(data), flags,
+ 20000);
+
+ return (error);
+}
+
+int
+cd_load_unload(cd, options, slot)
+ struct cd_softc *cd;
+ int options, slot;
+{
+ struct scsi_load_unload cmd;
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = LOAD_UNLOAD;
+ cmd.options = options; /* ioctl uses ATAPI values */
+ cmd.slot = slot;
+
+ return (scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&cmd,
+ sizeof(cmd), 0, 0, CDRETRIES, 200000, NULL, 0));
+}
+
+int
+cd_set_pa_immed(cd, flags)
+ struct cd_softc *cd;
+ int flags;
+{
+ struct scsi_mode_sense_buf data;
+ struct cd_audio_page *audio = NULL;
+ int error;
+
+ if (cd->sc_link->flags & SDEV_ATAPI)
+ /* XXX Noop? */
+ return (0);
+
+ error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data,
+ (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags);
+ if (error != 0)
+ return (error);
+ if (audio == NULL)
+ return (EIO);
+
+ audio->flags &= ~CD_PA_SOTC;
+ audio->flags |= CD_PA_IMMED;
+
+ if (MODE_HEADER_IS_BIG(&data, audio))
+ error = scsi_mode_select_big(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header_big *)&data, sizeof(data), flags,
+ 20000);
+ else
+ error = scsi_mode_select(cd->sc_link, SMS_PF,
+ (struct scsi_mode_header *)&data, sizeof(data), flags,
+ 20000);
+
+ return (error);
+}
/*
* Get scsi driver to send a "start playing" command
diff --git a/sys/scsi/cd.h b/sys/scsi/cd.h
index 17df8c5881d..4b90bd1b44c 100644
--- a/sys/scsi/cd.h
+++ b/sys/scsi/cd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd.h,v 1.2 2005/04/16 16:54:34 krw Exp $ */
+/* $OpenBSD: cd.h,v 1.3 2005/05/27 16:07:51 krw Exp $ */
/* $NetBSD: scsi_cd.h,v 1.6 1996/03/19 03:06:39 mycroft Exp $ */
/*
@@ -131,6 +131,20 @@ struct scsi_read_cd_capacity {
u_int8_t control;
};
+struct scsi_load_unload {
+ u_int8_t opcode;
+ u_int8_t reserved;
+#define IMMED 0x1
+ u_int8_t reserved2[2];
+ u_int8_t options;
+#define START 0x1
+#define LOUNLO 0x2
+ u_int8_t reserved4[3];
+ u_int8_t slot;
+ u_int8_t reserved5[2];
+ u_int8_t control;
+};
+
/*
* Opcodes
*/
@@ -145,6 +159,7 @@ struct scsi_read_cd_capacity {
#define PLAY_TRACK_REL 0x49 /* cdrom play track/index mode */
#define PAUSE 0x4b /* cdrom pause in 'play audio' mode */
#define PLAY_BIG 0xa5 /* cdrom pause in 'play audio' mode */
+#define LOAD_UNLOAD 0xa6 /* cdrom load/unload media */
#define PLAY_TRACK_REL_BIG 0xa9 /* cdrom play track/index mode */
@@ -184,7 +199,6 @@ struct cd_audio_page {
#define RIGHT_PORT 1
};
-#ifdef CDDA
/*
* There are 2352 bytes in a CD digital audio frame. One frame is 1/75 of a
* second, at 44.1kHz sample rate, 16 bits/sample, 2 channels.
@@ -193,13 +207,7 @@ struct cd_audio_page {
* channel first. Samples are little endian 16-bit signed values.
*/
#define CD_DA_BLKSIZ 2352 /* # bytes in CD-DA frame */
-#ifndef CD_NORMAL_DENSITY_CODE
#define CD_NORMAL_DENSITY_CODE 0x00 /* from Toshiba CD-ROM specs */
-#endif
-#ifndef CD_DA_DENSITY_CODE
#define CD_DA_DENSITY_CODE 0x82 /* from Toshiba CD-ROM specs */
-#endif
-#endif /* CDDA */
-
-#endif /*_SCSI_CD_H*/
+#endif
diff --git a/sys/scsi/cdvar.h b/sys/scsi/cdvar.h
index b69f27e48c4..c43d4fefc04 100644
--- a/sys/scsi/cdvar.h
+++ b/sys/scsi/cdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cdvar.h,v 1.3 2002/03/14 01:27:13 millert Exp $ */
+/* $OpenBSD: cdvar.h,v 1.4 2005/05/27 16:07:51 krw Exp $ */
/* $NetBSD: cdvar.h,v 1.10 1999/02/02 13:02:49 bouyer Exp $ */
/*
@@ -63,14 +63,3 @@ struct cd_softc {
rndsource_element_t rnd_source;
#endif
};
-
-struct cd_ops {
- int (*cdo_setchan)(struct cd_softc *, int, int, int, int,
- int);
- int (*cdo_getvol)(struct cd_softc *, struct ioc_vol *, int);
- int (*cdo_setvol)(struct cd_softc *, const struct ioc_vol *,
- int);
- int (*cdo_set_pa_immed)(struct cd_softc *, int);
- int (*cdo_load_unload)(struct cd_softc *, int, int);
-};
-
diff --git a/sys/scsi/files.scsi b/sys/scsi/files.scsi
index bc4073a77d5..7ef33423207 100644
--- a/sys/scsi/files.scsi
+++ b/sys/scsi/files.scsi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.scsi,v 1.14 2005/05/14 00:20:43 krw Exp $
+# $OpenBSD: files.scsi,v 1.15 2005/05/27 16:07:51 krw Exp $
# $NetBSD: files.scsi,v 1.4 1996/05/16 04:01:08 mycroft Exp $
#
# Config.new file and device description for machine-independent SCSI code.
@@ -15,8 +15,6 @@ attach scsibus at scsi
device cd: disk
attach cd at scsibus
file scsi/cd.c cd needs-flag
-file scsi/cd_scsi.c cd
-file scsi/cd_atapi.c cd
device ch: disk
attach ch at scsibus