PERFORCE change 25529 for review
Robert Watson
rwatson at freebsd.org
Fri Feb 21 16:44:35 GMT 2003
http://perforce.freebsd.org/chv.cgi?CH=25529
Change 25529 by rwatson at rwatson_tislabs on 2003/02/21 08:43:59
Integ recent changes from FreeBSD vendor branch.
Affected files ...
.. //depot/projects/trustedbsd/base/Makefile.inc1#33 integrate
.. //depot/projects/trustedbsd/base/etc/rc.d/virecover#4 integrate
.. //depot/projects/trustedbsd/base/gnu/usr.bin/Makefile#6 integrate
.. //depot/projects/trustedbsd/base/lib/Makefile#13 integrate
.. //depot/projects/trustedbsd/base/lib/libc/gen/dlopen.3#8 integrate
.. //depot/projects/trustedbsd/base/sbin/Makefile#11 integrate
.. //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_all.c#10 integrate
.. //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_all.h#5 integrate
.. //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_cd.c#13 integrate
.. //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_cd.h#4 integrate
.. //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_da.c#25 integrate
.. //depot/projects/trustedbsd/base/sys/conf/kern.post.mk#21 integrate
.. //depot/projects/trustedbsd/base/sys/conf/kern.pre.mk#15 integrate
.. //depot/projects/trustedbsd/base/sys/dev/aac/aac_disk.c#10 integrate
.. //depot/projects/trustedbsd/base/sys/dev/amr/amr_disk.c#6 integrate
.. //depot/projects/trustedbsd/base/sys/dev/ata/ata-disk.c#16 integrate
.. //depot/projects/trustedbsd/base/sys/dev/ata/ata-raid.c#13 integrate
.. //depot/projects/trustedbsd/base/sys/dev/ata/atapi-cam.c#8 integrate
.. //depot/projects/trustedbsd/base/sys/dev/ata/atapi-fd.c#13 integrate
.. //depot/projects/trustedbsd/base/sys/dev/ccd/ccd.c#13 integrate
.. //depot/projects/trustedbsd/base/sys/dev/firewire/firewirereg.h#5 integrate
.. //depot/projects/trustedbsd/base/sys/dev/firewire/iec68113.h#3 integrate
.. //depot/projects/trustedbsd/base/sys/dev/firewire/sbp.c#9 integrate
.. //depot/projects/trustedbsd/base/sys/dev/mlx/mlx_disk.c#3 integrate
.. //depot/projects/trustedbsd/base/sys/dev/raidframe/rf_freebsdkintf.c#6 integrate
.. //depot/projects/trustedbsd/base/sys/dev/twe/twe_freebsd.c#9 integrate
.. //depot/projects/trustedbsd/base/sys/dev/usb/umass.c#20 integrate
.. //depot/projects/trustedbsd/base/sys/geom/geom_disk.c#20 integrate
.. //depot/projects/trustedbsd/base/sys/kern/kern_thread.c#21 integrate
.. //depot/projects/trustedbsd/base/sys/netinet/in_pcb.c#17 integrate
.. //depot/projects/trustedbsd/base/sys/sys/disk.h#7 integrate
.. //depot/projects/trustedbsd/base/sys/sys/mchain.h#6 integrate
.. //depot/projects/trustedbsd/base/tools/tools/tinderbox/tbmaster.pl#2 integrate
.. //depot/projects/trustedbsd/base/usr.bin/Makefile#23 integrate
.. //depot/projects/trustedbsd/base/usr.bin/wall/wall.c#3 integrate
.. //depot/projects/trustedbsd/base/usr.sbin/Makefile#20 integrate
Differences ...
==== //depot/projects/trustedbsd/base/Makefile.inc1#33 (text+ko) ====
@@ -1,5 +1,5 @@
#
-# $FreeBSD: src/Makefile.inc1,v 1.317 2003/02/11 19:21:13 trhodes Exp $
+# $FreeBSD: src/Makefile.inc1,v 1.318 2003/02/21 11:19:25 ru Exp $
#
# Make command line options:
# -DMAKE_KERBEROS4 to build KerberosIV
@@ -495,22 +495,21 @@
.if !defined(NOCLEAN) && !defined(NO_KERNELCLEAN)
cd ${KRNLOBJDIR}/${_kernel}; \
${KMAKEENV} ${MAKE} KERNEL=${INSTKERNNAME} -DNO_MODULES clean
-.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists(${KRNLSRCDIR}/modules)
cd ${KRNLOBJDIR}/${_kernel}; \
${KMAKEENV} ${MAKE} KERNEL=${INSTKERNNAME} cleandir
.endif
-.endif
cd ${KRNLOBJDIR}/${_kernel}; \
MAKESRCPATH=${KRNLSRCDIR}/dev/aic7xxx/aicasm \
${MAKE} -DNO_CPU_CFLAGS -f ${KRNLSRCDIR}/dev/aic7xxx/aicasm/Makefile
+ cd ${KRNLOBJDIR}/${_kernel}; \
+ ${KMAKEENV} ${MAKE} KERNEL=${INSTKERNNAME} obj
+# XXX - Gratuitously builds aicasm in the ``makeoptions NO_MODULES'' case.
.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists(${KRNLSRCDIR}/modules)
- cd ${KRNLOBJDIR}/${_kernel}; \
- ${KMAKEENV} ${MAKE} KERNEL=${INSTKERNNAME} modules-obj
+.for target in obj depend all
cd ${.CURDIR}/sys/modules/aic7xxx/aicasm; \
MAKEOBJDIRPREFIX=${KRNLOBJDIR}/${_kernel}/modules \
- ${MAKE} -DNO_CPU_CFLAGS depend; \
- MAKEOBJDIRPREFIX=${KRNLOBJDIR}/${_kernel}/modules \
- ${MAKE} -DNO_CPU_CFLAGS all
+ ${MAKE} -DNO_CPU_CFLAGS ${target}
+.endfor
.endif
.if !defined(NO_KERNELDEPEND)
cd ${KRNLOBJDIR}/${_kernel}; \
==== //depot/projects/trustedbsd/base/etc/rc.d/virecover#4 (text+ko) ====
@@ -1,7 +1,7 @@
#!/bin/sh
#
# $NetBSD: virecover,v 1.6 2002/03/22 04:34:00 thorpej Exp $
-# $FreeBSD: src/etc/rc.d/virecover,v 1.3 2002/09/06 16:18:05 gordon Exp $
+# $FreeBSD: src/etc/rc.d/virecover,v 1.4 2003/02/21 09:37:20 dougb Exp $
#
# PROVIDE: virecover
@@ -27,6 +27,7 @@
virecover_start()
{
+ [ -d /var/tmp/vi.recover ] || return
find /var/tmp/vi.recover ! -type f -a ! -type d -delete
vibackup=`echo /var/tmp/vi.recover/vi.*`
if [ "${vibackup}" != '/var/tmp/vi.recover/vi.*' ]; then
==== //depot/projects/trustedbsd/base/gnu/usr.bin/Makefile#6 (text+ko) ====
@@ -1,7 +1,11 @@
-# $FreeBSD: src/gnu/usr.bin/Makefile,v 1.72 2002/09/17 01:43:21 obrien Exp $
+# $FreeBSD: src/gnu/usr.bin/Makefile,v 1.73 2003/02/21 02:30:50 obrien Exp $
+
+.if ${MACHINE_ARCH} != "powerpc"
+_gperf=gperf
+.endif
SUBDIR= bc binutils cc cpio dc dialog diff diff3 \
- gperf grep groff gzip man patch rcs sdiff send-pr sort tar texinfo
+ ${_gperf} grep groff gzip man patch rcs sdiff send-pr sort tar texinfo
.if !defined(NO_CVS)
SUBDIR+=cvs
==== //depot/projects/trustedbsd/base/lib/Makefile#13 (text+ko) ====
@@ -1,5 +1,5 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/Makefile,v 1.148 2003/02/08 15:17:49 phk Exp $
+# $FreeBSD: src/lib/Makefile,v 1.149 2003/02/21 02:30:51 obrien Exp $
# To satisfy shared library or ELF linkage when only the libraries being
# built are visible:
@@ -24,7 +24,7 @@
SUBDIR= ${_csu} libcom_err libcrypt libkvm msun libmd \
libncurses libradius librpcsvc libsbuf libtacplus libutil libypclnt \
${_compat} libalias libatm ${_libbind} libbz2 libc ${_libc_r} \
- libcalendar libcam libcompat libdevinfo libdevstat libdisk \
+ libcalendar libcam libcompat libdevinfo libdevstat ${_libdisk} \
libedit libexpat libfetch libform libftpio libgeom ${_libio} libipsec \
libipx libisc libmenu ${_libmilter} ${_libmp} ${_libncp} \
libnetgraph libopie libpam libpanel libpcap \
@@ -67,6 +67,10 @@
_compat= compat
.endif
+.if ${MACHINE_ARCH} != "powerpc"
+_libdisk=libdisk
+.endif
+
.if defined(RELEASEDIR) || \
(!exists(${.CURDIR}/../secure) && !exists(${.CURDIR}/../kerberosIV)) || \
defined(NOCRYPT) || (defined(NOSECURE) && !defined(MAKE_KERBEROS4))
==== //depot/projects/trustedbsd/base/lib/libc/gen/dlopen.3#8 (text+ko) ====
@@ -30,7 +30,7 @@
.\" Copyright (c) 1991 Sun Microsystems, Inc.
.\"
.\" @(#) dlopen.3 1.6 90/01/31 SMI
-.\" $FreeBSD: src/lib/libc/gen/dlopen.3,v 1.26 2003/02/14 10:57:20 phantom Exp $
+.\" $FreeBSD: src/lib/libc/gen/dlopen.3,v 1.27 2003/02/21 13:43:41 phantom Exp $
.\"
.Dd September 10, 2002
.Os
@@ -278,6 +278,8 @@
returns a null-terminated character string describing the last error that
occurred during a call to
.Fn dlopen ,
+.Fn dladdr ,
+.Fn dlinfo ,
.Fn dlsym ,
.Fn dlfunc ,
or
==== //depot/projects/trustedbsd/base/sbin/Makefile#11 (text+ko) ====
@@ -1,5 +1,5 @@
# @(#)Makefile 8.5 (Berkeley) 3/31/94
-# $FreeBSD: src/sbin/Makefile,v 1.117 2003/01/31 07:40:25 jake Exp $
+# $FreeBSD: src/sbin/Makefile,v 1.118 2003/02/21 02:16:35 obrien Exp $
# XXX MISSING: icheck ncheck
@@ -12,7 +12,6 @@
clri \
comcontrol \
conscontrol \
- devd \
devfs \
dhclient \
dmesg \
@@ -78,6 +77,10 @@
umount \
vinum
+.if !defined(NO_CXX)
+SUBDIR+=devd
+.endif
+
.if !defined(NO_IPFILTER)
SUBDIR+=ipf \
ipfs \
==== //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_all.c#10 (text+ko) ====
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.39 2003/02/21 06:19:37 ken Exp $
*/
#include <sys/param.h>
@@ -1950,6 +1950,7 @@
#else /* !_KERNEL */
scsi_command_string(device, csio, sb);
#endif /* _KERNEL/!_KERNEL */
+ sbuf_printf(sb, "\n");
}
/*
@@ -2068,9 +2069,9 @@
/* Bit pointer is valid */
if (sense->sense_key_spec[0] & 0x08)
snprintf(tmpstr2, sizeof(tmpstr2),
- "bit %d",
+ "bit %d ",
sense->sense_key_spec[0] & 0x7);
- sbuf_printf(sb, ": %s byte %d %s is invalid",
+ sbuf_printf(sb, ": %s byte %d %sis invalid",
bad_command ? "Command" : "Data",
scsi_2btoul(
&sense->sense_key_spec[1]),
@@ -2447,12 +2448,24 @@
u_int8_t page, u_int8_t *param_buf, u_int32_t param_len,
u_int8_t sense_len, u_int32_t timeout)
{
+ return(scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd,
+ page_code, page, param_buf, param_len, 0,
+ sense_len, timeout));
+}
+void
+scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, int dbd, u_int8_t page_code,
+ u_int8_t page, u_int8_t *param_buf, u_int32_t param_len,
+ int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout)
+{
u_int8_t cdb_len;
/*
* Use the smallest possible command to perform the operation.
*/
- if (param_len < 256) {
+ if ((param_len < 256)
+ && (minimum_cmd_size < 10)) {
/*
* We can fit in a 6 byte cdb.
*/
@@ -2500,12 +2513,26 @@
u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len,
u_int32_t timeout)
{
+ return(scsi_mode_select_len(csio, retries, cbfcnp, tag_action,
+ scsi_page_fmt, save_pages, param_buf,
+ param_len, 0, sense_len, timeout));
+}
+
+void
+scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, int scsi_page_fmt, int save_pages,
+ u_int8_t *param_buf, u_int32_t param_len,
+ int minimum_cmd_size, u_int8_t sense_len,
+ u_int32_t timeout)
+{
u_int8_t cdb_len;
/*
* Use the smallest possible command to perform the operation.
*/
- if (param_len < 256) {
+ if ((param_len < 256)
+ && (minimum_cmd_size < 10)) {
/*
* We can fit in a 6 byte cdb.
*/
==== //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_all.h#5 (text+ko) ====
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian at tfs.com) Sept 1992
*
- * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.21 2002/10/08 17:12:44 ken Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.22 2003/02/21 06:19:38 ken Exp $
*/
/*
@@ -926,6 +926,15 @@
u_int8_t *param_buf, u_int32_t param_len,
u_int8_t sense_len, u_int32_t timeout);
+void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *,
+ union ccb *),
+ u_int8_t tag_action, int dbd,
+ u_int8_t page_code, u_int8_t page,
+ u_int8_t *param_buf, u_int32_t param_len,
+ int minimum_cmd_size, u_int8_t sense_len,
+ u_int32_t timeout);
+
void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
union ccb *),
@@ -934,6 +943,14 @@
u_int32_t param_len, u_int8_t sense_len,
u_int32_t timeout);
+void scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *,
+ union ccb *),
+ u_int8_t tag_action, int scsi_page_fmt,
+ int save_pages, u_int8_t *param_buf,
+ u_int32_t param_len, int minimum_cmd_size,
+ u_int8_t sense_len, u_int32_t timeout);
+
void scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, u_int8_t page_code,
==== //depot/projects/trustedbsd/base/sys/cam/scsi/scsi_cd.c#13 (text+ko) ====
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1997 Justin T. Gibbs.
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 Kenneth D. Merry.
+ * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Kenneth D. Merry.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.71 2003/02/19 05:46:57 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.72 2003/02/21 06:19:38 ken Exp $
*/
/*
* Portions of this driver taken from the original FreeBSD cd driver.
@@ -79,11 +79,12 @@
};
typedef enum {
- CD_Q_NONE = 0x00,
- CD_Q_NO_TOUCH = 0x01,
- CD_Q_BCD_TRACKS = 0x02,
- CD_Q_NO_CHANGER = 0x04,
- CD_Q_CHANGER = 0x08
+ CD_Q_NONE = 0x00,
+ CD_Q_NO_TOUCH = 0x01,
+ CD_Q_BCD_TRACKS = 0x02,
+ CD_Q_NO_CHANGER = 0x04,
+ CD_Q_CHANGER = 0x08,
+ CD_Q_10_BYTE_ONLY = 0x10
} cd_quirks;
typedef enum {
@@ -95,7 +96,9 @@
CD_FLAG_CHANGER = 0x040,
CD_FLAG_ACTIVE = 0x080,
CD_FLAG_SCHED_ON_COMP = 0x100,
- CD_FLAG_RETRY_UA = 0x200
+ CD_FLAG_RETRY_UA = 0x200,
+ CD_FLAG_VALID_MEDIA = 0x400,
+ CD_FLAG_VALID_TOC = 0x800
} cd_flags;
typedef enum {
@@ -116,6 +119,16 @@
#define ccb_state ppriv_field0
#define ccb_bp ppriv_ptr1
+struct cd_tocdata {
+ struct ioc_toc_header header;
+ struct cd_toc_entry entries[100];
+};
+
+struct cd_toc_single {
+ struct ioc_toc_header header;
+ struct cd_toc_entry entry;
+};
+
typedef enum {
CD_STATE_PROBE,
CD_STATE_NORMAL
@@ -137,20 +150,45 @@
struct cam_periph *periph;
dev_t dev;
eventhandler_tag clonetag;
+ int minimum_command_size;
+ struct sysctl_ctx_list sysctl_ctx;
+ struct sysctl_oid *sysctl_tree;
+ STAILQ_HEAD(, cd_mode_params) mode_queue;
+ struct cd_tocdata toc;
};
+struct cd_page_sizes {
+ int page;
+ int page_size;
+};
+
+static struct cd_page_sizes cd_page_size_table[] =
+{
+ { AUDIO_PAGE, sizeof(struct cd_audio_page)}
+};
+
struct cd_quirk_entry {
struct scsi_inquiry_pattern inq_pat;
cd_quirks quirks;
};
/*
- * These quirk entries aren't strictly necessary. Basically, what they do
- * is tell cdregister() up front that a device is a changer. Otherwise, it
- * will figure that fact out once it sees a LUN on the device that is
- * greater than 0. If it is known up front that a device is a changer, all
- * I/O to the device will go through the changer scheduling routines, as
+ * The changer quirk entries aren't strictly necessary. Basically, what
+ * they do is tell cdregister() up front that a device is a changer.
+ * Otherwise, it will figure that fact out once it sees a LUN on the device
+ * that is greater than 0. If it is known up front that a device is a changer,
+ * all I/O to the device will go through the changer scheduling routines, as
* opposed to the "normal" CD code.
+ *
+ * NOTE ON 10_BYTE_ONLY quirks: Any 10_BYTE_ONLY quirks MUST be because
+ * your device hangs when it gets a 10 byte command. Adding a quirk just
+ * to get rid of the informative diagnostic message is not acceptable. All
+ * 10_BYTE_ONLY quirks must be documented in full in a PR (which should be
+ * referenced in a comment along with the quirk) , and must be approved by
+ * ken at FreeBSD.org. Any quirks added that don't adhere to this policy may
+ * be removed until the submitter can explain why they are needed.
+ * 10_BYTE_ONLY quirks will be removed (as they will no longer be necessary)
+ * when the CAM_NEW_TRAN_CODE work is done.
*/
static struct cd_quirk_entry cd_quirk_table[] =
{
@@ -186,6 +224,7 @@
static periph_oninv_t cdoninvalidate;
static void cdasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
+static int cdcmdsizesysctl(SYSCTL_HANDLER_ARGS);
static void cdshorttimeout(void *arg);
static void cdschedule(struct cam_periph *periph, int priority);
static void cdrunchangerqueue(void *arg);
@@ -195,21 +234,25 @@
u_int32_t cam_flags,
u_int32_t sense_flags),
u_int32_t cam_flags, u_int32_t sense_flags);
-static union ccb *cdgetccb(struct cam_periph *periph,
+static union ccb *cdgetccb(struct cam_periph *periph,
u_int32_t priority);
static void cddone(struct cam_periph *periph,
union ccb *start_ccb);
+static union cd_pages *cdgetpage(struct cd_mode_params *mode_params);
+static int cdgetpagesize(int page_num);
+static void cdprevent(struct cam_periph *periph, int action);
+static int cdcheckmedia(struct cam_periph *periph);
+static int cdsize(struct cam_periph *periph, u_int32_t *size);
+static int cd6byteworkaround(union ccb *ccb);
static int cderror(union ccb *ccb, u_int32_t cam_flags,
u_int32_t sense_flags);
-static void cdprevent(struct cam_periph *periph, int action);
-static int cdsize(dev_t dev, u_int32_t *size);
static int cdreadtoc(struct cam_periph *periph, u_int32_t mode,
- u_int32_t start, struct cd_toc_entry *data,
- u_int32_t len);
+ u_int32_t start, u_int8_t *data,
+ u_int32_t len, u_int32_t sense_flags);
static int cdgetmode(struct cam_periph *periph,
- struct cd_mode_data *data, u_int32_t page);
+ struct cd_mode_params *data, u_int32_t page);
static int cdsetmode(struct cam_periph *periph,
- struct cd_mode_data *data);
+ struct cd_mode_params *data);
static int cdplay(struct cam_periph *periph, u_int32_t blk,
u_int32_t len);
static int cdreadsubchannel(struct cam_periph *periph,
@@ -226,7 +269,7 @@
u_int32_t etrack, u_int32_t eindex);
static int cdpause(struct cam_periph *periph, u_int32_t go);
static int cdstopunit(struct cam_periph *periph, u_int32_t eject);
-static int cdstartunit(struct cam_periph *periph);
+static int cdstartunit(struct cam_periph *periph, int load);
static int cdsetspeed(struct cam_periph *periph,
u_int32_t rdspeed, u_int32_t wrspeed);
static int cdreportkey(struct cam_periph *periph,
@@ -276,8 +319,10 @@
SYSCTL_NODE(_kern_cam_cd, OID_AUTO, changer, CTLFLAG_RD, 0, "CD Changer");
SYSCTL_INT(_kern_cam_cd_changer, OID_AUTO, min_busy_seconds, CTLFLAG_RW,
&changer_min_busy_seconds, 0, "Minimum changer scheduling quantum");
+TUNABLE_INT("kern.cam.cd.changer.min_busy_seconds", &changer_min_busy_seconds);
SYSCTL_INT(_kern_cam_cd_changer, OID_AUTO, max_busy_seconds, CTLFLAG_RW,
&changer_max_busy_seconds, 0, "Maximum changer scheduling quantum");
+TUNABLE_INT("kern.cam.cd.changer.max_busy_seconds", &changer_max_busy_seconds);
struct cdchanger {
path_id_t path_id;
@@ -554,12 +599,50 @@
}
}
+/*
+ * We have a handler function for this so we can check the values when the
+ * user sets them, instead of every time we look at them.
+ */
+static int
+cdcmdsizesysctl(SYSCTL_HANDLER_ARGS)
+{
+ int error, value;
+
+ value = *(int *)arg1;
+
+ error = sysctl_handle_int(oidp, &value, 0, req);
+
+ if ((error != 0)
+ || (req->newptr == NULL))
+ return (error);
+
+ /*
+ * The only real values we can have here are 6 or 10. I don't
+ * really forsee having 12 be an option at any time in the future.
+ * So if the user sets something less than or equal to 6, we'll set
+ * it to 6. If he sets something greater than 6, we'll set it to 10.
+ *
+ * I suppose we could just return an error here for the wrong values,
+ * but I don't think it's necessary to do so, as long as we can
+ * determine the user's intent without too much trouble.
+ */
+ if (value < 6)
+ value = 6;
+ else if (value > 6)
+ value = 10;
+
+ *(int *)arg1 = value;
+
+ return (0);
+}
+
static cam_status
cdregister(struct cam_periph *periph, void *arg)
{
struct cd_softc *softc;
struct ccb_setasync csa;
struct ccb_getdev *cgd;
+ char tmpstr[80], tmpstr2[80];
caddr_t match;
cgd = (struct ccb_getdev *)arg;
@@ -582,6 +665,7 @@
bzero(softc, sizeof(*softc));
LIST_INIT(&softc->pending_ccbs);
+ STAILQ_INIT(&softc->mode_queue);
softc->state = CD_STATE_PROBE;
bioq_init(&softc->bio_queue);
if (SID_IS_REMOVABLE(&cgd->inq_data))
@@ -605,7 +689,46 @@
else
softc->quirks = CD_Q_NONE;
+ snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number);
+ snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
+ softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
+ SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO,
+ tmpstr2, CTLFLAG_RD, 0, tmpstr);
+ if (softc->sysctl_tree == NULL) {
+ printf("cdregister: unable to allocate sysctl tree\n");
+ free(softc, M_DEVBUF);
+ return (CAM_REQ_CMP_ERR);
+ }
+
+ /* The default is 6 byte commands, unless quirked otherwise */
+ if (softc->quirks & CD_Q_10_BYTE_ONLY)
+ softc->minimum_command_size = 10;
+ else
+ softc->minimum_command_size = 6;
+
+ /*
+ * Load the user's default, if any.
+ */
+ snprintf(tmpstr, sizeof(tmpstr), "kern.cam.cd.%d.minimum_cmd_size",
+ periph->unit_number);
+ TUNABLE_INT_FETCH(tmpstr, &softc->minimum_command_size);
+
+ /* 6 and 10 are the only permissible values here. */
+ if (softc->minimum_command_size < 6)
+ softc->minimum_command_size = 6;
+ else if (softc->minimum_command_size > 6)
+ softc->minimum_command_size = 10;
+
/*
+ * Now register the sysctl handler, so the user can the value on
+ * the fly.
+ */
+ SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
+ OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
+ &softc->minimum_command_size, 0, cdcmdsizesysctl, "I",
+ "Minimum CDB size");
+
+ /*
* We need to register the statistics structure for this device,
* but we don't have the blocksize yet for it. So, we register
* the structure and indicate that we don't have the blocksize
@@ -873,7 +996,6 @@
{
struct cam_periph *periph;
struct cd_softc *softc;
- u_int32_t size;
int error;
int s;
@@ -902,26 +1024,12 @@
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
return(ENXIO);
- cdprevent(periph, PR_PREVENT);
-
- /* find out the size */
- if ((error = cdsize(dev, &size)) != 0) {
- cdprevent(periph, PR_ALLOW);
- cam_periph_unlock(periph);
- cam_periph_release(periph);
- return(error);
- }
-
/*
- * We unconditionally (re)set the blocksize each time the
- * CD device is opened. This is because the CD can change,
- * and therefore the blocksize might change.
- * XXX problems here if some slice or partition is still
- * open with the old size?
+ * Check for media, and set the appropriate flags. We don't bail
+ * if we don't have media, but then we don't allow anything but the
+ * CDIOCEJECT/CDIOCCLOSE ioctls if there is no media.
*/
- if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0)
- softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
- softc->device_stats.block_size = softc->params.blksize;
+ cdcheckmedia(periph);
cam_periph_unlock(periph);
@@ -951,10 +1059,15 @@
/*
* Since we're closing this CD, mark the blocksize as unavailable.
- * It will be marked as available whence the CD is opened again.
+ * It will be marked as available when the CD is opened again.
*/
softc->device_stats.flags |= DEVSTAT_BS_UNAVAILABLE;
+ /*
+ * We'll check the media and toc again at the next open().
+ */
+ softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
+
cam_periph_unlock(periph);
cam_periph_release(periph);
@@ -1330,6 +1443,21 @@
return;
}
+ /*
+ * If we don't have valid media, look for it before trying to
+ * schedule the I/O.
+ */
+ if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0) {
+ int error;
+
+ error = cdcheckmedia(periph);
+ if (error != 0) {
+ splx(s);
+ biofinish(bp, NULL, error);
+ return;
+ }
+ }
+
/*
* Place it in the queue of disk activities for this disk
*/
@@ -1743,7 +1871,36 @@
xpt_release_ccb(done_ccb);
}
+static union cd_pages *
+cdgetpage(struct cd_mode_params *mode_params)
+{
+ union cd_pages *page;
+
+ if (mode_params->cdb_size == 10)
+ page = (union cd_pages *)find_mode_page_10(
+ (struct scsi_mode_header_10 *)mode_params->mode_buf);
+ else
+ page = (union cd_pages *)find_mode_page_6(
+ (struct scsi_mode_header_6 *)mode_params->mode_buf);
+
+ return (page);
+}
+
static int
+cdgetpagesize(int page_num)
+{
+ int i;
+
+ for (i = 0; i < (sizeof(cd_page_size_table)/
+ sizeof(cd_page_size_table[0])); i++) {
+ if (cd_page_size_table[i].page == page_num)
+ return (cd_page_size_table[i].page_size);
+ }
+
+ return (-1);
+}
+
+static int
cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
{
@@ -1766,6 +1923,19 @@
if (error != 0)
return(error);
+ /*
+ * If we don't have media loaded, check for it. If still don't
+ * have media loaded, we can only do a load or eject.
+ */
+ if (((softc->flags & CD_FLAG_VALID_MEDIA) == 0)
+ && ((cmd != CDIOCCLOSE)
+ && (cmd != CDIOCEJECT))) {
+ error = cdcheckmedia(periph);
+ if (error != 0) {
+ cam_periph_unlock(periph);
+ return (error);
+ }
+ }
switch (cmd) {
@@ -1781,57 +1951,117 @@
{
struct ioc_play_track *args
= (struct ioc_play_track *) addr;
- struct cd_mode_data *data;
+ struct cd_mode_params params;
+ union cd_pages *page;
- data = malloc(sizeof(struct cd_mode_data), M_TEMP,
- M_WAITOK);
+ params.alloc_len = sizeof(union cd_mode_data_6_10);
+ params.mode_buf = malloc(params.alloc_len, M_TEMP,
+ M_WAITOK | M_ZERO);
CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("trying to do CDIOCPLAYTRACKS\n"));
- error = cdgetmode(periph, data, AUDIO_PAGE);
+ error = cdgetmode(periph, ¶ms, AUDIO_PAGE);
if (error) {
- free(data, M_TEMP);
+ free(params.mode_buf, M_TEMP);
break;
}
- data->page.audio.flags &= ~CD_PA_SOTC;
- data->page.audio.flags |= CD_PA_IMMED;
- error = cdsetmode(periph, data);
- free(data, M_TEMP);
+ page = cdgetpage(¶ms);
+
+ page->audio.flags &= ~CD_PA_SOTC;
+ page->audio.flags |= CD_PA_IMMED;
+ error = cdsetmode(periph, ¶ms);
+ free(params.mode_buf, M_TEMP);
if (error)
break;
- if (softc->quirks & CD_Q_BCD_TRACKS) {
- args->start_track = bin2bcd(args->start_track);
- args->end_track = bin2bcd(args->end_track);
+
+ /*
+ * This was originally implemented with the PLAY
+ * AUDIO TRACK INDEX command, but that command was
+ * deprecated after SCSI-2. Most (all?) SCSI CDROM
+ * drives support it but ATAPI and ATAPI-derivative
+ * drives don't seem to support it. So we keep a
+ * cache of the table of contents and translate
+ * track numbers to MSF format.
+ */
+ if (softc->flags & CD_FLAG_VALID_TOC) {
+ union msf_lba *sentry, *eentry;
+ int st, et;
+
+ if (args->end_track <
+ softc->toc.header.ending_track + 1)
+ args->end_track++;
+ if (args->end_track >
+ softc->toc.header.ending_track + 1)
+ args->end_track =
+ softc->toc.header.ending_track + 1;
+ st = args->start_track -
+ softc->toc.header.starting_track;
+ et = args->end_track -
+ softc->toc.header.starting_track;
+ if ((st < 0)
+ || (et < 0)
+ || (st > (softc->toc.header.ending_track -
+ softc->toc.header.starting_track))) {
+ error = EINVAL;
+ break;
+ }
+ sentry = &softc->toc.entries[st].addr;
+ eentry = &softc->toc.entries[et].addr;
+ error = cdplaymsf(periph,
+ sentry->msf.minute,
+ sentry->msf.second,
+ sentry->msf.frame,
+ eentry->msf.minute,
+ eentry->msf.second,
+ eentry->msf.frame);
+ } else {
+ /*
+ * If we don't have a valid TOC, try the
+ * play track index command. It is part of
+ * the SCSI-2 spec, but was removed in the
+ * MMC specs. ATAPI and ATAPI-derived
+ * drives don't support it.
+ */
+ if (softc->quirks & CD_Q_BCD_TRACKS) {
+ args->start_track =
+ bin2bcd(args->start_track);
+ args->end_track =
+ bin2bcd(args->end_track);
+ }
+ error = cdplaytracks(periph,
+ args->start_track,
+ args->start_index,
+ args->end_track,
+ args->end_index);
}
- error = cdplaytracks(periph,
- args->start_track,
- args->start_index,
- args->end_track,
- args->end_index);
}
break;
case CDIOCPLAYMSF:
{
struct ioc_play_msf *args
= (struct ioc_play_msf *) addr;
- struct cd_mode_data *data;
+ struct cd_mode_params params;
+ union cd_pages *page;
- data = malloc(sizeof(struct cd_mode_data), M_TEMP,
- M_WAITOK);
+ params.alloc_len = sizeof(union cd_mode_data_6_10);
+ params.mode_buf = malloc(params.alloc_len, M_TEMP,
+ M_WAITOK | M_ZERO);
CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("trying to do CDIOCPLAYMSF\n"));
- error = cdgetmode(periph, data, AUDIO_PAGE);
+ error = cdgetmode(periph, ¶ms, AUDIO_PAGE);
if (error) {
- free(data, M_TEMP);
+ free(params.mode_buf, M_TEMP);
break;
}
- data->page.audio.flags &= ~CD_PA_SOTC;
- data->page.audio.flags |= CD_PA_IMMED;
- error = cdsetmode(periph, data);
- free(data, M_TEMP);
+ page = cdgetpage(¶ms);
+
+ page->audio.flags &= ~CD_PA_SOTC;
+ page->audio.flags |= CD_PA_IMMED;
+ error = cdsetmode(periph, ¶ms);
+ free(params.mode_buf, M_TEMP);
if (error)
break;
error = cdplaymsf(periph,
@@ -1847,23 +2077,27 @@
{
struct ioc_play_blocks *args
= (struct ioc_play_blocks *) addr;
- struct cd_mode_data *data;
+ struct cd_mode_params params;
+ union cd_pages *page;
CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("trying to do CDIOCPLAYBLOCKS\n"));
- data = malloc(sizeof(struct cd_mode_data), M_TEMP,
- M_WAITOK);
+ params.alloc_len = sizeof(union cd_mode_data_6_10);
+ params.mode_buf = malloc(params.alloc_len, M_TEMP,
+ M_WAITOK | M_ZERO);
- error = cdgetmode(periph, data, AUDIO_PAGE);
+ error = cdgetmode(periph, ¶ms, AUDIO_PAGE);
if (error) {
- free(data, M_TEMP);
+ free(params.mode_buf, M_TEMP);
break;
}
- data->page.audio.flags &= ~CD_PA_SOTC;
- data->page.audio.flags |= CD_PA_IMMED;
- error = cdsetmode(periph, data);
- free(data, M_TEMP);
+ page = cdgetpage(¶ms);
+
+ page->audio.flags &= ~CD_PA_SOTC;
+ page->audio.flags |= CD_PA_IMMED;
+ error = cdsetmode(periph, ¶ms);
+ free(params.mode_buf, M_TEMP);
if (error)
break;
error = cdplay(periph, args->blk, args->len);
@@ -1925,9 +2159,8 @@
th = malloc(sizeof(struct ioc_toc_header), M_TEMP,
M_WAITOK);
- error = cdreadtoc(periph, 0, 0,
- (struct cd_toc_entry *)th,
- sizeof (*th));
+ error = cdreadtoc(periph, 0, 0, (u_int8_t *)th,
+ sizeof (*th), /*sense_flags*/0);
if (error) {
free(th, M_TEMP);
break;
@@ -1947,17 +2180,8 @@
break;
case CDIOREADTOCENTRYS:
{
- typedef struct {
- struct ioc_toc_header header;
- struct cd_toc_entry entries[100];
- } data_t;
- typedef struct {
- struct ioc_toc_header header;
- struct cd_toc_entry entry;
- } lead_t;
-
- data_t *data;
- lead_t *lead;
+ struct cd_tocdata *data;
+ struct cd_toc_single *lead;
struct ioc_read_toc_entry *te =
(struct ioc_read_toc_entry *) addr;
struct ioc_toc_header *th;
@@ -1967,8 +2191,8 @@
CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("trying to do CDIOREADTOCENTRYS\n"));
- data = malloc(sizeof(data_t), M_TEMP, M_WAITOK);
- lead = malloc(sizeof(lead_t), M_TEMP, M_WAITOK);
+ data = malloc(sizeof(*data), M_TEMP, M_WAITOK);
+ lead = malloc(sizeof(*lead), M_TEMP, M_WAITOK);
if (te->data_len < sizeof(struct cd_toc_entry)
|| (te->data_len % sizeof(struct cd_toc_entry)) != 0
@@ -1983,9 +2207,8 @@
}
th = &data->header;
- error = cdreadtoc(periph, 0, 0,
- (struct cd_toc_entry *)th,
- sizeof (*th));
+ error = cdreadtoc(periph, 0, 0, (u_int8_t *)th,
+ sizeof (*th), /*sense_flags*/0);
if (error) {
free(data, M_TEMP);
free(lead, M_TEMP);
@@ -2039,8 +2262,9 @@
if (readlen > 0) {
error = cdreadtoc(periph, te->address_format,
starting_track,
- (struct cd_toc_entry *)data,
- readlen + sizeof (*th));
+ (u_int8_t *)data,
+ readlen + sizeof (*th),
+ /*sense_flags*/0);
if (error) {
free(data, M_TEMP);
free(lead, M_TEMP);
@@ -2054,9 +2278,9 @@
th->ending_track = bcd2bin(th->ending_track);
if (idx == th->ending_track + 1) {
error = cdreadtoc(periph, te->address_format,
>>> TRUNCATED FOR MAIL (1000 lines) <<<
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list