From owner-p4-projects Fri Feb 21 8:45: 3 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id F153D37B405; Fri, 21 Feb 2003 08:44:37 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 84EBC37B401 for ; Fri, 21 Feb 2003 08:44:37 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5DB4043FDF for ; Fri, 21 Feb 2003 08:44:36 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h1LGia0U092326 for ; Fri, 21 Feb 2003 08:44:36 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h1LGiZ0e092323 for perforce@freebsd.org; Fri, 21 Feb 2003 08:44:35 -0800 (PST) Date: Fri, 21 Feb 2003 08:44:35 -0800 (PST) Message-Id: <200302211644.h1LGiZ0e092323@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson Subject: PERFORCE change 25529 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=25529 Change 25529 by rwatson@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 @@ -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@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@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@FreeBSD.org with "unsubscribe p4-projects" in the body of the message