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, &params, 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(&params);
+
+			page->audio.flags &= ~CD_PA_SOTC;
+			page->audio.flags |= CD_PA_IMMED;
+			error = cdsetmode(periph, &params);
+			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, &params, 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(&params);
+
+			page->audio.flags &= ~CD_PA_SOTC;
+			page->audio.flags |= CD_PA_IMMED;
+			error = cdsetmode(periph, &params);
+			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, &params, 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(&params);
+
+			page->audio.flags &= ~CD_PA_SOTC;
+			page->audio.flags |= CD_PA_IMMED;
+			error = cdsetmode(periph, &params);
+			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