Synchronize the USB, CAM, and TASKQUEUE subsystems with FreeBSD RELENG_4.
authorMatthew Dillon <dillon@dragonflybsd.org>
Mon, 29 Dec 2003 06:42:22 +0000 (06:42 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Mon, 29 Dec 2003 06:42:22 +0000 (06:42 +0000)
Also update the $FreeBSD$ ids in the files to the synchronized rev numbers.

This has the side effect of bringing in some additional SCSI robustness
checks, bug fixes, quirk inheritance between subsystems (e.g. USB now sets
PIM_NO_6_BYTE by default and CAM now understands it).

This also brings in a huge amount of SCSI CD code that had been MFCd to
FreeBSD-4 from FreeBSD-5.

22 files changed:
sys/bus/cam/cam_ccb.h
sys/bus/cam/scsi/scsi_all.c
sys/bus/cam/scsi/scsi_all.h
sys/bus/cam/scsi/scsi_cd.c
sys/bus/cam/scsi/scsi_cd.h
sys/bus/cam/scsi/scsi_da.c
sys/bus/cam/scsi/scsi_low.c
sys/bus/cam/scsi/scsi_targ_bh.c
sys/bus/usb/uhci.c
sys/bus/usb/usbdevs
sys/bus/usb/usbdevs.h
sys/bus/usb/usbdevs_data.h
sys/dev/usbmisc/ubsa/ubsa.c
sys/dev/usbmisc/ucom/ucom.c
sys/dev/usbmisc/uftdi/uftdi.c
sys/dev/usbmisc/ulpt/ulpt.c
sys/dev/usbmisc/umass/umass.c
sys/dev/usbmisc/uplcom/uplcom.c
sys/dev/usbmisc/uscanner/uscanner.c
sys/dev/usbmisc/uvisor/uvisor.c
sys/kern/subr_taskqueue.c
sys/sys/taskqueue.h

index 3893ac4..5ff4929 100644 (file)
@@ -25,8 +25,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_ccb.h,v 1.15.2.2 2000/09/22 23:09:19 gibbs Exp $
- * $DragonFly: src/sys/bus/cam/cam_ccb.h,v 1.3 2003/08/07 21:16:44 dillon Exp $
+ * $FreeBSD: src/sys/cam/cam_ccb.h,v 1.15.2.3 2003/07/29 04:00:34 njl Exp $
+ * $DragonFly: src/sys/bus/cam/cam_ccb.h,v 1.4 2003/12/29 06:42:09 dillon Exp $
  */
 
 #ifndef _CAM_CAM_CCB_H
@@ -484,7 +484,8 @@ typedef enum {
        PIM_SCANHILO    = 0x80, /* Bus scans from high ID to low ID */
        PIM_NOREMOVE    = 0x40, /* Removeable devices not included in scan */
        PIM_NOINITIATOR = 0x20, /* Initiator role not supported. */
-       PIM_NOBUSRESET  = 0x10  /* User has disabled initial BUS RESET */
+       PIM_NOBUSRESET  = 0x10, /* User has disabled initial BUS RESET */
+       PIM_NO_6_BYTE   = 0x08  /* Do not send 6-byte commands */
 } pi_miscflag;
 
 /* Path Inquiry CCB */
index bfe5203..0d7e98b 100644 (file)
@@ -26,8 +26,8 @@
  * 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.14.2.9 2002/10/21 05:38:11 simokawa Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_all.c,v 1.3 2003/08/07 21:16:44 dillon Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.14.2.11 2003/10/30 15:06:35 thomas Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_all.c,v 1.4 2003/12/29 06:42:10 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -2523,6 +2523,7 @@ scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
        scsi_cmd = (struct scsi_request_sense *)&csio->cdb_io.cdb_bytes;
        bzero(scsi_cmd, sizeof(*scsi_cmd));
        scsi_cmd->opcode = REQUEST_SENSE;
+       scsi_cmd->length = dxfer_len;
 }
 
 void
@@ -2568,13 +2569,25 @@ scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
                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,
                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.
                 */
@@ -2621,13 +2634,26 @@ scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
                 u_int8_t tag_action, int scsi_page_fmt, int save_pages,
                 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.
                 */
index 1fee368..3de4ba4 100644 (file)
@@ -14,8 +14,8 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.14.2.4 2002/10/11 20:38:28 ken Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_all.h,v 1.2 2003/06/17 04:28:19 dillon Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.14.2.5 2003/08/24 03:26:37 ken Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_all.h,v 1.3 2003/12/29 06:42:10 dillon Exp $
  */
 
 /*
@@ -833,6 +833,14 @@ void               scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
                                u_int8_t page_code, u_int8_t page,
                                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 *,
@@ -842,6 +850,14 @@ void               scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
                                 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_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
                                   void (*cbfcnp)(struct cam_periph *, 
                                   union ccb *), u_int8_t tag_action, 
index f5c0013..da19387 100644 (file)
@@ -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, 2003, 2003 Kenneth D. Merry.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -24,8 +24,8 @@
  * 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.31.2.13 2002/11/25 05:30:31 njl Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.c,v 1.9 2003/08/07 21:16:44 dillon Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.31.2.16 2003/10/21 22:26:11 thomas Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.c,v 1.10 2003/12/29 06:42:10 dillon Exp $
  */
 /*
  * Portions of this driver taken from the original FreeBSD cd driver.
@@ -62,6 +62,7 @@
 #include <sys/dvdio.h>
 #include <sys/devicestat.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #include <sys/proc.h>
 #include <sys/buf2.h>
 
@@ -84,23 +85,28 @@ struct cd_params {
 };
 
 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 {
-       CD_FLAG_INVALID         = 0x001,
-       CD_FLAG_NEW_DISC        = 0x002,
-       CD_FLAG_DISC_LOCKED     = 0x004,
-       CD_FLAG_DISC_REMOVABLE  = 0x008,
-       CD_FLAG_TAGGED_QUEUING  = 0x010,
-       CD_FLAG_CHANGER         = 0x040,
-       CD_FLAG_ACTIVE          = 0x080,
-       CD_FLAG_SCHED_ON_COMP   = 0x100,
-       CD_FLAG_RETRY_UA        = 0x200
+       CD_FLAG_INVALID         = 0x0001,
+       CD_FLAG_NEW_DISC        = 0x0002,
+       CD_FLAG_DISC_LOCKED     = 0x0004,
+       CD_FLAG_DISC_REMOVABLE  = 0x0008,
+       CD_FLAG_TAGGED_QUEUING  = 0x0010,
+       CD_FLAG_CHANGER         = 0x0040,
+       CD_FLAG_ACTIVE          = 0x0080,
+       CD_FLAG_SCHED_ON_COMP   = 0x0100,
+       CD_FLAG_RETRY_UA        = 0x0200,
+       CD_FLAG_VALID_MEDIA     = 0x0400,
+       CD_FLAG_VALID_TOC       = 0x0800,
+       CD_FLAG_OPEN            = 0x1000,
+       CD_FLAG_SCTX_INIT       = 0x2000
 } cd_flags;
 
 typedef enum {
@@ -121,6 +127,16 @@ typedef enum {
 #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
@@ -141,6 +157,22 @@ struct cd_softc {
        struct cdchanger        *changer;
        int                     bufs_left;
        struct cam_periph       *periph;
+       int                     minimum_command_size;
+       struct task             sysctl_task;
+       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 {
@@ -149,12 +181,22 @@ struct cd_quirk_entry {
 };
 
 /*
- * 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[] =
 {
@@ -188,6 +230,7 @@ static      periph_start_t  cdstart;
 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);
@@ -203,16 +246,19 @@ static    void            cddone(struct cam_periph *periph,
                               union ccb *start_ccb);
 static int             cderror(union ccb *ccb, u_int32_t cam_flags,
                                u_int32_t sense_flags);
+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             cdsize(dev_t dev, u_int32_t *size);
-static int             cdfirsttrackisdata(struct cam_periph *periph);
+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             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, 
@@ -229,7 +275,7 @@ static      int             cdplaytracks(struct cam_periph *periph,
                                     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,
@@ -292,8 +338,10 @@ SYSCTL_NODE(_kern_cam, OID_AUTO, cd, CTLFLAG_RD, 0, "CAM CDROM driver");
 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;
@@ -420,6 +468,12 @@ cdcleanup(struct cam_periph *periph)
        xpt_print_path(periph->path);
        printf("removing device entry\n");
 
+       if ((softc->flags & CD_FLAG_SCTX_INIT) != 0
+           && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
+               xpt_print_path(periph->path);
+               printf("can't remove sysctl context\n");
+       }
+
        s = splsoftcam();
        /*
         * In the queued, non-active case, the device in question
@@ -562,12 +616,85 @@ cdasync(void *callback_arg, u_int32_t code,
        }
 }
 
+static void
+cdsysctlinit(void *context, int pending)
+{
+       struct cam_periph *periph;
+       struct cd_softc *softc;
+       char tmpstr[80], tmpstr2[80];
+
+       periph = (struct cam_periph *)context;
+       softc = (struct cd_softc *)periph->softc;
+
+       snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number);
+       snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
+
+       sysctl_ctx_init(&softc->sysctl_ctx);
+       softc->flags |= CD_FLAG_SCTX_INIT;
+       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("cdsysctlinit: unable to allocate sysctl tree\n");
+               return;
+       }
+
+       /*
+        * 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 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_pathinq cpi;
        struct ccb_getdev *cgd;
+       char tmpstr[80];
        caddr_t match;
 
        cgd = (struct ccb_getdev *)arg;
@@ -590,6 +717,7 @@ cdregister(struct cam_periph *periph, void *arg)
 
        bzero(softc, sizeof(*softc));
        LIST_INIT(&softc->pending_ccbs);
+       STAILQ_INIT(&softc->mode_queue);
        softc->state = CD_STATE_PROBE;
        bufq_init(&softc->buf_queue);
        if (SID_IS_REMOVABLE(&cgd->inq_data))
@@ -615,6 +743,34 @@ cdregister(struct cam_periph *periph, void *arg)
        else
                softc->quirks = CD_Q_NONE;
 
+       /* Check if the SIM does not want 6 byte commands */
+       xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+       cpi.ccb_h.func_code = XPT_PATH_INQ;
+       xpt_action((union ccb *)&cpi);
+       if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
+               softc->quirks |= CD_Q_10_BYTE_ONLY;
+
+       TASK_INIT(&softc->sysctl_task, 0, cdsysctlinit, periph);
+
+       /* 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;
+
        /*
         * We need to register the statistics structure for this device,
         * but we don't have the blocksize yet for it.  So, we register
@@ -878,11 +1034,8 @@ cdregisterexit:
 static int
 cdopen(dev_t dev, int flags, int fmt, struct thread *td)
 {
-       struct disklabel *label;
        struct cam_periph *periph;
        struct cd_softc *softc;
-       struct ccb_getdev cgd;
-       u_int32_t size;
        int unit, error;
        int s;
 
@@ -913,72 +1066,19 @@ cdopen(dev_t dev, int flags, int fmt, struct thread *td)
        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);
-       }
-
-       /*
-        * If we get a non-zero return, revert back to not reading the
-        * label off the disk.  The first track is likely audio, which
-        * won't have a disklabel.
-        */
-       if ((error = cdfirsttrackisdata(periph)) != 0) {
-               softc->disk.d_dsflags &= ~DSO_COMPATLABEL;
-               softc->disk.d_dsflags |= DSO_NOLABELS;
-               error = 0;
-       }
-
-       /*
-        * Build prototype label for whole disk.
-        * Should take information about different data tracks from the
-        * TOC and put it in the partition table.
-        */
-       label = &softc->disk.d_label;
-       bzero(label, sizeof(*label));
-       label->d_type = DTYPE_SCSI;
-
-       /*
-        * Grab the inquiry data to get the vendor and product names.
-        * Put them in the typename and packname for the label.
-        */
-       xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1);
-       cgd.ccb_h.func_code = XPT_GDEV_TYPE;
-       xpt_action((union ccb *)&cgd);
-
-       strncpy(label->d_typename, cgd.inq_data.vendor,
-               min(SID_VENDOR_SIZE, sizeof(label->d_typename)));
-       strncpy(label->d_packname, cgd.inq_data.product,
-               min(SID_PRODUCT_SIZE, sizeof(label->d_packname)));
-               
-       label->d_secsize = softc->params.blksize;
-       label->d_secperunit = softc->params.disksize;
-       label->d_flags = D_REMOVABLE;
        /*
-        * Make partition 'a' cover the whole disk.  This is a temporary
-        * compatibility hack.  The 'a' partition should not exist, so
-        * the slice code won't create it.  The slice code will make
-        * partition (RAW_PART + 'a') cover the whole disk and fill in
-        * some more defaults.
+        * 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.
+        *
+        * XXX KDM for now, we do fail the open if we don't have media.  We
+        * can change this once we've figured out how to make the slice
+        * code work well with media changing underneath it.
         */
-       label->d_partitions[0].p_size = label->d_secperunit;
-       label->d_partitions[0].p_fstype = FS_OTHER;
+       error = cdcheckmedia(periph);
 
-       /*
-        * 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?
-        */
-       if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0)
-               softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
-       softc->device_stats.block_size = softc->params.blksize;
+       if (error == 0)
+               softc->flags |= CD_FLAG_OPEN;
 
        cam_periph_unlock(periph);
 
@@ -1016,10 +1116,17 @@ cdclose(dev_t dev, int flag, int fmt, struct thread *td)
 
        /*
         * 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);
+       
+       softc->flags &= ~CD_FLAG_OPEN;
+
        cam_periph_unlock(periph);
        cam_periph_release(periph);
 
@@ -1398,6 +1505,21 @@ cdstrategy(struct buf *bp)
                goto bad;
        }
 
+       /*
+        * 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);
+                       bp->b_error = error;
+                       goto bad;
+               }
+       }
+
        /*
         * Place it in the queue of disk activities for this disk
         */
@@ -1785,6 +1907,11 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
                        xpt_announce_periph(periph, announce_buf);
                        if (softc->flags & CD_FLAG_CHANGER)
                                cdchangerschedule(softc);
+                       /*
+                        * Create our sysctl variables, now that we know
+                        * we have successfully attached.
+                        */
+                       taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
                }
                softc->state = CD_STATE_NORMAL;         
                /*
@@ -1814,6 +1941,34 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
        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)
 {
@@ -1840,63 +1995,137 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
        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) {
 
        case CDIOCPLAYTRACKS:
                {
                        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,
@@ -1912,23 +2141,27 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                {
                        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);
@@ -1990,9 +2223,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
 
                        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;
@@ -2012,17 +2244,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                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;
@@ -2032,8 +2255,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        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
@@ -2048,9 +2271,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        }
 
                        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);
@@ -2104,8 +2326,9 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        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);
@@ -2119,9 +2342,9 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                                th->ending_track = bcd2bin(th->ending_track);
                        if (idx == th->ending_track + 1) {
                                error = cdreadtoc(periph, te->address_format,
-                                                 LEADOUT, 
-                                                 (struct cd_toc_entry *)lead,
-                                                 sizeof(*lead));
+                                                 LEADOUT, (u_int8_t *)lead,
+                                                 sizeof(*lead),
+                                                 /*sense_flags*/0);
                                if (error) {
                                        free(data, M_TEMP);
                                        free(lead, M_TEMP);
@@ -2144,13 +2367,7 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                break;
        case CDIOREADTOCENTRY:
                {
-                       /* yeah yeah, this is ugly */
-                       typedef struct {
-                               struct ioc_toc_header header;
-                               struct cd_toc_entry entry;
-                       } data_t;
-
-                       data_t *data;
+                       struct cd_toc_single *data;
                        struct ioc_read_toc_single_entry *te =
                                (struct ioc_read_toc_single_entry *) addr;
                        struct ioc_toc_header *th;
@@ -2159,7 +2376,7 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOREADTOCENTRY\n"));
 
-                       data = malloc(sizeof(data_t), M_TEMP, M_WAITOK);
+                       data = malloc(sizeof(*data), M_TEMP, M_WAITOK);
 
                        if (te->address_format != CD_MSF_FORMAT
                            && te->address_format != CD_LBA_FORMAT) {
@@ -2171,9 +2388,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        }
 
                        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);
                                break;
@@ -2202,8 +2418,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                        }
 
                        error = cdreadtoc(periph, te->address_format, track,
-                                         (struct cd_toc_entry *)data,
-                                         sizeof(data_t));
+                                         (u_int8_t *)data, sizeof(*data),
+                                         /*sense_flags*/0);
                        if (error) {
                                free(data, M_TEMP);
                                break;
@@ -2218,196 +2434,226 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                break;
        case CDIOCSETPATCH:
                {
-                       struct ioc_patch *arg = (struct ioc_patch *) addr;
-                       struct cd_mode_data *data;
+                       struct ioc_patch *arg = (struct ioc_patch *)addr;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETPATCH\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP, 
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = 
                                arg->patch[0];
-                       data->page.audio.port[RIGHT_PORT].channels = 
+                       page->audio.port[RIGHT_PORT].channels = 
                                arg->patch[1];
-                       data->page.audio.port[2].channels = arg->patch[2];
-                       data->page.audio.port[3].channels = arg->patch[3];
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page->audio.port[2].channels = arg->patch[2];
+                       page->audio.port[3].channels = arg->patch[3];
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCGETVOL:
                {
                        struct ioc_vol *arg = (struct ioc_vol *) 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 CDIOCGETVOL\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP, 
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
+                       page = cdgetpage(&params);
+
                        arg->vol[LEFT_PORT] = 
-                               data->page.audio.port[LEFT_PORT].volume;
+                               page->audio.port[LEFT_PORT].volume;
                        arg->vol[RIGHT_PORT] = 
-                               data->page.audio.port[RIGHT_PORT].volume;
-                       arg->vol[2] = data->page.audio.port[2].volume;
-                       arg->vol[3] = data->page.audio.port[3].volume;
-                       free(data, M_TEMP);
+                               page->audio.port[RIGHT_PORT].volume;
+                       arg->vol[2] = page->audio.port[2].volume;
+                       arg->vol[3] = page->audio.port[3].volume;
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETVOL:
                {
                        struct ioc_vol *arg = (struct ioc_vol *) 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 CDIOCSETVOL\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP, 
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = CHANNEL_0;
-                       data->page.audio.port[LEFT_PORT].volume = 
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = CHANNEL_0;
+                       page->audio.port[LEFT_PORT].volume = 
                                arg->vol[LEFT_PORT];
-                       data->page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
-                       data->page.audio.port[RIGHT_PORT].volume = 
+                       page->audio.port[RIGHT_PORT].channels = CHANNEL_1;
+                       page->audio.port[RIGHT_PORT].volume = 
                                arg->vol[RIGHT_PORT];
-                       data->page.audio.port[2].volume = arg->vol[2];
-                       data->page.audio.port[3].volume = arg->vol[3];
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page->audio.port[2].volume = arg->vol[2];
+                       page->audio.port[3].volume = arg->vol[3];
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETMONO:
                {
-                       struct cd_mode_data *data;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETMONO\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), 
-                                     M_TEMP, M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = 
                                LEFT_CHANNEL | RIGHT_CHANNEL;
-                       data->page.audio.port[RIGHT_PORT].channels = 
+                       page->audio.port[RIGHT_PORT].channels = 
                                LEFT_CHANNEL | RIGHT_CHANNEL;
-                       data->page.audio.port[2].channels = 0;
-                       data->page.audio.port[3].channels = 0;
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page->audio.port[2].channels = 0;
+                       page->audio.port[3].channels = 0;
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETSTEREO:
                {
-                       struct cd_mode_data *data;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETSTEREO\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP,
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = 
                                LEFT_CHANNEL;
-                       data->page.audio.port[RIGHT_PORT].channels = 
+                       page->audio.port[RIGHT_PORT].channels = 
                                RIGHT_CHANNEL;
-                       data->page.audio.port[2].channels = 0;
-                       data->page.audio.port[3].channels = 0;
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page->audio.port[2].channels = 0;
+                       page->audio.port[3].channels = 0;
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETMUTE:
                {
-                       struct cd_mode_data *data;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETMUTE\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP,
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(&params, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 0;
-                       data->page.audio.port[RIGHT_PORT].channels = 0;
-                       data->page.audio.port[2].channels = 0;
-                       data->page.audio.port[3].channels = 0;
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = 0;
+                       page->audio.port[RIGHT_PORT].channels = 0;
+                       page->audio.port[2].channels = 0;
+                       page->audio.port[3].channels = 0;
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETLEFT:
                {
-                       struct cd_mode_data *data;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETLEFT\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP,
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 
-                               LEFT_CHANNEL;
-                       data->page.audio.port[RIGHT_PORT].channels = 
-                               LEFT_CHANNEL;
-                       data->page.audio.port[2].channels = 0;
-                       data->page.audio.port[3].channels = 0;
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
+                       page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL;
+                       page->audio.port[2].channels = 0;
+                       page->audio.port[3].channels = 0;
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCSETRIGHT:
                {
-                       struct cd_mode_data *data;
+                       struct cd_mode_params params;
+                       union cd_pages *page;
 
                        CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 
                                  ("trying to do CDIOCSETRIGHT\n"));
 
-                       data = malloc(sizeof(struct cd_mode_data), M_TEMP,
-                                     M_WAITOK);
-                       error = cdgetmode(periph, data, AUDIO_PAGE);
+                       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, &params, AUDIO_PAGE);
                        if (error) {
-                               free(data, M_TEMP);
+                               free(params.mode_buf, M_TEMP);
                                break;
                        }
-                       data->page.audio.port[LEFT_PORT].channels = 
-                               RIGHT_CHANNEL;
-                       data->page.audio.port[RIGHT_PORT].channels = 
-                               RIGHT_CHANNEL;
-                       data->page.audio.port[2].channels = 0;
-                       data->page.audio.port[3].channels = 0;
-                       error = cdsetmode(periph, data);
-                       free(data, M_TEMP);
+                       page = cdgetpage(&params);
+
+                       page->audio.port[LEFT_PORT].channels = RIGHT_CHANNEL;
+                       page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
+                       page->audio.port[2].channels = 0;
+                       page->audio.port[3].channels = 0;
+                       error = cdsetmode(periph, &params);
+                       free(params.mode_buf, M_TEMP);
                }
                break;
        case CDIOCRESUME:
@@ -2417,13 +2663,40 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
                error = cdpause(periph, 0);
                break;
        case CDIOCSTART:
-               error = cdstartunit(periph);
+               error = cdstartunit(periph, 0);
+               break;
+       case CDIOCCLOSE:
+               error = cdstartunit(periph, 1);
+
+#ifdef notyet
+               if (error != 0)
+                       break;
+
+               /*
+                * The user successfully closed the tray, run
+                * cdcheckmedia() again so we can re-sync the disklabel
+                * information.
+                */
+               cdcheckmedia(periph);
+#endif /* notyet */
                break;
        case CDIOCSTOP:
                error = cdstopunit(periph, 0);
                break;
        case CDIOCEJECT:
                error = cdstopunit(periph, 1);
+
+#ifdef notyet
+               if (error != 0)
+                       break;
+
+               /*
+                * Since we've successfully ejected the media, run
+                * cdcheckmedia() again so we re-sync the disklabel
+                * information.
+                */
+               cdcheckmedia(periph);
+#endif /* notyet */
                break;
        case CDIOCALLOW:
                cdprevent(periph, PR_ALLOW);
@@ -2523,20 +2796,295 @@ cdprevent(struct cam_periph *periph, int action)
        }
 }
 
+int
+cdcheckmedia(struct cam_periph *periph)
+{
+       struct cd_softc *softc;
+       struct ioc_toc_header *toch;
+       struct cd_toc_single leadout;
+       struct ccb_getdev cgd;
+       u_int32_t size, toclen;
+       int error, num_entries, cdindex;
+       int first_track_audio;
+       struct disklabel *label;
+
+       softc = (struct cd_softc *)periph->softc;
+
+       first_track_audio = -1;
+       error = 0;
+
+       cdprevent(periph, PR_PREVENT);
+
+       /*
+        * Build prototype label for whole disk.
+        * Should take information about different data tracks from the
+        * TOC and put it in the partition table.
+        */
+       label = &softc->disk.d_label;
+       bzero(label, sizeof(*label));
+       label->d_type = DTYPE_SCSI;
+
+       /*
+        * Grab the inquiry data to get the vendor and product names.
+        * Put them in the typename and packname for the label.
+        */
+       xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1);
+       cgd.ccb_h.func_code = XPT_GDEV_TYPE;
+       xpt_action((union ccb *)&cgd);
+
+       strncpy(label->d_typename, cgd.inq_data.vendor,
+               min(SID_VENDOR_SIZE, sizeof(label->d_typename)));
+       strncpy(label->d_packname, cgd.inq_data.product,
+               min(SID_PRODUCT_SIZE, sizeof(label->d_packname)));
+               
+       label->d_flags = D_REMOVABLE;
+       /*
+        * Make partition 'a' cover the whole disk.  This is a temporary
+        * compatibility hack.  The 'a' partition should not exist, so
+        * the slice code won't create it.  The slice code will make
+        * partition (RAW_PART + 'a') cover the whole disk and fill in
+        * some more defaults.
+        */
+       label->d_partitions[0].p_size = label->d_secperunit;
+       label->d_partitions[0].p_fstype = FS_OTHER;
+
+       /*
+        * Default to not reading the disklabel off the disk, until we can
+        * verify that we have media, that we have a table of contents, and
+        * that the first track is a data track (which could theoretically
+        * contain a disklabel).
+        */
+       softc->disk.d_dsflags &= ~DSO_COMPATLABEL;
+       softc->disk.d_dsflags |= DSO_NOLABELS;
+
+       /*
+        * Clear the valid media and TOC flags until we've verified that we
+        * have both.
+        */
+       softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
+
+       /*
+        * Get the disc size and block size.  If we can't get it, we don't
+        * have media, most likely.
+        */
+       if ((error = cdsize(periph, &size)) != 0) {
+               /*
+                * Set a bogus sector size, so the slice code won't try to
+                * divide by 0 and panic the kernel.
+                */
+               label->d_secsize = 2048;
+
+               label->d_secperunit = 0;
+
+               /*
+                * XXX KDM is this a good idea?  Seems to cause more
+                * problems.
+                */
+               if (softc->flags & CD_FLAG_OPEN) {
+                       int force;
+
+                       force = 1;
+
+                       /*
+                        * We don't bother checking the return value here,
+                        * since we already have an error...
+                        */
+                       dsioctl(softc->disk.d_dev, DIOCSYNCSLICEINFO,
+                               /*data*/(caddr_t)&force, /*flags*/ 0,
+                               &softc->disk.d_slice);
+               }
+
+               /*
+                * Tell devstat(9) we don't have a blocksize.
+                */
+               softc->device_stats.flags |= DEVSTAT_BS_UNAVAILABLE;
+
+               cdprevent(periph, PR_ALLOW);
+
+               return (error);
+       } else {
+
+               label->d_secsize = softc->params.blksize;
+               label->d_secperunit = softc->params.disksize;
+
+               /*
+                * Force a re-sync of slice information, like the blocksize,
+                * now that we know it.  It isn't pretty...but according to
+                * Bruce Evans, this is probably the best way to do it in
+                * -stable.  We only do this if we're already open, and
+                * therefore dsopen() has already run.  If CD_FLAG_OPEN
+                * isn't set, this isn't necessary.
+                */
+               if (softc->flags & CD_FLAG_OPEN) {
+                       int force;
+
+                       force = 1;
+
+                       error = dsioctl(softc->disk.d_dev, DIOCSYNCSLICEINFO,
+                                       /*data*/(caddr_t)&force, /*flags*/ 0,
+                                       &softc->disk.d_slice);
+                       if (error != 0) {
+                               /*
+                                * Set a bogus sector size, so the slice code
+                                * won't try to divide by 0 and panic the
+                                * kernel.
+                                */
+                               label->d_secsize = 2048;
+
+                               label->d_secperunit = 0;
+
+                               /*
+                                * Tell devstat(9) we don't have a blocksize.
+                                */
+                               softc->device_stats.flags |=
+                                       DEVSTAT_BS_UNAVAILABLE;
+
+                               cdprevent(periph, PR_ALLOW);
+                       }
+               }
+
+               /*
+                * 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?
+                */
+               if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0)
+                       softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
+               softc->device_stats.block_size = softc->params.blksize;
+
+               softc->flags |= CD_FLAG_VALID_MEDIA;
+       }
+
+       /*
+        * Now we check the table of contents.  This (currently) is only
+        * used for the CDIOCPLAYTRACKS ioctl.  It may be used later to do
+        * things like present a separate entry in /dev for each track,
+        * like that acd(4) driver does.
+        */
+       bzero(&softc->toc, sizeof(softc->toc));
+       toch = &softc->toc.header;
+
+       /*
+        * We will get errors here for media that doesn't have a table of
+        * contents.  According to the MMC-3 spec: "When a Read TOC/PMA/ATIP
+        * command is presented for a DDCD/CD-R/RW media, where the first TOC
+        * has not been recorded (no complete session) and the Format codes
+        * 0000b, 0001b, or 0010b are specified, this command shall be rejected
+        * with an INVALID FIELD IN CDB.  Devices that are not capable of
+        * reading an incomplete session on DDC/CD-R/RW media shall report
+        * CANNOT READ MEDIUM - INCOMPATIBLE FORMAT."
+        *
+        * So this isn't fatal if we can't read the table of contents, it
+        * just means that the user won't be able to issue the play tracks
+        * ioctl, and likely lots of other stuff won't work either.  They
+        * need to burn the CD before we can do a whole lot with it.  So
+        * we don't print anything here if we get an error back.
+        */
+       error = cdreadtoc(periph, 0, 0, (u_int8_t *)toch, sizeof(*toch),
+                         SF_NO_PRINT);
+       /*
+        * Errors in reading the table of contents aren't fatal, we just
+        * won't have a valid table of contents cached.
+        */
+       if (error != 0) {
+               error = 0;
+               bzero(&softc->toc, sizeof(softc->toc));
+               goto bailout;
+       }
+
+       if (softc->quirks & CD_Q_BCD_TRACKS) {
+               toch->starting_track = bcd2bin(toch->starting_track);
+               toch->ending_track = bcd2bin(toch->ending_track);
+       }
+
+       /* Number of TOC entries, plus leadout */
+       num_entries = (toch->ending_track - toch->starting_track) + 2;
+
+       if (num_entries <= 0)
+               goto bailout;
+
+       toclen = num_entries * sizeof(struct cd_toc_entry);
+
+       error = cdreadtoc(periph, CD_MSF_FORMAT, toch->starting_track,
+                         (u_int8_t *)&softc->toc, toclen + sizeof(*toch),
+                         SF_NO_PRINT);
+       if (error != 0) {
+               error = 0;
+               bzero(&softc->toc, sizeof(softc->toc));
+               goto bailout;
+       }
+
+       if (softc->quirks & CD_Q_BCD_TRACKS) {
+               toch->starting_track = bcd2bin(toch->starting_track);
+               toch->ending_track = bcd2bin(toch->ending_track);
+       }
+       toch->len = scsi_2btoul((uint8_t *)&toch->len);
+
+       /*
+        * XXX KDM is this necessary?  Probably only if the drive doesn't
+        * return leadout information with the table of contents.
+        */
+       cdindex = toch->starting_track + num_entries -1;
+       if (cdindex == toch->ending_track + 1) {
+
+               error = cdreadtoc(periph, CD_MSF_FORMAT, LEADOUT, 
+                                 (u_int8_t *)&leadout, sizeof(leadout),
+                                 SF_NO_PRINT);
+               if (error != 0) {
+                       error = 0;
+                       goto bailout;
+               }
+               softc->toc.entries[cdindex - toch->starting_track] =
+                       leadout.entry;
+       }
+       if (softc->quirks & CD_Q_BCD_TRACKS) {
+               for (cdindex = 0; cdindex < (num_entries - 1); cdindex++) {
+                       softc->toc.entries[cdindex].track =
+                               bcd2bin(softc->toc.entries[cdindex].track);
+               }
+       }
+
+       /*
+        * Run through the TOC entries, find the first entry and determine
+        * whether it is an audio or data track.
+        */
+       for (cdindex = 0; cdindex < (num_entries - 1); cdindex++) {
+               if (softc->toc.entries[cdindex].track == toch->starting_track) {
+                       if (softc->toc.entries[cdindex].control & 0x04)
+                               first_track_audio = 0;
+                       else
+                               first_track_audio = 1;
+                       break;
+               }
+       }
+
+       /*
+        * If first_track_audio is non-zero, we either have an error (e.g.
+        * couldn't find the starting track) or the first track is an audio
+        * track.  If first_track_audio is 0, the first track is a data
+        * track that could have a disklabel.  Attempt to read the
+        * disklabel off the media, just in case the user put one there.
+        */
+       if (first_track_audio == 0) {
+               softc->disk.d_dsflags |= DSO_COMPATLABEL;
+               softc->disk.d_dsflags &= ~DSO_NOLABELS;
+       }
+       softc->flags |= CD_FLAG_VALID_TOC;
+
+bailout:
+       return (error);
+}
+
 static int
-cdsize(dev_t dev, u_int32_t *size)
+cdsize(struct cam_periph *periph, u_int32_t *size)
 {
-       struct cam_periph *periph;
        struct cd_softc *softc;
        union ccb *ccb;
        struct scsi_read_capacity_data *rcap_buf;
        int error;
 
-       periph = cam_extend_get(cdperiphs, dkunit(dev));
-
-       if (periph == NULL)
-               return (ENXIO);
-        
        CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdsize\n"));
 
        softc = (struct cd_softc *)periph->softc;
@@ -2579,78 +3127,153 @@ cdsize(dev_t dev, u_int32_t *size)
 
 }
 
-/*
- * The idea here is to try to figure out whether the first track is data or
- * audio.  If it is data, we can at least attempt to read a disklabel off
- * the first sector of the disk.  If it is audio, there won't be a
- * disklabel.
- *
- * This routine returns 0 if the first track is data, and non-zero if there
- * is an error or the first track is audio.  (If either non-zero case, we
- * should not attempt to read the disklabel.)
- */
 static int
-cdfirsttrackisdata(struct cam_periph *periph)
+cd6byteworkaround(union ccb *ccb)
 {
-       struct cdtocdata {
-               struct ioc_toc_header header;
-               struct cd_toc_entry entries[100];
-       };
+       u_int8_t *cdb;
+       struct cam_periph *periph;
        struct cd_softc *softc;
-       struct ioc_toc_header *th;
-       struct cdtocdata *data;
-       int num_entries, i;
-       int error, first_track_audio;
-
-       error = 0;
-       first_track_audio = -1;
+       struct cd_mode_params *params;
+       int frozen, found;
 
+       periph = xpt_path_periph(ccb->ccb_h.path);
        softc = (struct cd_softc *)periph->softc;
 
-       data = malloc(sizeof(struct cdtocdata), M_TEMP, M_WAITOK);
+       cdb = ccb->csio.cdb_io.cdb_bytes;
 
-       th = &data->header;
-       error = cdreadtoc(periph, 0, 0, (struct cd_toc_entry *)data,
-                         sizeof(*data));
+       if ((ccb->ccb_h.flags & CAM_CDB_POINTER)
+        || ((cdb[0] != MODE_SENSE_6)
+         && (cdb[0] != MODE_SELECT_6)))
+               return (0);
 
-       if (error)
-               goto bailout;
+       /*
+        * Because there is no convenient place to stash the overall
+        * cd_mode_params structure pointer, we have to grab it like this.
+        * This means that ALL MODE_SENSE and MODE_SELECT requests in the
+        * cd(4) driver MUST go through cdgetmode() and cdsetmode()!
+        *
+        * XXX It would be nice if, at some point, we could increase the
+        * number of available peripheral private pointers.  Both pointers
+        * are currently used in most every peripheral driver.
+        */
+       found = 0;
 
-       if (softc->quirks & CD_Q_BCD_TRACKS) {
-               /* we are going to have to convert the BCD
-                * encoding on the cd to what is expected
-                */
-               th->starting_track =
-                   bcd2bin(th->starting_track);
-               th->ending_track = bcd2bin(th->ending_track);
+       STAILQ_FOREACH(params, &softc->mode_queue, links) {
+               if (params->mode_buf == ccb->csio.data_ptr) {
+                       found = 1;
+                       break;
+               }
        }
-       th->len = scsi_2btoul((u_int8_t *)&th->len);
 
-       if ((th->len - 2) > 0)
-               num_entries = (th->len - 2) / sizeof(struct cd_toc_entry);
-       else
-               num_entries = 0;
+       /*
+        * This shouldn't happen.  All mode sense and mode select
+        * operations in the cd(4) driver MUST go through cdgetmode() and
+        * cdsetmode()!
+        */
+       if (found == 0) {
+               xpt_print_path(periph->path);
+               printf("mode buffer not found in mode queue!\n");
+               return (0);
+       }
 
-       for (i = 0; i < num_entries; i++) {
-               if (data->entries[i].track == th->starting_track) {
-                       if (data->entries[i].control & 0x4)
-                               first_track_audio = 0;
-                       else
-                               first_track_audio = 1;
-                       break;
-               }
+       params->cdb_size = 10;
+       softc->minimum_command_size = 10;
+       xpt_print_path(ccb->ccb_h.path);
+       printf("%s(6) failed, increasing minimum CDB size to 10 bytes\n",
+              (cdb[0] == MODE_SENSE_6) ? "MODE_SENSE" : "MODE_SELECT");
+
+       if (cdb[0] == MODE_SENSE_6) {
+               struct scsi_mode_sense_10 ms10;
+               struct scsi_mode_sense_6 *ms6;
+               int len;
+
+               ms6 = (struct scsi_mode_sense_6 *)cdb;
+
+               bzero(&ms10, sizeof(ms10));
+               ms10.opcode = MODE_SENSE_10;
+               ms10.byte2 = ms6->byte2;
+               ms10.page = ms6->page;
+
+               /*
+                * 10 byte mode header, block descriptor,
+                * sizeof(union cd_pages)
+                */
+               len = sizeof(struct cd_mode_data_10);
+               ccb->csio.dxfer_len = len;
+
+               scsi_ulto2b(len, ms10.length);
+               ms10.control = ms6->control;
+               bcopy(&ms10, cdb, 10);
+               ccb->csio.cdb_len = 10;
+       } else {
+               struct scsi_mode_select_10 ms10;
+               struct scsi_mode_select_6 *ms6;
+               struct scsi_mode_header_6 *header6;
+               struct scsi_mode_header_10 *header10;
+               struct scsi_mode_page_header *page_header;
+               int blk_desc_len, page_num, page_size, len;
+
+               ms6 = (struct scsi_mode_select_6 *)cdb;
+
+               bzero(&ms10, sizeof(ms10));
+               ms10.opcode = MODE_SELECT_10;
+               ms10.byte2 = ms6->byte2;
+
+               header6 = (struct scsi_mode_header_6 *)params->mode_buf;
+               header10 = (struct scsi_mode_header_10 *)params->mode_buf;
+
+               page_header = find_mode_page_6(header6);
+               page_num = page_header->page_code;
+
+               blk_desc_len = header6->blk_desc_len;
+
+               page_size = cdgetpagesize(page_num);
+
+               if (page_size != (page_header->page_length +
+                   sizeof(*page_header)))
+                       page_size = page_header->page_length +
+                               sizeof(*page_header);
+
+               len = sizeof(*header10) + blk_desc_len + page_size;
+
+               len = min(params->alloc_len, len);
+
+               /*
+                * Since the 6 byte parameter header is shorter than the 10
+                * byte parameter header, we need to copy the actual mode
+                * page data, and the block descriptor, if any, so things wind
+                * up in the right place.  The regions will overlap, but
+                * bcopy() does the right thing.
+                */
+               bcopy(params->mode_buf + sizeof(*header6),
+                     params->mode_buf + sizeof(*header10),
+                     len - sizeof(*header10));
+
+               /* Make sure these fields are set correctly. */
+               scsi_ulto2b(0, header10->data_length);
+               header10->medium_type = 0;
+               scsi_ulto2b(blk_desc_len, header10->blk_desc_len);
+
+               ccb->csio.dxfer_len = len;
+
+               scsi_ulto2b(len, ms10.length);
+               ms10.control = ms6->control;
+               bcopy(&ms10, cdb, 10);
+               ccb->csio.cdb_len = 10;
        }
 
-       if (first_track_audio == -1)
-               error = ENOENT;
-       else if (first_track_audio == 1)
-               error = EINVAL;
-       else
-               error = 0;
-bailout:
-       free(data, M_TEMP);
+       frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
+       ccb->ccb_h.status = CAM_REQUEUE_REQ;
+       xpt_action(ccb);
+       if (frozen) {
+               cam_release_devq(ccb->ccb_h.path,
+                                /*relsim_flags*/0,
+                                /*openings*/0,
+                                /*timeout*/0,
+                                /*getcount_only*/0);
+       }
 
-       return(error);
+       return (ERESTART);
 }
 
 static int
@@ -2658,10 +3281,37 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
 {
        struct cd_softc *softc;
        struct cam_periph *periph;
+       int error;
 
        periph = xpt_path_periph(ccb->ccb_h.path);
        softc = (struct cd_softc *)periph->softc;
 
+       error = 0;
+
+       /*
+        * We use a status of CAM_REQ_INVALID as shorthand -- if a 6 byte
+        * CDB comes back with this particular error, try transforming it
+        * into the 10 byte version.
+        */
+       if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
+               error = cd6byteworkaround(ccb);
+       } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
+                    CAM_SCSI_STATUS_ERROR)
+        && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
+        && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
+        && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
+        && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
+               int sense_key, error_code, asc, ascq;
+
+               scsi_extract_sense(&ccb->csio.sense_data,
+                                  &error_code, &sense_key, &asc, &ascq);
+               if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
+                       error = cd6byteworkaround(ccb);
+       }
+
+       if (error == ERESTART)
+               return (error);
+
        /*
         * XXX
         * Until we have a better way of doing pack validation,
@@ -2677,7 +3327,7 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
  */
 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_int8_t *data, u_int32_t len, u_int32_t sense_flags)
 {
        struct scsi_read_toc *scsi_cmd;
        u_int32_t ntoc;
@@ -2697,7 +3347,7 @@ cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start,
                      /* cbfcnp */ cddone, 
                      /* flags */ CAM_DIR_IN,
                      /* tag_action */ MSG_SIMPLE_Q_TAG,
-                     /* data_ptr */ (u_int8_t *)data,
+                     /* data_ptr */ data,
                      /* dxfer_len */ len,
                      /* sense_len */ SSD_FULL_SIZE,
                      sizeof(struct scsi_read_toc),
@@ -2716,7 +3366,8 @@ cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start,
        scsi_cmd->op_code = READ_TOC;
 
        error = cdrunccb(ccb, cderror, /*cam_flags*/0,
-                        /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO);
+                        /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO |
+                        sense_flags);
 
        xpt_release_ccb(ccb);
 
@@ -2770,93 +3421,205 @@ cdreadsubchannel(struct cam_periph *periph, u_int32_t mode,
        return(error);
 }
 
-
+/*
+ * All MODE_SENSE requests in the cd(4) driver MUST go through this
+ * routine.  See comments in cd6byteworkaround() for details.
+ */
 static int
-cdgetmode(struct cam_periph *periph, struct cd_mode_data *data, u_int32_t page)
+cdgetmode(struct cam_periph *periph, struct cd_mode_params *data,
+         u_int32_t page)
 {
-       struct scsi_mode_sense_6 *scsi_cmd;
-        struct ccb_scsiio *csio;
+       struct ccb_scsiio *csio;
+       struct cd_softc *softc;
        union ccb *ccb;
+       int param_len;
        int error;
 
+       softc = (struct cd_softc *)periph->softc;
+
        ccb = cdgetccb(periph, /* priority */ 1);
 
        csio = &ccb->csio;
 
-       bzero(data, sizeof(*data));
-       cam_fill_csio(csio, 
-                     /* retries */ 1, 
-                     /* cbfcnp */ cddone, 
-                     /* flags */ CAM_DIR_IN,
-                     /* tag_action */ MSG_SIMPLE_Q_TAG,
-                     /* data_ptr */ (u_int8_t *)data,
-                     /* dxfer_len */ sizeof(*data),
-                     /* sense_len */ SSD_FULL_SIZE,
-                     sizeof(struct scsi_mode_sense_6),
-                     /* timeout */ 50000);
-
-       scsi_cmd = (struct scsi_mode_sense_6 *)&csio->cdb_io.cdb_bytes;
-       bzero (scsi_cmd, sizeof(*scsi_cmd));
+       data->cdb_size = softc->minimum_command_size;
+       if (data->cdb_size < 10)
+               param_len = sizeof(struct cd_mode_data);
+       else
+               param_len = sizeof(struct cd_mode_data_10);
+
+       /* Don't say we've got more room than we actually allocated */
+       param_len = min(param_len, data->alloc_len);
+
+       scsi_mode_sense_len(csio,
+                           /* retries */ 1,
+                           /* cbfcnp */ cddone,
+                           /* tag_action */ MSG_SIMPLE_Q_TAG,
+                           /* dbd */ 0,
+                           /* page_code */ SMS_PAGE_CTRL_CURRENT,
+                           /* page */ page,
+                           /* param_buf */ data->mode_buf,
+                           /* param_len */ param_len,
+                           /* minimum_cmd_size */ softc->minimum_command_size,
+                           /* sense_len */ SSD_FULL_SIZE,
+                           /* timeout */ 50000);
 
-       scsi_cmd->page = page;
-       scsi_cmd->length = sizeof(*data) & 0xff;
-       scsi_cmd->opcode = MODE_SENSE;
+       /*
+        * It would be nice not to have to do this, but there's no
+        * available pointer in the CCB that would allow us to stuff the
+        * mode params structure in there and retrieve it in
+        * cd6byteworkaround(), so we can set the cdb size.  The cdb size
+        * lets the caller know what CDB size we ended up using, so they
+        * can find the actual mode page offset.
+        */
+       STAILQ_INSERT_TAIL(&softc->mode_queue, data, links);
 
        error = cdrunccb(ccb, cderror, /*cam_flags*/0,
                         /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO);
 
        xpt_release_ccb(ccb);
 
-       return(error);
+       STAILQ_REMOVE(&softc->mode_queue, data, cd_mode_params, links);
+
+       /*
+        * This is a bit of belt-and-suspenders checking, but if we run
+        * into a situation where the target sends back multiple block
+        * descriptors, we might not have enough space in the buffer to
+        * see the whole mode page.  Better to return an error than
+        * potentially access memory beyond our malloced region.
+        */
+       if (error == 0) {
+               u_int32_t data_len;
+
+               if (data->cdb_size == 10) {
+                       struct scsi_mode_header_10 *hdr10;
+
+                       hdr10 = (struct scsi_mode_header_10 *)data->mode_buf;
+                       data_len = scsi_2btoul(hdr10->data_length);
+                       data_len += sizeof(hdr10->data_length);
+               } else {
+                       struct scsi_mode_header_6 *hdr6;
+
+                       hdr6 = (struct scsi_mode_header_6 *)data->mode_buf;
+                       data_len = hdr6->data_length;
+                       data_len += sizeof(hdr6->data_length);
+               }
+
+               /*
+                * Complain if there is more mode data available than we
+                * allocated space for.  This could potentially happen if
+                * we miscalculated the page length for some reason, if the
+                * drive returns multiple block descriptors, or if it sets
+                * the data length incorrectly.
+                */
+               if (data_len > data->alloc_len) {
+                       xpt_print_path(periph->path);
+                       printf("allocated modepage %d length %d < returned "
+                              "length %d\n", page, data->alloc_len, data_len);
+
+                       error = ENOSPC;
+               }
+       }
+       return (error);
 }
 
+/*
+ * All MODE_SELECT requests in the cd(4) driver MUST go through this
+ * routine.  See comments in cd6byteworkaround() for details.
+ */
 static int
-cdsetmode(struct cam_periph *periph, struct cd_mode_data *data)
+cdsetmode(struct cam_periph *periph, struct cd_mode_params *data)
 {
-       struct scsi_mode_select_6 *scsi_cmd;
-        struct ccb_scsiio *csio;
+       struct ccb_scsiio *csio;
+       struct cd_softc *softc;
        union ccb *ccb;
+       int cdb_size, param_len;
        int error;
 
+       softc = (struct cd_softc *)periph->softc;
+
        ccb = cdgetccb(periph, /* priority */ 1);
 
        csio = &ccb->csio;
 
        error = 0;
 
-       cam_fill_csio(csio, 
-                     /* retries */ 1, 
-                     /* cbfcnp */ cddone, 
-                     /* flags */ CAM_DIR_OUT,
-                     /* tag_action */ MSG_SIMPLE_Q_TAG,
-                     /* data_ptr */ (u_int8_t *)data,
-                     /* dxfer_len */ sizeof(*data),
-                     /* sense_len */ SSD_FULL_SIZE,
-                     sizeof(struct scsi_mode_select_6),
-                     /* timeout */ 50000);
-
-       scsi_cmd = (struct scsi_mode_select_6 *)&csio->cdb_io.cdb_bytes;
-
-       bzero(scsi_cmd, sizeof(*scsi_cmd));
-       scsi_cmd->opcode = MODE_SELECT;
-       scsi_cmd->byte2 |= SMS_PF;
-       scsi_cmd->length = sizeof(*data) & 0xff;
-       data->header.data_length = 0;
        /*
-        * SONY drives do not allow a mode select with a medium_type
-        * value that has just been returned by a mode sense; use a
-        * medium_type of 0 (Default) instead.
+        * If the data is formatted for the 10 byte version of the mode
+        * select parameter list, we need to use the 10 byte CDB.
+        * Otherwise, we use whatever the stored minimum command size.
         */
-       data->header.medium_type = 0;
+       if (data->cdb_size == 10)
+               cdb_size = data->cdb_size;
+       else
+               cdb_size = softc->minimum_command_size;
+
+       if (cdb_size >= 10) {
+               struct scsi_mode_header_10 *mode_header;
+               u_int32_t data_len;
+
+               mode_header = (struct scsi_mode_header_10 *)data->mode_buf;
+
+               data_len = scsi_2btoul(mode_header->data_length);
+
+               scsi_ulto2b(0, mode_header->data_length);
+               /*
+                * SONY drives do not allow a mode select with a medium_type
+                * value that has just been returned by a mode sense; use a
+                * medium_type of 0 (Default) instead.
+                */
+               mode_header->medium_type = 0;
+
+               /*
+                * Pass back whatever the drive passed to us, plus the size
+                * of the data length field.
+                */
+               param_len = data_len + sizeof(mode_header->data_length);
+
+       } else {
+               struct scsi_mode_header_6 *mode_header;
+
+               mode_header = (struct scsi_mode_header_6 *)data->mode_buf;
+
+               param_len = mode_header->data_length + 1;
+
+               mode_header->data_length = 0;
+               /*
+                * SONY drives do not allow a mode select with a medium_type
+                * value that has just been returned by a mode sense; use a
+                * medium_type of 0 (Default) instead.
+                */
+               mode_header->medium_type = 0;
+       }
+
+       /* Don't say we've got more room than we actually allocated */
+       param_len = min(param_len, data->alloc_len);
+
+       scsi_mode_select_len(csio,
+                            /* retries */ 1,
+                            /* cbfcnp */ cddone,
+                            /* tag_action */ MSG_SIMPLE_Q_TAG,
+                            /* scsi_page_fmt */ 1,
+                            /* save_pages */ 0,
+                            /* param_buf */ data->mode_buf,
+                            /* param_len */ param_len,
+                            /* minimum_cmd_size */ cdb_size,
+                            /* sense_len */ SSD_FULL_SIZE,
+                            /* timeout */ 50000);
+
+       /* See comments in cdgetmode() and cd6byteworkaround(). */
+       STAILQ_INSERT_TAIL(&softc->mode_queue, data, links);
 
        error = cdrunccb(ccb, cderror, /*cam_flags*/0,
                         /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO);
 
        xpt_release_ccb(ccb);
 
-       return(error);
+       STAILQ_REMOVE(&softc->mode_queue, data, cd_mode_params, links);
+
+       return (error);
 }
 
+  
 
 static int 
 cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len)
@@ -3042,7 +3805,7 @@ cdpause(struct cam_periph *periph, u_int32_t go)
 }
 
 static int
-cdstartunit(struct cam_periph *periph)
+cdstartunit(struct cam_periph *periph, int load)
 {
        union ccb *ccb;
        int error;
@@ -3056,7 +3819,7 @@ cdstartunit(struct cam_periph *periph)
                        /* cbfcnp */ cddone,
                        /* tag_action */ MSG_SIMPLE_Q_TAG,
                        /* start */ TRUE,
-                       /* load_eject */ FALSE,
+                       /* load_eject */ load,
                        /* immediate */ FALSE,
                        /* sense_len */ SSD_FULL_SIZE,
                        /* timeout */ 50000);
index 154e26d..f7cced7 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2000 Kenneth D. Merry
+ * Copyright (c) 2000, 2002 Kenneth D. Merry
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,8 @@
  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  *
  *     from: scsi_cd.h,v 1.10 1997/02/22 09:44:28 peter Exp $
- * $FreeBSD: src/sys/cam/scsi/scsi_cd.h,v 1.2.6.2 2002/11/20 00:26:18 njl Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.h,v 1.2 2003/06/17 04:28:19 dillon Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_cd.h,v 1.2.6.3 2003/08/24 03:26:38 ken Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.h,v 1.3 2003/12/29 06:42:10 dillon Exp $
  */
 #ifndef        _SCSI_SCSI_CD_H
 #define _SCSI_SCSI_CD_H 1
@@ -657,38 +657,47 @@ struct scsi_read_cd_cap_data
        u_int8_t length_0;      /* Least significant */
 };
 
-union  cd_pages
+struct cd_audio_page
 {
-       struct  audio_page
+       u_int8_t page_code;
+#define        CD_PAGE_CODE            0x3F
+#define        AUDIO_PAGE              0x0e
+#define        CD_PAGE_PS              0x80
+       u_int8_t param_len;
+       u_int8_t flags;
+#define        CD_PA_SOTC              0x02
+#define        CD_PA_IMMED             0x04
+       u_int8_t unused[2];
+       u_int8_t format_lba;
+#define        CD_PA_FORMAT_LBA        0x0F
+#define        CD_PA_APR_VALID         0x80
+       u_int8_t lb_per_sec[2];
+       struct  port_control
        {
-               u_int8_t page_code;
-#define        CD_PAGE_CODE    0x3F
-#define        AUDIO_PAGE      0x0e
-#define        CD_PAGE_PS      0x80
-               u_int8_t param_len;
-               u_int8_t flags;
-#define                CD_PA_SOTC      0x02
-#define                CD_PA_IMMED     0x04
-               u_int8_t unused[2];
-               u_int8_t format_lba;
-#define                CD_PA_FORMAT_LBA        0x0F
-#define                CD_PA_APR_VALID 0x80
-               u_int8_t lb_per_sec[2];
-               struct  port_control
-               {
-                       u_int8_t channels;
-#define        CHANNEL 0x0F
-#define        CHANNEL_0 1
-#define        CHANNEL_1 2
-#define        CHANNEL_2 4
-#define        CHANNEL_3 8
-#define        LEFT_CHANNEL    CHANNEL_0
-#define        RIGHT_CHANNEL   CHANNEL_1
-                       u_int8_t volume;
-               } port[4];
-#define        LEFT_PORT       0
-#define        RIGHT_PORT      1
-       }audio;
+               u_int8_t channels;
+#define        CHANNEL                 0x0F
+#define        CHANNEL_0               1
+#define        CHANNEL_1               2
+#define        CHANNEL_2               4
+#define        CHANNEL_3               8
+#define        LEFT_CHANNEL            CHANNEL_0
+#define        RIGHT_CHANNEL           CHANNEL_1
+               u_int8_t volume;
+       } port[4];
+#define        LEFT_PORT               0
+#define        RIGHT_PORT              1
+};
+
+union cd_pages
+{
+       struct cd_audio_page audio;
+};
+
+struct cd_mode_data_10
+{
+       struct scsi_mode_header_10 header;
+       struct scsi_mode_blk_desc  blk_desc;
+       union cd_pages page;
 };
 
 struct cd_mode_data
@@ -698,6 +707,20 @@ struct cd_mode_data
        union cd_pages page;
 };
 
+union cd_mode_data_6_10
+{
+       struct cd_mode_data mode_data_6;
+       struct cd_mode_data_10 mode_data_10;
+};
+
+struct cd_mode_params
+{
+       STAILQ_ENTRY(cd_mode_params)    links;
+       int                             cdb_size;
+       int                             alloc_len;
+       u_int8_t                        *mode_buf;
+};
+
 __BEGIN_DECLS
 void scsi_report_key(struct ccb_scsiio *csio, u_int32_t retries,
                     void (*cbfcnp)(struct cam_periph *, union ccb *),
index b9110bf..f7d5fb0 100644 (file)
@@ -25,8 +25,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.36 2003/05/17 21:48:30 njl Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.11 2003/11/29 15:23:33 drhodus Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.46 2003/10/21 22:18:19 thomas Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.12 2003/12/29 06:42:10 dillon Exp $
  */
 
 #ifdef _KERNEL
@@ -41,6 +41,7 @@
 #include <sys/kernel.h>
 #include <sys/buf.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #endif /* _KERNEL */
 
 #include <sys/devicestat.h>
@@ -93,13 +94,15 @@ typedef enum {
        DA_FLAG_NEED_OTAG       = 0x020,
        DA_FLAG_WENT_IDLE       = 0x040,
        DA_FLAG_RETRY_UA        = 0x080,
-       DA_FLAG_OPEN            = 0x100
+       DA_FLAG_OPEN            = 0x100,
+       DA_FLAG_SCTX_INIT       = 0x200
 } da_flags;
 
 typedef enum {
        DA_Q_NONE               = 0x00,
        DA_Q_NO_SYNC_CACHE      = 0x01,
-       DA_Q_NO_6_BYTE          = 0x02
+       DA_Q_NO_6_BYTE          = 0x02,
+       DA_Q_NO_PREVENT         = 0x04
 } da_quirks;
 
 typedef enum {
@@ -136,6 +139,9 @@ struct da_softc {
        struct   disk_params params;
        struct   disk disk;
        union    ccb saved_ccb;
+       struct task             sysctl_task;
+       struct sysctl_ctx_list  sysctl_ctx;
+       struct sysctl_oid       *sysctl_tree;
 };
 
 struct da_quirk_entry {
@@ -148,6 +154,7 @@ static const char microp[] = "MICROP";
 
 static struct da_quirk_entry da_quirk_table[] =
 {
+       /* SPI, FC devices */
        {
                /*
                 * Fujitsu M2513A MO drives.
@@ -224,14 +231,12 @@ static struct da_quirk_entry da_quirk_table[] =
                /*quirks*/ DA_Q_NO_6_BYTE
        },
        {
-               /*
-                * See above.
-                */
+               /* See above. */
                {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
                /*quirks*/ DA_Q_NO_6_BYTE
        },
-
-       /* Below a list of quirks for USB devices supported by umass. */
+       /* XXX USB floppy quirks temporarily enabled for 4.9R */
+       /* USB floppy devices supported by umass(4) */
        {
                /*
                 * This USB floppy drive uses the UFI command set. This
@@ -240,13 +245,32 @@ static struct da_quirk_entry da_quirk_table[] =
                 * not support sync cache (0x35).
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "Y-E DATA", "USB-FDU", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /* Another USB floppy */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "MATSHITA", "FDD CF-VFDU*","*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
+       },
+       {
+               /*
+                * The vendor, product and version strings coming from the
+                * controller are null terminated instead of being padded with
+                * spaces. The trailing wildcard character '*' is required.
+                */
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "SMSC*", "USB FDC*","*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
+       },
+       {
+               /*
+                * SmartDisk (Mitsumi) USB floppy drive
+                * PR: kern/50226
+                */
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "MITSUMI", "USB FDD", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
+#ifdef DA_OLD_QUIRKS
+       /* USB mass storage devices supported by umass(4) */
        {
                /*
                 * Sony Memory Stick adapter MSAC-US1 and
@@ -254,7 +278,7 @@ static struct da_quirk_entry da_quirk_table[] =
                 * Make all sony MS* products use this quirk.
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "MS*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -262,32 +286,23 @@ static struct da_quirk_entry da_quirk_table[] =
                 * of PalmOS PDA's
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "CLIE*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * Sony DSC cameras (DSC-S30, DSC-S50, DSC-S70)
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
-                * Maxtor 3000LE USB Drive
+                * Intelligent Stick USB disk-on-key
+                * PR: kern/53005
                 */
-               {T_DIRECT, SIP_MEDIA_FIXED, "MAXTOR*", "K040H2*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB Card",
+                "IntelligentStick*", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
-                * LaCie USB drive, among others
+                * Sony DSC cameras (DSC-S30, DSC-S50, DSC-S70)
                 */
-               {T_DIRECT, SIP_MEDIA_FIXED, "Maxtor*", "D080H4*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "MCF3064AP", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -295,44 +310,28 @@ static struct da_quirk_entry da_quirk_table[] =
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "eUSB    Compact*",
                 "Compact Flash*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * The vendor, product and version strings coming from the
-                * controller are null terminated instead of being padded with
-                * spaces. The trailing wildcard character '*' is required.
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "SMSC*", "USB FDC*","*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
                 * Olympus digital cameras (C-3040ZOOM, C-2040ZOOM, C-1)
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "C-*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * Olympus digital cameras (D-370)
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "D-*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
                 * Olympus digital cameras (E-100RS, E-10).
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "E-*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
                 * KingByte Pen Drives
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "NO BRAND", "PEN DRIVE", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -340,57 +339,14 @@ static struct da_quirk_entry da_quirk_table[] =
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJIFILMUSB-DRIVEUNIT",
                 "USB-DRIVEUNIT", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
-       {
-               /*
-                * Nikon Coolpix E775/E995 Cameras 
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "NIKON", "NIKON DSC E*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Nikon Coolpix E885 Camera
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "Nikon", "Digital Camera", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * SimpleTech FlashLink UCF-100
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "OEI-USB", "CompactFlash", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Minolta Dimage 2330
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "MINOLTA", "DIMAGE 2330*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
        {
                /*
                 * Minolta Dimage E203
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "MINOLTA", "DiMAGE E203", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * DIVA USB Mp3 Player.
-                * PR: kern/33638
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "DIVA USB", "Media Reader","*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Daisy Technology PhotoClip USB Camera
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "Digital", "World   DMC","*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -398,7 +354,7 @@ static struct da_quirk_entry da_quirk_table[] =
                 * PR: kern/43627
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "Apacer", "HandyDrive", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -406,23 +362,7 @@ static struct da_quirk_entry da_quirk_table[] =
                 * PR: kern/43580
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "ZORAN", "COACH", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * HP 315 Digital Camera
-                * PR: kern/41010
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "HP", "USB CAMERA", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Fujitsu-Siemens Memorybird pen drive
-                * PR: kern/34712
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "Fujitsu", "Memorybird", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
@@ -430,79 +370,33 @@ static struct da_quirk_entry da_quirk_table[] =
                 * PR: kern/46386
                 */
                {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Storage Media", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
-       },
-       {
-               /*
-                * Lexar Media Jumpdrive
-                * PR: kern/47006
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "LEXAR", "DIGITAL FILM", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "LEXAR", "JUMPDRIVE", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Pentax USB Optio 230 camera
-                * PR: kern/46369
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE,
-                "PENTAX", "DIGITAL_CAMERA", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * Casio QV-R3 USB camera (uses Pentax chip as above)
-                * PR: kern/46545
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE,
-                "CASIO", "DIGITAL_CAMERA", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       },
-       {
-               /*
-                * M-Systems DiskOnKey USB flash key
-                * PR: kern/47793
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "M-Sys", "DiskOnKey", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
+#endif /* DA_OLD_QUIRKS */
        {
                /*
-                * SanDisk ImageMate (I, II, ...) compact flash
-                * PR: kern/47877
+                * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
+                * PR: kern/51675
                 */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk", "ImageMate*", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
-                * Feiya "slider" dual-slot flash reader. The vendor field
-                * is blank so this may match other devices.
-                * PR: kern/50020
+                * Jungsoft NEXDISK USB flash key
+                * PR: kern/54737
                 */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "", "USB CARD READER", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE
        },
        {
                /*
-                * SmartDisk (Mitsumi) USB floppy drive
-                * PR: kern/50226
+                * Creative Nomad MUVO mp3 player (USB)
+                * PR: kern/53094
                 */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "MITSUMI", "USB FDD", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+               {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
+               /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
        },
-       {
-               /*
-                * OTi USB Flash Key
-                * PR: kern/51825
-                */
-               {T_DIRECT, SIP_MEDIA_REMOVABLE, "OTi", "Flash Disk", "*"},
-               /*quirks*/ DA_Q_NO_6_BYTE
-       }
 };
 
 static d_open_t        daopen;
@@ -513,6 +407,7 @@ static      d_dump_t        dadump;
 static periph_init_t   dainit;
 static void            daasync(void *callback_arg, u_int32_t code,
                                struct cam_path *path, void *arg);
+static int             dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
 static periph_ctor_t   daregister;
 static periph_dtor_t   dacleanup;
 static periph_start_t  dastart;
@@ -537,17 +432,16 @@ static void               dashutdown(void *arg, int howto);
 
 static int da_retry_count = DA_DEFAULT_RETRY;
 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
-static int da_no_6_byte = 0;
 
 SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
 SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
             "CAM Direct Access Disk driver");
 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
            &da_retry_count, 0, "Normal I/O retry count");
+TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
-SYSCTL_INT(_kern_cam_da, OID_AUTO, no_6_byte, CTLFLAG_RW,
-           &da_no_6_byte, 0, "No 6 bytes commands");
+TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
 
 /*
  * DA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -701,9 +595,9 @@ daopen(dev_t dev, int flags, int fmt, struct thread *td)
                                  * softc->params.secs_per_track;
                label->d_secperunit = softc->params.sectors;
 
-               if (((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0)) {
+               if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
+                   (softc->quirks & DA_Q_NO_PREVENT) == 0)
                        daprevent(periph, PR_PREVENT);
-               }
        
                /*
                 * Check to see whether or not the blocksize is set yet.
@@ -717,9 +611,9 @@ daopen(dev_t dev, int flags, int fmt, struct thread *td)
        }
        
        if (error != 0) {
-               if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
+               if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
+                   (softc->quirks & DA_Q_NO_PREVENT) == 0)
                        daprevent(periph, PR_ALLOW);
-               }
                softc->flags &= ~DA_FLAG_OPEN;
                cam_periph_release(periph);
        }
@@ -797,7 +691,8 @@ daclose(dev_t dev, int flag, int fmt, struct thread *td)
        }
 
        if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
-               daprevent(periph, PR_ALLOW);
+               if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
+                       daprevent(periph, PR_ALLOW);
                /*
                 * If we've got removeable media, mark the blocksize as
                 * unavailable, since it could change when new media is
@@ -925,7 +820,7 @@ dadump(dev_t dev)
        u_int       num;        /* number of sectors to write */
        u_int       blknum;
        long        blkcnt;
-       vm_offset_t addr;       
+       vm_paddr_t  addr;       
        struct      ccb_scsiio csio;
        int         dumppages = MAXDUMPPGS;
        int         error;
@@ -960,7 +855,7 @@ dadump(dev_t dev)
                        dumppages = num / blkcnt;
 
                for (i = 0; i < dumppages; ++i) {
-                       vm_offset_t a = addr + (i * PAGE_SIZE);
+                       vm_paddr_t a = addr + (i * PAGE_SIZE);
                        if (is_physical_memory(a))
                                va = pmap_kenter_temporary(trunc_page(a), i);
                        else
@@ -1160,6 +1055,14 @@ dacleanup(struct cam_periph *periph)
        cam_extend_release(daperiphs, periph->unit_number);
        xpt_print_path(periph->path);
        printf("removing device entry\n");
+       /*
+        * If we can't free the sysctl tree, oh well...
+        */
+       if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
+           && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
+               xpt_print_path(periph->path);
+               printf("can't remove sysctl context\n");
+       }
        if (softc->disk.d_dev) {
                disk_destroy(&softc->disk);
        }
@@ -1229,13 +1132,80 @@ daasync(void *callback_arg, u_int32_t code,
        }
 }
 
+static void
+dasysctlinit(void *context, int pending)
+{
+       struct cam_periph *periph;
+       struct da_softc *softc;
+       char tmpstr[80], tmpstr2[80];
+
+       periph = (struct cam_periph *)context;
+       softc = (struct da_softc *)periph->softc;
+
+       snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
+       snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
+
+       sysctl_ctx_init(&softc->sysctl_ctx);
+       softc->flags |= DA_FLAG_SCTX_INIT;
+       softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
+               SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
+               CTLFLAG_RD, 0, tmpstr);
+       if (softc->sysctl_tree == NULL) {
+               printf("dasysctlinit: unable to allocate sysctl tree\n");
+               return;
+       }
+
+       /*
+        * 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_cmd_size, 0, dacmdsizesysctl, "I",
+               "Minimum CDB size");
+}
+
+static int
+dacmdsizesysctl(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);
+
+       /*
+        * Acceptable values here are 6, 10 or 12.  It's possible we may
+        * support a 16 byte minimum command size in the future, since
+        * there are now READ(16) and WRITE(16) commands defined in the
+        * SBC-2 spec.
+        */
+       if (value < 6)
+               value = 6;
+       else if ((value > 6)
+             && (value <= 10))
+               value = 10;
+       else if (value > 10)
+               value = 12;
+
+       *(int *)arg1 = value;
+
+       return (0);
+}
+
 static cam_status
 daregister(struct cam_periph *periph, void *arg)
 {
        int s;
        struct da_softc *softc;
        struct ccb_setasync csa;
+       struct ccb_pathinq cpi;
        struct ccb_getdev *cgd;
+       char tmpstr[80];
        caddr_t match;
 
        cgd = (struct ccb_getdev *)arg;
@@ -1283,11 +1253,41 @@ daregister(struct cam_periph *periph, void *arg)
        else
                softc->quirks = DA_Q_NONE;
 
+       TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
+
+       /* Check if the SIM does not want 6 byte commands */
+       xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+       cpi.ccb_h.func_code = XPT_PATH_INQ;
+       xpt_action((union ccb *)&cpi);
+       if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
+               softc->quirks |= DA_Q_NO_6_BYTE;
+
+       /*
+        * RBC devices don't have to support READ(6), only READ(10).
+        */
        if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
                softc->minimum_cmd_size = 10;
        else
                softc->minimum_cmd_size = 6;
 
+       /*
+        * Load the user's default, if any.
+        */
+       snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
+                periph->unit_number);
+       TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
+
+       /*
+        * 6, 10 and 12 are the currently permissible values.
+        */
+       if (softc->minimum_cmd_size < 6)
+               softc->minimum_cmd_size = 6;
+       else if ((softc->minimum_cmd_size > 6)
+             && (softc->minimum_cmd_size <= 10))
+               softc->minimum_cmd_size = 10;
+       else if (softc->minimum_cmd_size > 12)
+               softc->minimum_cmd_size = 12;
+
        /*
         * Block our timeout handler while we
         * add this softc to the dev list.
@@ -1387,8 +1387,6 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
                        } else {
                                tag_code = MSG_SIMPLE_Q_TAG;
                        }
-                       if (da_no_6_byte && softc->minimum_cmd_size == 6)
-                               softc->minimum_cmd_size = 10;
                        scsi_read_write(&start_ccb->csio,
                                        /*retries*/da_retry_count,
                                        dadone,
@@ -1580,15 +1578,8 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
                        } else {
                                bp->b_resid = csio->resid;
                                bp->b_error = 0;
-                               if (bp->b_resid != 0) {
-                                       /* Short transfer ??? */
-#if 0
-                                       if (cmd6workaround(done_ccb) 
-                                                               == ERESTART)
-                                               return;
-#endif
+                               if (bp->b_resid != 0)
                                        bp->b_flags |= B_ERROR;
-                               }
                        }
                        if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
                                cam_release_devq(done_ccb->ccb_h.path,
@@ -1598,14 +1589,8 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
                                                 /*getcount_only*/0);
                } else {
                        bp->b_resid = csio->resid;
-                       if (csio->resid > 0) {
-                               /* Short transfer ??? */
-#if 0 /* XXX most of the broken umass devices need this ad-hoc work around */
-                               if (cmd6workaround(done_ccb) == ERESTART)
-                                       return;
-#endif
+                       if (csio->resid > 0)
                                bp->b_flags |= B_ERROR;
-                       }
                }
 
                /*
@@ -1731,8 +1716,14 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
                        }
                }
                free(rdcap, M_TEMP);
-               if (announce_buf[0] != '\0')
+               if (announce_buf[0] != '\0') {
                        xpt_announce_periph(periph, announce_buf);
+                       /*
+                        * Create our sysctl variables, now that we know
+                        * we have successfully attached.
+                        */
+                       taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
+               }
                softc->state = DA_STATE_NORMAL;         
                /*
                 * Since our peripheral may be invalidated by an error
@@ -1766,7 +1757,7 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
 {
        struct da_softc   *softc;
        struct cam_periph *periph;
-       int error, sense_key, error_code, asc, ascq;
+       int error;
 
        periph = xpt_path_periph(ccb->ccb_h.path);
        softc = (struct da_softc *)periph->softc;
@@ -1776,8 +1767,16 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
         * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
         */
        error = 0;
-       if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR
-         && ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) {
+       if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
+               error = cmd6workaround(ccb);
+       } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
+                  CAM_SCSI_STATUS_ERROR)
+        && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
+        && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
+        && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
+        && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
+               int sense_key, error_code, asc, ascq;
+
                scsi_extract_sense(&ccb->csio.sense_data,
                                   &error_code, &sense_key, &asc, &ascq);
                if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
index c02e733..3d57a78 100644 (file)
@@ -1,7 +1,8 @@
-/*     $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.4 2001/12/17 13:30:20 non Exp $   */
-/*     $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.4 2003/08/27 11:42:33 rob Exp $ */
-/*     $NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ */
-/*     $NetBSD$        */
+/*
+ * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.5 2003/12/29 06:42:10 dillon Exp $
+ * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $
+ */
 
 #define        SCSI_LOW_STATICS
 #define        SCSI_LOW_DEBUG
@@ -1807,7 +1808,7 @@ scsi_low_alloc_li(ti, lun, alloc)
 
        li = SCSI_LOW_MALLOC(ti->ti_lunsize);
        if (li == NULL)
-               panic("no lun info mem\n");
+               panic("no lun info mem");
 
        SCSI_LOW_BZERO(li, ti->ti_lunsize);
        li->li_lun = lun;
@@ -1849,7 +1850,7 @@ scsi_low_alloc_ti(slp, targ)
 
        ti = SCSI_LOW_MALLOC(slp->sl_targsize);
        if (ti == NULL)
-               panic("%s short of memory\n", slp->sl_xname);
+               panic("%s short of memory", slp->sl_xname);
 
        SCSI_LOW_BZERO(ti, slp->sl_targsize);
        ti->ti_id = targ;
@@ -1956,7 +1957,7 @@ scsi_low_timeout_check(slp)
                        cb->ccb_flags |= CCB_NORETRY;
                        cb->ccb_error |= SELTIMEOUTIO;
                        if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
-                               panic("%s: ccb not finished\n", slp->sl_xname);
+                               panic("%s: ccb not finished", slp->sl_xname);
                }
 
                if (slp->sl_Tnexus == NULL)
@@ -2080,7 +2081,7 @@ scsi_low_abort_ccb(slp, cb)
        else if ((cb->ccb_flags & CCB_DISCQ) != 0)
        {
                if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
-                       panic("%s: revoked ccb done\n", slp->sl_xname);
+                       panic("%s: revoked ccb done", slp->sl_xname);
 
                cb->ccb_flags |= CCB_STARTQ;
                TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
@@ -2091,7 +2092,7 @@ scsi_low_abort_ccb(slp, cb)
        else
        {
                if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
-                       panic("%s: revoked ccb retried\n", slp->sl_xname);
+                       panic("%s: revoked ccb retried", slp->sl_xname);
        }
        return 0;
 }
@@ -2116,7 +2117,7 @@ scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
 #endif /* SCSI_LOW_INTERFACE_CAM */
 
        if (slp->sl_osdep_fp == NULL)
-               panic("scsi_low: interface not spcified\n");
+               panic("scsi_low: interface not spcified");
 
        if (ntargs > SCSI_LOW_NTARGETS)
        {
@@ -2386,7 +2387,7 @@ scsi_low_setup_start(slp, ti, li, cb)
                return SCSI_LOW_START_QTAG;
 
        default:
-               panic("%s: no setup phase\n", slp->sl_xname);
+               panic("%s: no setup phase", slp->sl_xname);
        }
 
        return SCSI_LOW_START_NO_QTAG;
@@ -2442,7 +2443,7 @@ scsi_low_start(slp)
        if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
        {
                scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
-               panic("%s: inconsistent\n", slp->sl_xname);
+               panic("%s: inconsistent", slp->sl_xname);
        }
 #endif /* SCSI_LOW_DIAGNOSTIC */
 
@@ -3775,7 +3776,7 @@ cmd_link_start:
        cb->ccb_tag = SCSI_LOW_UNKTAG;
        cb->ccb_otag = SCSI_LOW_UNKTAG;
        if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
-               panic("%s: linked ccb retried\n", slp->sl_xname);
+               panic("%s: linked ccb retried", slp->sl_xname);
 
        slp->sl_Qnexus = ncb;
        slp->sl_ph_count = 0;
@@ -4445,7 +4446,7 @@ scsi_low_revoke_ccb(slp, cb, fdone)
        if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 
            (CCB_STARTQ | CCB_DISCQ))
        {
-               panic("%s: ccb in both queue\n", slp->sl_xname);
+               panic("%s: ccb in both queue", slp->sl_xname);
        }
 #endif /* SCSI_LOW_DIAGNOSTIC */
 
@@ -4472,7 +4473,7 @@ scsi_low_revoke_ccb(slp, cb, fdone)
                cb->ccb_error |= FATALIO;
                cb->ccb_flags &= ~CCB_AUTOSENSE;
                if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
-                       panic("%s: done ccb retried\n", slp->sl_xname);
+                       panic("%s: done ccb retried", slp->sl_xname);
                return NULL;
        }
        else
index 7e6aef6..8fb2e43 100644 (file)
@@ -25,8 +25,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_targ_bh.c,v 1.4.2.5 2001/07/30 00:15:22 mjacob Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_targ_bh.c,v 1.4 2003/08/07 21:16:45 dillon Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_targ_bh.c,v 1.4.2.6 2003/11/14 11:31:25 simokawa Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_targ_bh.c,v 1.5 2003/12/29 06:42:10 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -167,7 +167,7 @@ targbhinit(void)
 
                xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
                csa.ccb_h.func_code = XPT_SASYNC_CB;
-               csa.event_enable = AC_PATH_REGISTERED;
+               csa.event_enable = AC_PATH_REGISTERED | AC_PATH_DEREGISTERED;
                csa.callback = targbhasync;
                csa.callback_arg = NULL;
                xpt_action((union ccb *)&csa);
@@ -185,55 +185,56 @@ static void
 targbhasync(void *callback_arg, u_int32_t code,
            struct cam_path *path, void *arg)
 {
-       struct cam_periph *periph;
+       struct cam_path *new_path;
+       struct ccb_pathinq *cpi;
+       path_id_t bus_path_id;
+       cam_status status;
+
+       cpi = (struct ccb_pathinq *)arg;
+       if (code == AC_PATH_REGISTERED)
+               bus_path_id = cpi->ccb_h.path_id;
+       else
+               bus_path_id = xpt_path_path_id(path);
+       /*
+        * Allocate a peripheral instance for
+        * this target instance.
+        */
+       status = xpt_create_path(&new_path, NULL,
+                                bus_path_id,
+                                CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
+       if (status != CAM_REQ_CMP) {
+               printf("targbhasync: Unable to create path "
+                       "due to status 0x%x\n", status);
+               return;
+       }
 
-       periph = (struct cam_periph *)callback_arg;
        switch (code) {
        case AC_PATH_REGISTERED:
        {
-               struct ccb_pathinq *cpi;
-               struct cam_path *new_path;
-               cam_status status;
-               cpi = (struct ccb_pathinq *)arg;
-
                /* Only attach to controllers that support target mode */
                if ((cpi->target_sprt & PIT_PROCESSOR) == 0)
                        break;
 
-               /*
-                * Allocate a peripheral instance for
-                * this target instance.
-                */
-               status = xpt_create_path(&new_path, NULL,
-                                        xpt_path_path_id(path),
-                                        CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
-               if (status != CAM_REQ_CMP) {
-                       printf("targbhasync: Unable to create path "
-                               "due to status 0x%x\n", status);
-                       break;
-               }
                status = cam_periph_alloc(targbhctor, NULL, targbhdtor,
                                          targbhstart,
                                          "targbh", CAM_PERIPH_BIO,
                                          new_path, targbhasync,
                                          AC_PATH_REGISTERED,
                                          cpi);
-               xpt_free_path(new_path);
-               if (status != CAM_REQ_CMP
-                && status != CAM_REQ_INPROG)
-                       printf("targbhasync: Unable to allocate new periph "
-                              "due to status 0x%x\n", status);
                break;
        }
        case AC_PATH_DEREGISTERED:
        {
-               targbhdislun(periph);
+               struct cam_periph *periph;
+
+               if ((periph = cam_periph_find(new_path, "targbh")) != NULL)
+                       cam_periph_invalidate(periph);
                break;
        }
        default:
                break;
        }
+       xpt_free_path(new_path);
 }
 
 /* Attempt to enable our lun */
@@ -441,13 +442,15 @@ targbhdtor(struct cam_periph *periph)
        targbhdislun(periph);
 
        switch (softc->init_level) {
-       default:
-               /* FALLTHROUGH */
+       case 0:
+               panic("targdtor - impossible init level");;
        case 1:
+               /* FALLTHROUGH */
+       default:
+               /* XXX Wait for callback of targbhdislun() */
+               tsleep(softc, PRIBIO, "targbh", hz/2);
                free(softc, M_DEVBUF);
                break;
-       case 0:
-               panic("targdtor - impossible init level");;
        }
 }
 
index cd4995c..b379495 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: uhci.c,v 1.80 2000/01/19 01:16:38 augustss Exp $       */
-/*     $FreeBSD: src/sys/dev/usb/uhci.c,v 1.40.2.10 2003/01/12 02:13:58 iedowse Exp $  */
-/*     $DragonFly: src/sys/bus/usb/uhci.c,v 1.6 2003/08/07 21:16:47 dillon Exp $       */
+/*
+ * $NetBSD: uhci.c,v 1.80 2000/01/19 01:16:38 augustss Exp $
+ * $FreeBSD: src/sys/dev/usb/uhci.c,v 1.40.2.11 2003/08/22 06:59:11 njl Exp $
+ * $DragonFly: src/sys/bus/usb/uhci.c,v 1.7 2003/12/29 06:42:12 dillon Exp $
+ */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -1203,11 +1205,10 @@ uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
        for (; timo >= 0; timo--) {
                usb_delay_ms(&sc->sc_bus, 1);
                DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
-               if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
+               if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
                        uhci_intr(sc);
-                       if (xfer->status != USBD_IN_PROGRESS)
-                               return;
-               }
+               if (xfer->status != USBD_IN_PROGRESS)
+                       return;
        }
 
        /* Timeout */
index e205fcd..4af2b9c 100644 (file)
@@ -34,8 +34,8 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.42 2003/05/11 00:12:29 murray Exp $
- * $DragonFly: src/sys/bus/usb/Attic/usbdevs,v 1.3 2003/08/15 01:19:54 dillon Exp $
+ * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.50 2003/12/22 07:52:56 sanpei Exp $
+ * $DragonFly: src/sys/bus/usb/Attic/usbdevs,v 1.4 2003/12/29 06:42:12 dillon Exp $
  */
 
 /*
@@ -116,6 +116,7 @@ vendor LUCENT               0x047e  Lucent
 vendor STMICRO         0x0483  STMicroelectronics
 vendor YAMAHA          0x0499  YAMAHA
 vendor COMPAQ          0x049f  Compaq Computers
+vendor HITACHI         0x04a4  Hitachi, Ltd.
 vendor ACERP           0x04a5  Acer Peripherals
 vendor VISIONEER       0x04a7  Visioneer
 vendor CANON           0x04a9  Canon
@@ -146,7 +147,9 @@ vendor ALTEC                0x04d2  Altec Lansing Technologies
 vendor PANASONIC       0x04da  Panasonic (Matsushita)
 vendor IIYAMA          0x04e1  Iiyama
 vendor SHUTTLE         0x04e6  Shuttle Technology
+vendor SAMSUNG         0x04e8  Samsung Electronics
 vendor ANNABOOKS       0x04ed  Annabooks
+vendor JVC             0x04f1  JVC
 vendor CHICONY         0x04f2  Chicony Electronics
 vendor BROTHER         0x04f9  Brother Industries
 vendor DALLAS          0x04fa  Dallas Semiconductor
@@ -253,9 +256,10 @@ vendor MCT         0x0711  MCT
 vendor DIGITALSTREAM   0x074e  Digital Stream
 vendor AUREAL          0x0755  Aureal Semiconductor
 vendor MIDIMAN         0x0763  Midiman
-vendor LINKSYS2                0x077b  Linksys 
+vendor LINKSYS2                0x077b  Linksys
 vendor GRIFFIN         0x077d  Griffin Technology
 vendor SANDISK         0x0781  SanDisk Corp
+vendor LOGITEC         0x0789  Logitec Corp
 vendor BRIMAX          0x078e  Brimax
 vendor AXIS            0x0792  Axis Communications
 vendor ABL             0x0794  ABL Electronics
@@ -267,6 +271,7 @@ vendor ADMTEK               0x07a6  ADMtek
 vendor COREGA          0x07aa  Corega
 vendor FREECOM         0x07ab  Freecom
 vendor MICROTECH       0x07af  Microtech
+vendor GENERALINSTMNTS 0x07b2  General Instruments (Motorola)
 vendor OLYMPUS         0x07b4  Olympus
 vendor ABOCOM          0x07b8  AboCom Systems
 vendor KEISOKUGIKEN    0x07c1  Keisokugiken
@@ -285,6 +290,7 @@ vendor BROADLOGIC   0x0827  BroadLogic
 vendor HANDSPRING      0x082d  Handspring
 vendor ACTIONSTAR      0x0835  Action Star Enterprise
 vendor PALM            0x0830  Palm Computing
+vendor SOURCENEXT      0x0833  SOURCENEXT
 vendor ACCTON          0x083a  Accton Technology
 vendor DIAMOND         0x0841  Diamond
 vendor NETGEAR         0x0846  BayNETGEAR
@@ -307,6 +313,7 @@ vendor AUTHENTEC    0x08ff  AuthenTec
 vendor ALATION         0x0910  Alation Systems
 vendor GOHUBS          0x0921  GoHubs
 vendor BIOMETRIC       0x0929  American Biometric Company
+vendor TOSHIBA         0x0930  Toshiba Corporation
 vendor YANO            0x094f  Yano
 vendor KINGSTON                0x0951  Kingston Technology
 vendor BLUEWATER       0x0956  BlueWater Systems
@@ -314,6 +321,7 @@ vendor AGILENT              0x0957  Agilent Technologies
 vendor PORTSMITH       0x095a  Portsmith
 vendor ADIRONDACK      0x0976  Adirondack Wire & Cable
 vendor BECKHOFF                0x0978  Beckhoff
+vendor INTERSIL                0x09aa  Intersil
 vendor ALTIUS          0x09b3  Altius Solutions
 vendor ARRIS           0x09c1  Arris Interactive
 vendor ACTIVCARD       0x09c3  ACTIVCARD
@@ -333,6 +341,7 @@ vendor GREENHOUSE   0x0a6b  GREENHOUSE
 vendor GEOCAST         0x0a79  Geocast Network Systems
 vendor NEODIO          0x0aec  Neodio
 vendor TODOS           0x0b0c  Todos Data System
+vendor HAL             0x0b41  HAL Corporation
 vendor NEC2            0x0b62  NEC
 vendor ATI2            0x0b6f  ATI
 vendor ASIX            0x0b95  ASIX Electronics
@@ -340,6 +349,9 @@ vendor REALTEK              0x0bda  RealTek
 vendor AGATE           0x0c08  Agate Technologies
 vendor DMI             0x0c0b  DMI
 vendor LUWEN           0x0c76  Luwen
+vendor SMC3            0x0d5c  Standard Microsystems
+vendor PNY             0x0d7d  PNY
+vendor HAWKING         0x0e66  Hawking Technologies
 vendor MOTOROLA                0x1063  Motorola
 vendor PLX             0x10b5  PLX
 vendor ASANTE          0x10bd  Asante
@@ -355,6 +367,7 @@ vendor INSIDEOUT    0x1608  Inside Out Networks
 vendor ENTREGA         0x1645  Entrega
 vendor ACTIONTEC       0x1668  Actiontec Electronics
 vendor DLINK           0x2001  D-Link
+vendor VIDZMEDIA       0x3275  VidzMedia Pte Ltd
 vendor DAISY           0x3579  Daisy Technology
 vendor INTEL           0x8086  Intel
 vendor HP2             0xf003  Hewlett Packard
@@ -403,6 +416,9 @@ product ACERP ACERSCAN_620U 0x2060  Acerscan 620U
 product ACTIVEWIRE IOBOARD     0x0100  I/O Board
 product ACTIVEWIRE IOBOARD_FW1 0x0101  I/O Board, rev. 1 firmware
 
+/* Actiontec, Inc. products */
+product ACTIONTEC UAT1 0x7605  UAT1 Wireless Ethernet adapter
+
 /* ADMtek products */
 product ADMTEK PEGASUS         0x0986  AN986 USB Ethernet adapter
 product ADMTEK PEGASUSII       0x8511  AN8511 USB Ethernet adapter
@@ -456,6 +472,7 @@ product APPLE SPEAKERS              0x1101  Speakers
 
 /* Asahi Optical products */
 product ASAHIOPTICAL OPTIO230  0x0004  Digital camera
+product ASAHIOPTICAL OPTIO330  0x0006  Digital camera
 
 /* ASIX Electronics products */
 product ASIX AX88172           0x1720  USB 2.0 10/100 ethernet controller
@@ -468,6 +485,7 @@ product ATEN UC232A         0x2008  Serial adapter
 /* Atmel Comp. products */
 product ATMEL UHB124           0x3301  UHB124 hub
 product ATMEL DWL120           0x7602  DWL-120 Wireless adapter
+product ATMEL BW002            0x7605  BW002 Wireless adapter
 
 /* Avision products */
 product AVISION 1200U          0x0268  1200U scanner
@@ -479,6 +497,7 @@ product BELKIN USB2LAN              0x0121  USB to LAN Converter
 product BELKIN F5U103          0x0103  F5U103 Serial adapter
 product BELKIN F5U109          0x0109  F5U109 Serial adapter
 product BELKIN F5U120          0x1203  F5U120-PC Hub
+product BELKIN F5U208          0x0208  F5U208 VideoBus II
 
 /* Billionton products */
 product BILLIONTON USB100      0x0986  USB100N 10/100 FastEthernet Adapter
@@ -493,9 +512,11 @@ product BROTHER HL1050             0x0002  HL-1050 laser printer
 product BTC BTC7932            0x6782  Keyboard with mouse port
 
 /* Canon, Inc. products */
-product CANON N656U            0x2206  CANOSCAN N656U
+product CANON N656U            0x2206  CanoScan N656U
+product CANON N1240U           0x220e  CanoScan N1240U
 product CANON S10              0x3041  PowerShot S10
 product CANON S100             0x3045  PowerShot S100
+product CANON S200             0x3065  PowerShot S200
 
 /* CATC products */
 product CATC NETMATE           0x000a  Netmate ethernet adapter
@@ -538,6 +559,7 @@ product CTX EX1300          0x9999  Ex1300 hub
 product CYPRESS MOUSE          0x0001  mouse
 product CYPRESS THERMO         0x0002  thermometer
 product CYPRESS FMRADIO                0x1002  FM Radio
+product CYPRESS SLIM_HUB       0x6560  Slim Hub
 
 /* Daisy Technology products */
 product DAISY DMC              0x6901  USB MultiMedia Reader
@@ -607,8 +629,10 @@ product EPSON 1600         0x0107  Expression 1600 scanner
 product EPSON 1640             0x010a  Perfection 1640SU scanner
 product EPSON 1240             0x010b  Perfection 1240U / 1240Photo scanner
 product EPSON 640U             0x010c  Perfection 640U scanner
+product EPSON 1250             0x010f  Perfection 1250U / 1250Photo scanner
 product EPSON 1650             0x0110  Perfection 1650 scanner
 product EPSON GT9700F          0x0112  GT-9700F scanner
+product EPSON GT9300UF         0x011b  GT-9300UF scanner
 product EPSON 1260             0x011d  Perfection 1260 scanner
 product EPSON 1660             0x011e  Perfection 1660 scanner
 
@@ -643,11 +667,17 @@ product FUJIPHOTO MASS0100        0x0100  Mass Storage
 /* Fujitsu protducts */
 product        FUJITSU AH_F401U        0x105b  AH-F401U Air H device
 
+/* General Instruments (Motorola) products */
+product GENERALINSTMNTS SB5100 0x5100  SURFboard SB5100 Cable modem
+
 /* Genesys Logic products */
 product        GENESYS GL650           0x0604  GL650 Hub
 product        GENESYS GL641USB        0x0700  GL641USB CompactFlash Card Reader
 product        GENESYS GL641USB2IDE    0x0702  GL641USB USB-IDE Bridge
 
+/* HAL Corporation products */
+product HAL IMR001             0x0011  Crossam2+USB IR commander
+
 /* Hagiwara products */
 product HAGIWARA FGSM          0x0002  FlashGate SmartMedia Card Reader
 product HAGIWARA FGCF          0x0003  FlashGate CompactFlash Card Reader
@@ -655,10 +685,17 @@ product HAGIWARA FG               0x0005  FlashGate
 
 /* Handspring, Inc. */
 product HANDSPRING VISOR       0x0100  Handspring Visor
+product HANDSPRING TREO                0x0200  Handspring Treo
 
 /* Hauppauge Computer Works */
 product HAUPPAUGE WINTV_USB_FM 0x4d12  WinTV USB FM
 
+/* Hawking Technologies products */
+product        HAWKING UF100           0x400c  10/100 USB Ethernet
+
+/* Hitachi, Ltd. products */
+product HITACHI DVDCAM_USB     0x001e  DVDCAM USB HS Interface
+
 /* HP products */
 product HP 895C                        0x0004  DeskJet 895C
 product HP 4100C               0x0101  Scanjet 4100C
@@ -684,12 +721,14 @@ product HP 6300C          0x0601  Scanjet 6300C
 product HP 840C                        0x0604  DeskJet 840c
 product HP 2200C               0x0605  ScanJet 2200C
 product HP 5300C               0x0701  Scanjet 5300C
+product HP 4400C               0x0705  Scanjet 4400C
 product HP 970CSE              0x1004  Deskjet 970Cse
 product HP 5400C               0x1005  Scanjet 5400C
 product HP 930C                        0x1204  DeskJet 930c
 product HP P2000U              0x1801  Inkjet P-2000U
 product HP 640C                        0x2004  DeskJet 640c
 product HP P1100               0x3102  Photosmart P1100
+product HP HN210E              0x811c  Ethernet HN210E
 
 /* HP products */
 product HP2 C500               0x6002  PhotoSmart C500
@@ -711,6 +750,9 @@ product INSYSTEM USBCABLE   0x081a  USB cable
 product INTEL EASYPC_CAMERA    0x0110  Easy PC Camera
 product INTEL TESTBOARD                0x9890  82930 test board
 
+/* Intersil products */
+product INTERSIL PRISM_2X      0x3642  Prism2.x or Atmel WLAN
+
 /* I/O DATA products */
 product IODATA USBETT          0x0901  USB ETT
 product IODATA USBETTX         0x0904  USB ETTX
@@ -721,6 +763,9 @@ product     IODATA USBRSAQ          0x0a03  USB serial adapter USB-RSAQ1
 product IOMEGA ZIP100          0x0001  Zip 100
 product IOMEGA ZIP250          0x0030  Zip 250
 
+/* JVC products */
+product        JVC GR_DX95             0x000a  GR-DX95
+
 /* JRC products */
 product JRC AH_J3001V_J3002V   0x0001  AirH\" PHONE AH-J3001V/J3002V
 
@@ -807,11 +852,15 @@ product LOGITECH UN58A            0xc030  iFeel Mouse
 product LOGITECH BB13          0xc401  USB-PS/2 Trackball
 product LOGITECH WMPAD         0xc208  WingMan GamePad Extreme
 product LOGITECH WMRPAD                0xc20a  WingMan RumblePad
-product LOGITECH WMJOY         0xc281  WingMan Force joystick 
+product LOGITECH WMJOY         0xc281  WingMan Force joystick
 product LOGITECH RK53          0xc501  Cordless mouse
 product LOGITECH RB6           0xc503  Cordless keyboard
+product LOGITECH MX700         0xc506  Cordless optical mouse
 product LOGITECH QUICKCAMPRO2  0xd001  QuickCam Pro
 
+/* Logitec Corp. products */
+product        LOGITEC LDR_H443U2      0x00b3  DVD Multi-plus unit LDR-H443U2
+
 /* Lucent products */
 product LUCENT EVALKIT         0x1001  USS-720 evaluation kit
 
@@ -843,8 +892,10 @@ product MICROSOFT INTELLIMOUSE     0x0009  IntelliMouse
 product MICROSOFT NATURALKBD   0x000b  Natural Keyboard Elite
 product MICROSOFT DDS80                0x0014  Digital Sound System 80
 product MICROSOFT SIDEWINDER   0x001a  Sidewinder Precision Racing Wheel
+product MICROSOFT INETPRO      0x001c  Internet Keyboard Pro
 product MICROSOFT INTELLIEYE   0x0025  IntelliEye mouse
-product MICROSOFT INETPRO      0x002b  Internet Keyboard Pro
+product MICROSOFT INETPRO2     0x002b  Internet Keyboard Pro
+product MICROSOFT MN110                0x007a  10/100 USB NIC
 
 /* Microtech products */
 product MICROTECH SCSIDB25     0x0004  USB-SCSI-DB25
@@ -868,6 +919,7 @@ product MIDIMAN MIDISPORT2X2        0x1001  Midisport 2x2
 product MINOLTA 2300           0x4001  Dimage 2300
 product MINOLTA S304           0x4007  Dimage S304
 product MINOLTA X              0x4009  Dimage X
+product MINOLTA 5400           0x400e  Dimage 5400
 
 /* Mitsumi products */
 product MITSUMI CDRRW          0x0000  CD-R/RW Drive
@@ -887,11 +939,13 @@ product MUSTEK 1200UB             0x0006  1200 UB scanner
 product MUSTEK 1200USBPLUS     0x0007  1200 USB Plus scanner
 product MUSTEK 1200CUPLUS      0x0008  1200 CU Plus scanner
 product MUSTEK BEARPAW1200F    0x0010  BearPaw 1200F scanner
+product MUSTEK BEARPAW1200TA   0x021e  BearPaw 1200TA scanner
 product MUSTEK 600USB          0x0873  600 USB scanner
 product MUSTEK MDC800          0xa800  MDC-800 digital camera
 
 /* M-Systems products */
 product MSYSTEMS DISKONKEY     0x0010  DiskOnKey
+product        MSYSTEMS DISKONKEY2     0x0011  DiskOnKey
 
 /* National Semiconductor */
 product NATIONAL BEARPAW1200   0x1000  BearPaw 1200
@@ -927,9 +981,17 @@ product PALM SERIAL                0x0080  USB Serial Adaptor
 product PALM M500              0x0001  Palm m500
 product PALM M505              0x0002  Palm m505
 product PALM M515              0x0003  Palm m515
+product PALM I705              0x0020  Palm i705
+product PALM TUNGSTEN_Z                0x0031  Palm Tungsten Z
 product PALM M125              0x0040  Palm m125
+product PALM M130              0x0050  Palm m130
+product PALM TUNGSTEN_T                0x0060  Palm Tungsten T
+product PALM ZIRE              0x0070  Palm Zire
 
 /* Panasonic products */
+product        PANASONIC KXLRW32AN     0x0d09  CD-R Drive KXL-RW32AN
+product        PANASONIC KXLCB20AN     0x0d0a  CD-R Drive KXL-CB20AN
+product        PANASONIC KXLCB35AN     0x0d0e  DVD-ROM & CD-R/RW
 product PANASONIC SDCAAE       0x1b00  MultiMediaCard Adapter
 
 /* Peracom products */
@@ -956,6 +1018,9 @@ product PIENGINEERING PS2USB       0x020b  PS2 to Mac USB Adapter
 /* PLX products */
 product PLX TESTBOARD          0x9060  test board
 
+/* PNY products */
+product PNY ATTACHE            0x1300  USB 2.0 Flash Drive
+
 /* Primax products */
 product PRIMAX G2X300          0x0300  G2-200 scanner
 product PRIMAX G2E300          0x0301  G2E-300 scanner
@@ -992,7 +1057,7 @@ product QTRONIX 980N               0x2011  Scorpion-980N keyboard
 product QUICKSHOT STRIKEPAD    0x6238  USB StrikePad
 
 /* Rainbow Technologies products */
-product        RAINBOW IKEY2000        0x1200  i-Key 2000  
+product        RAINBOW IKEY2000        0x1200  i-Key 2000
 
 /* ReakTek products */
 product REALTEK USBKR100       0x8150  USBKR100 USB Ethernet (GREEN HOUSE)
@@ -1008,6 +1073,9 @@ product ROCKFIRE GAMEPAD  0x2033  gamepad 203USB
 /* RATOC Systems products */
 product RATOC REXUSB60         0xb000  USB serial adapter REX-USB60
 
+/* Samsung products */
+product SAMSUNG ML6060         0x3008  ML-6060 laser printer
+
 /* SanDisk products */
 product SANDISK SDDR05A                0x0001  ImageMate SDDR-05a
 product SANDISK SDDR05         0x0005  ImageMate SDDR-05
@@ -1034,10 +1102,14 @@ product SHUTTLE CF              0x000a  eUSB CompactFlash Adapter
 product SHUTTLE EUSCSI_B       0x000b  eUSCSI Bridge
 product SHUTTLE EUSCSI_C       0x000c  eUSCSI Bridge
 product SHUTTLE CDRW           0x0101  CD-RW Device
+product SHUTTLE EUSBORCA       0x0325  eUSB ORCA Quad Reader
 
 /* Siemens products */
 product SIEMENS SPEEDSTREAM    0x1001  SpeedStream USB
 
+/* Sigmatel products */
+product SIGMATEL I_BEAD100     0x8008  i-Bead 100 MP3 Player
+
 /* SIIG products */
 product SIIG DIGIFILMREADER    0x0004  DigiFilm-Combo Reader
 
@@ -1057,6 +1129,7 @@ product SMC 2102USB               0x0100  10Mbps ethernet adapter
 product SMC 2202USB            0x0200  10/100 ethernet adapter
 product SMC 2206USB            0x0201  EZ Connect USB Ethernet Adapter
 product SMC2 2020HUB           0x2020  USB Hub
+product SMC3 2662WUSB          0xa002  2662W-AR Wireless Adapter
 
 /* SOHOware products */
 product        SOHOWARE NUB100         0x9100  10/100 USB Ethernet
@@ -1068,9 +1141,17 @@ product SOLIDYEAR KEYBOARD       0x2101  Solid Year USB keyboard
 product SONY DSC               0x0010  DSC cameras
 product SONY MSACUS1           0x002d  Memorystick MSAC-US1
 product SONY MSC               0x0032  MSC memory stick slot
+product SONY CLIE_35           0x0038  Sony Clie v3.5
 product SONY CLIE_40           0x0066  Sony Clie v4.0
+product SONY CLIE_40_MS                0x006d  Sony Clie v4.0 Memory Stick slot
+product SONY CLIE_S360         0x0095  Sony Clie s360
+product SONY CLIE_41_MS                0x0099  Sony Clie v4.1 Memory Stick slot
 product SONY CLIE_41           0x009a  Sony Clie v4.1
-product SONY CLIE_50           0x00da  Sony Clie v5.0
+product SONY CLIE_NX60         0x00da  Sony Clie nx60
+
+/* SOURCENEXT products */
+product SOURCENEXT KEIKAI8     0x039f  KeikaiDenwa 8
+product SOURCENEXT KEIKAI8_CHG 0x012e  KeikaiDenwa 8 with charger
 
 /* STMicroelectronics products */
 product STMICRO COMMUNICATOR   0x7554  USB Communicator
@@ -1097,7 +1178,7 @@ product DIAMOND2 RIO800USB        0x5002  Rio 800 USB
 
 /* Taugagreining products */
 product TAUGA CAMERAMATE       0x0005  CameraMate (DPCM_USB)
+
 /* TDK products */
 product TDK UPA9664            0x0115  USB-PDC Adapter UPA9664
 product TDK UCA1464            0x0116  USB-cdmaOne Adapter UCA1464
@@ -1117,6 +1198,9 @@ product TI TUSB2046               0x2046  TUSB2046 hub
 /* Thrustmaster products */
 product THRUST FUSION_PAD      0xa0a3  Fusion Digital Gamepad
 
+/* Toshiba Corporation products */
+product        TOSHIBA POCKETPC_E740   0x0706  PocketPC e740
+
 /* Trek Technology products */
 product TREK THUMBDRIVE                0x1111  ThumbDrive
 product TREK THUMBDRIVE_8MB    0x9988  ThumbDrive_8MB
@@ -1135,6 +1219,9 @@ product UMAX ASTRA3400            0x0060  Astra 3400 Scanner
 /* Universal Access products */
 product UNIACCESS PANACHE      0x0101  Panache Surf USB ISDN Adapter
 
+/* VidzMedia products */
+product VIDZMEDIA MONSTERTV    0x4fb1  MonsterTV P2H
+
 /* Vision products */
 product VISION VC6452V002      0x0002  CPiA Camera
 
@@ -1146,12 +1233,13 @@ product VISIONEER 6100          0x0231  OneTouch 6100
 product VISIONEER 6200         0x0311  OneTouch 6200
 product VISIONEER 8100         0x0321  OneTouch 8100
 product VISIONEER 8600         0x0331  OneTouch 8600
-                                                                      
+
 /* Wacom products */
 product WACOM CT0405U          0x0000  CT-0405-U Tablet
 product WACOM GRAPHIRE         0x0010  Graphire
 product WACOM INTUOSA5         0x0021  Intuos A5
+product WACOM GD0912U          0x0022  Intuos 9x12 Graphics Tablet
+
 /* Xirlink products */
 product XIRLINK PCCAM          0x8080  IBM PC Camera
 
index ae4f787..c0109a4 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *     $DragonFly: src/sys/bus/usb/Attic/usbdevs.h,v 1.3 2003/08/15 01:19:54 dillon Exp $
- *
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
  *
  */
@@ -40,8 +38,8 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.42 2003/05/11 00:12:29 murray Exp $
- * $DragonFly: src/sys/bus/usb/Attic/usbdevs.h,v 1.3 2003/08/15 01:19:54 dillon Exp $
+ * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.50 2003/12/22 07:52:56 sanpei Exp $
+ * $DragonFly: src/sys/bus/usb/Attic/usbdevs.h,v 1.4 2003/12/29 06:42:12 dillon Exp $
  */
 
 /*
 #define        USB_VENDOR_STMICRO      0x0483          /* STMicroelectronics */
 #define        USB_VENDOR_YAMAHA       0x0499          /* YAMAHA */
 #define        USB_VENDOR_COMPAQ       0x049f          /* Compaq Computers */
+#define        USB_VENDOR_HITACHI      0x04a4          /* Hitachi, Ltd. */
 #define        USB_VENDOR_ACERP        0x04a5          /* Acer Peripherals */
 #define        USB_VENDOR_VISIONEER    0x04a7          /* Visioneer */
 #define        USB_VENDOR_CANON        0x04a9          /* Canon */
 #define        USB_VENDOR_PANASONIC    0x04da          /* Panasonic (Matsushita) */
 #define        USB_VENDOR_IIYAMA       0x04e1          /* Iiyama */
 #define        USB_VENDOR_SHUTTLE      0x04e6          /* Shuttle Technology */
+#define        USB_VENDOR_SAMSUNG      0x04e8          /* Samsung Electronics */
 #define        USB_VENDOR_ANNABOOKS    0x04ed          /* Annabooks */
+#define        USB_VENDOR_JVC  0x04f1          /* JVC */
 #define        USB_VENDOR_CHICONY      0x04f2          /* Chicony Electronics */
 #define        USB_VENDOR_BROTHER      0x04f9          /* Brother Industries */
 #define        USB_VENDOR_DALLAS       0x04fa          /* Dallas Semiconductor */
 #define        USB_VENDOR_LINKSYS2     0x077b          /* Linksys */
 #define        USB_VENDOR_GRIFFIN      0x077d          /* Griffin Technology */
 #define        USB_VENDOR_SANDISK      0x0781          /* SanDisk Corp */
+#define        USB_VENDOR_LOGITEC      0x0789          /* Logitec Corp */
 #define        USB_VENDOR_BRIMAX       0x078e          /* Brimax */
 #define        USB_VENDOR_AXIS 0x0792          /* Axis Communications */
 #define        USB_VENDOR_ABL  0x0794          /* ABL Electronics */
 #define        USB_VENDOR_COREGA       0x07aa          /* Corega */
 #define        USB_VENDOR_FREECOM      0x07ab          /* Freecom */
 #define        USB_VENDOR_MICROTECH    0x07af          /* Microtech */
+#define        USB_VENDOR_GENERALINSTMNTS      0x07b2          /* General Instruments (Motorola) */
 #define        USB_VENDOR_OLYMPUS      0x07b4          /* Olympus */
 #define        USB_VENDOR_ABOCOM       0x07b8          /* AboCom Systems */
 #define        USB_VENDOR_KEISOKUGIKEN 0x07c1          /* Keisokugiken */
 #define        USB_VENDOR_HANDSPRING   0x082d          /* Handspring */
 #define        USB_VENDOR_ACTIONSTAR   0x0835          /* Action Star Enterprise */
 #define        USB_VENDOR_PALM 0x0830          /* Palm Computing */
+#define        USB_VENDOR_SOURCENEXT   0x0833          /* SOURCENEXT */
 #define        USB_VENDOR_ACCTON       0x083a          /* Accton Technology */
 #define        USB_VENDOR_DIAMOND      0x0841          /* Diamond */
 #define        USB_VENDOR_NETGEAR      0x0846          /* BayNETGEAR */
 #define        USB_VENDOR_ALATION      0x0910          /* Alation Systems */
 #define        USB_VENDOR_GOHUBS       0x0921          /* GoHubs */
 #define        USB_VENDOR_BIOMETRIC    0x0929          /* American Biometric Company */
+#define        USB_VENDOR_TOSHIBA      0x0930          /* Toshiba Corporation */
 #define        USB_VENDOR_YANO 0x094f          /* Yano */
 #define        USB_VENDOR_KINGSTON     0x0951          /* Kingston Technology */
 #define        USB_VENDOR_BLUEWATER    0x0956          /* BlueWater Systems */
 #define        USB_VENDOR_PORTSMITH    0x095a          /* Portsmith */
 #define        USB_VENDOR_ADIRONDACK   0x0976          /* Adirondack Wire & Cable */
 #define        USB_VENDOR_BECKHOFF     0x0978          /* Beckhoff */
+#define        USB_VENDOR_INTERSIL     0x09aa          /* Intersil */
 #define        USB_VENDOR_ALTIUS       0x09b3          /* Altius Solutions */
 #define        USB_VENDOR_ARRIS        0x09c1          /* Arris Interactive */
 #define        USB_VENDOR_ACTIVCARD    0x09c3          /* ACTIVCARD */
 #define        USB_VENDOR_GEOCAST      0x0a79          /* Geocast Network Systems */
 #define        USB_VENDOR_NEODIO       0x0aec          /* Neodio */
 #define        USB_VENDOR_TODOS        0x0b0c          /* Todos Data System */
+#define        USB_VENDOR_HAL  0x0b41          /* HAL Corporation */
 #define        USB_VENDOR_NEC2 0x0b62          /* NEC */
 #define        USB_VENDOR_ATI2 0x0b6f          /* ATI */
 #define        USB_VENDOR_ASIX 0x0b95          /* ASIX Electronics */
 #define        USB_VENDOR_AGATE        0x0c08          /* Agate Technologies */
 #define        USB_VENDOR_DMI  0x0c0b          /* DMI */
 #define        USB_VENDOR_LUWEN        0x0c76          /* Luwen */
+#define        USB_VENDOR_SMC3 0x0d5c          /* Standard Microsystems */
+#define        USB_VENDOR_PNY  0x0d7d          /* PNY */
+#define        USB_VENDOR_HAWKING      0x0e66          /* Hawking Technologies */
 #define        USB_VENDOR_MOTOROLA     0x1063          /* Motorola */
 #define        USB_VENDOR_PLX  0x10b5          /* PLX */
 #define        USB_VENDOR_ASANTE       0x10bd          /* Asante */
 #define        USB_VENDOR_ENTREGA      0x1645          /* Entrega */
 #define        USB_VENDOR_ACTIONTEC    0x1668          /* Actiontec Electronics */
 #define        USB_VENDOR_DLINK        0x2001          /* D-Link */
+#define        USB_VENDOR_VIDZMEDIA    0x3275          /* VidzMedia Pte Ltd */
 #define        USB_VENDOR_DAISY        0x3579          /* Daisy Technology */
 #define        USB_VENDOR_INTEL        0x8086          /* Intel */
 #define        USB_VENDOR_HP2  0xf003          /* Hewlett Packard */
 #define        USB_PRODUCT_ACTIVEWIRE_IOBOARD  0x0100          /* I/O Board */
 #define        USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1      0x0101          /* I/O Board, rev. 1 firmware */
 
+/* Actiontec, Inc. products */
+#define        USB_PRODUCT_ACTIONTEC_UAT1      0x7605          /* UAT1 Wireless Ethernet adapter */
+
 /* ADMtek products */
 #define        USB_PRODUCT_ADMTEK_PEGASUS      0x0986          /* AN986 USB Ethernet adapter */
 #define        USB_PRODUCT_ADMTEK_PEGASUSII    0x8511          /* AN8511 USB Ethernet adapter */
 
 /* Asahi Optical products */
 #define        USB_PRODUCT_ASAHIOPTICAL_OPTIO230       0x0004          /* Digital camera */
+#define        USB_PRODUCT_ASAHIOPTICAL_OPTIO330       0x0006          /* Digital camera */
 
 /* ASIX Electronics products */
 #define        USB_PRODUCT_ASIX_AX88172        0x1720          /* USB 2.0 10/100 ethernet controller */
 /* Atmel Comp. products */
 #define        USB_PRODUCT_ATMEL_UHB124        0x3301          /* UHB124 hub */
 #define        USB_PRODUCT_ATMEL_DWL120        0x7602          /* DWL-120 Wireless adapter */
+#define        USB_PRODUCT_ATMEL_BW002 0x7605          /* BW002 Wireless adapter */
 
 /* Avision products */
 #define        USB_PRODUCT_AVISION_1200U       0x0268          /* 1200U scanner */
 #define        USB_PRODUCT_BELKIN_F5U103       0x0103          /* F5U103 Serial adapter */
 #define        USB_PRODUCT_BELKIN_F5U109       0x0109          /* F5U109 Serial adapter */
 #define        USB_PRODUCT_BELKIN_F5U120       0x1203          /* F5U120-PC Hub */
+#define        USB_PRODUCT_BELKIN_F5U208       0x0208          /* F5U208 VideoBus II */
 
 /* Billionton products */
 #define        USB_PRODUCT_BILLIONTON_USB100   0x0986          /* USB100N 10/100 FastEthernet Adapter */
 #define        USB_PRODUCT_BTC_BTC7932 0x6782          /* Keyboard with mouse port */
 
 /* Canon, Inc. products */
-#define        USB_PRODUCT_CANON_N656U 0x2206          /* CANOSCAN N656U */
+#define        USB_PRODUCT_CANON_N656U 0x2206          /* CanoScan N656U */
+#define        USB_PRODUCT_CANON_N1240U        0x220e          /* CanoScan N1240U */
 #define        USB_PRODUCT_CANON_S10   0x3041          /* PowerShot S10 */
 #define        USB_PRODUCT_CANON_S100  0x3045          /* PowerShot S100 */
+#define        USB_PRODUCT_CANON_S200  0x3065          /* PowerShot S200 */
 
 /* CATC products */
 #define        USB_PRODUCT_CATC_NETMATE        0x000a          /* Netmate ethernet adapter */
 #define        USB_PRODUCT_CYPRESS_MOUSE       0x0001          /* mouse */
 #define        USB_PRODUCT_CYPRESS_THERMO      0x0002          /* thermometer */
 #define        USB_PRODUCT_CYPRESS_FMRADIO     0x1002          /* FM Radio */
+#define        USB_PRODUCT_CYPRESS_SLIM_HUB    0x6560          /* Slim Hub */
 
 /* Daisy Technology products */
 #define        USB_PRODUCT_DAISY_DMC   0x6901          /* USB MultiMedia Reader */
 #define        USB_PRODUCT_EPSON_1640  0x010a          /* Perfection 1640SU scanner */
 #define        USB_PRODUCT_EPSON_1240  0x010b          /* Perfection 1240U / 1240Photo scanner */
 #define        USB_PRODUCT_EPSON_640U  0x010c          /* Perfection 640U scanner */
+#define        USB_PRODUCT_EPSON_1250  0x010f          /* Perfection 1250U / 1250Photo scanner */
 #define        USB_PRODUCT_EPSON_1650  0x0110          /* Perfection 1650 scanner */
 #define        USB_PRODUCT_EPSON_GT9700F       0x0112          /* GT-9700F scanner */
+#define        USB_PRODUCT_EPSON_GT9300UF      0x011b          /* GT-9300UF scanner */
 #define        USB_PRODUCT_EPSON_1260  0x011d          /* Perfection 1260 scanner */
 #define        USB_PRODUCT_EPSON_1660  0x011e          /* Perfection 1660 scanner */
 
 /* Fujitsu protducts */
 #define        USB_PRODUCT_FUJITSU_AH_F401U    0x105b          /* AH-F401U Air H device */
 
+/* General Instruments (Motorola) products */
+#define        USB_PRODUCT_GENERALINSTMNTS_SB5100      0x5100          /* SURFboard SB5100 Cable modem */
+
 /* Genesys Logic products */
 #define        USB_PRODUCT_GENESYS_GL650       0x0604          /* GL650 Hub */
 #define        USB_PRODUCT_GENESYS_GL641USB    0x0700          /* GL641USB CompactFlash Card Reader */
 #define        USB_PRODUCT_GENESYS_GL641USB2IDE        0x0702          /* GL641USB USB-IDE Bridge */
 
+/* HAL Corporation products */
+#define        USB_PRODUCT_HAL_IMR001  0x0011          /* Crossam2+USB IR commander */
+
 /* Hagiwara products */
 #define        USB_PRODUCT_HAGIWARA_FGSM       0x0002          /* FlashGate SmartMedia Card Reader */
 #define        USB_PRODUCT_HAGIWARA_FGCF       0x0003          /* FlashGate CompactFlash Card Reader */
 
 /* Handspring, Inc. */
 #define        USB_PRODUCT_HANDSPRING_VISOR    0x0100          /* Handspring Visor */
+#define        USB_PRODUCT_HANDSPRING_TREO     0x0200          /* Handspring Treo */
 
 /* Hauppauge Computer Works */
 #define        USB_PRODUCT_HAUPPAUGE_WINTV_USB_FM      0x4d12          /* WinTV USB FM */
 
+/* Hawking Technologies products */
+#define        USB_PRODUCT_HAWKING_UF100       0x400c          /* 10/100 USB Ethernet */
+
+/* Hitachi, Ltd. products */
+#define        USB_PRODUCT_HITACHI_DVDCAM_USB  0x001e          /* DVDCAM USB HS Interface */
+
 /* HP products */
 #define        USB_PRODUCT_HP_895C     0x0004          /* DeskJet 895C */
 #define        USB_PRODUCT_HP_4100C    0x0101          /* Scanjet 4100C */
 #define        USB_PRODUCT_HP_840C     0x0604          /* DeskJet 840c */
 #define        USB_PRODUCT_HP_2200C    0x0605          /* ScanJet 2200C */
 #define        USB_PRODUCT_HP_5300C    0x0701          /* Scanjet 5300C */
+#define        USB_PRODUCT_HP_4400C    0x0705          /* Scanjet 4400C */
 #define        USB_PRODUCT_HP_970CSE   0x1004          /* Deskjet 970Cse */
 #define        USB_PRODUCT_HP_5400C    0x1005          /* Scanjet 5400C */
 #define        USB_PRODUCT_HP_930C     0x1204          /* DeskJet 930c */
 #define        USB_PRODUCT_HP_P2000U   0x1801          /* Inkjet P-2000U */
 #define        USB_PRODUCT_HP_640C     0x2004          /* DeskJet 640c */
 #define        USB_PRODUCT_HP_P1100    0x3102          /* Photosmart P1100 */
+#define        USB_PRODUCT_HP_HN210E   0x811c          /* Ethernet HN210E */
 
 /* HP products */
 #define        USB_PRODUCT_HP2_C500    0x6002          /* PhotoSmart C500 */
 #define        USB_PRODUCT_INTEL_EASYPC_CAMERA 0x0110          /* Easy PC Camera */
 #define        USB_PRODUCT_INTEL_TESTBOARD     0x9890          /* 82930 test board */
 
+/* Intersil products */
+#define        USB_PRODUCT_INTERSIL_PRISM_2X   0x3642          /* Prism2.x or Atmel WLAN */
+
 /* I/O DATA products */
 #define        USB_PRODUCT_IODATA_USBETT       0x0901          /* USB ETT */
 #define        USB_PRODUCT_IODATA_USBETTX      0x0904          /* USB ETTX */
 #define        USB_PRODUCT_IOMEGA_ZIP100       0x0001          /* Zip 100 */
 #define        USB_PRODUCT_IOMEGA_ZIP250       0x0030          /* Zip 250 */
 
+/* JVC products */
+#define        USB_PRODUCT_JVC_GR_DX95 0x000a          /* GR-DX95 */
+
 /* JRC products */
 #define        USB_PRODUCT_JRC_AH_J3001V_J3002V        0x0001          /* AirH\" PHONE AH-J3001V/J3002V */
 
 #define        USB_PRODUCT_LOGITECH_WMJOY      0xc281          /* WingMan Force joystick */
 #define        USB_PRODUCT_LOGITECH_RK53       0xc501          /* Cordless mouse */
 #define        USB_PRODUCT_LOGITECH_RB6        0xc503          /* Cordless keyboard */
+#define        USB_PRODUCT_LOGITECH_MX700      0xc506          /* Cordless optical mouse */
 #define        USB_PRODUCT_LOGITECH_QUICKCAMPRO2       0xd001          /* QuickCam Pro */
 
+/* Logitec Corp. products */
+#define        USB_PRODUCT_LOGITEC_LDR_H443U2  0x00b3          /* DVD Multi-plus unit LDR-H443U2 */
+
 /* Lucent products */
 #define        USB_PRODUCT_LUCENT_EVALKIT      0x1001          /* USS-720 evaluation kit */
 
 #define        USB_PRODUCT_MICROSOFT_NATURALKBD        0x000b          /* Natural Keyboard Elite */
 #define        USB_PRODUCT_MICROSOFT_DDS80     0x0014          /* Digital Sound System 80 */
 #define        USB_PRODUCT_MICROSOFT_SIDEWINDER        0x001a          /* Sidewinder Precision Racing Wheel */
+#define        USB_PRODUCT_MICROSOFT_INETPRO   0x001c          /* Internet Keyboard Pro */
 #define        USB_PRODUCT_MICROSOFT_INTELLIEYE        0x0025          /* IntelliEye mouse */
-#define        USB_PRODUCT_MICROSOFT_INETPRO   0x002b          /* Internet Keyboard Pro */
+#define        USB_PRODUCT_MICROSOFT_INETPRO2  0x002b          /* Internet Keyboard Pro */
+#define        USB_PRODUCT_MICROSOFT_MN110     0x007a          /* 10/100 USB NIC */
 
 /* Microtech products */
 #define        USB_PRODUCT_MICROTECH_SCSIDB25  0x0004          /* USB-SCSI-DB25 */
 #define        USB_PRODUCT_MINOLTA_2300        0x4001          /* Dimage 2300 */
 #define        USB_PRODUCT_MINOLTA_S304        0x4007          /* Dimage S304 */
 #define        USB_PRODUCT_MINOLTA_X   0x4009          /* Dimage X */
+#define        USB_PRODUCT_MINOLTA_5400        0x400e          /* Dimage 5400 */
 
 /* Mitsumi products */
 #define        USB_PRODUCT_MITSUMI_CDRRW       0x0000          /* CD-R/RW Drive */
 #define        USB_PRODUCT_MUSTEK_1200USBPLUS  0x0007          /* 1200 USB Plus scanner */
 #define        USB_PRODUCT_MUSTEK_1200CUPLUS   0x0008          /* 1200 CU Plus scanner */
 #define        USB_PRODUCT_MUSTEK_BEARPAW1200F 0x0010          /* BearPaw 1200F scanner */
+#define        USB_PRODUCT_MUSTEK_BEARPAW1200TA        0x021e          /* BearPaw 1200TA scanner */
 #define        USB_PRODUCT_MUSTEK_600USB       0x0873          /* 600 USB scanner */
 #define        USB_PRODUCT_MUSTEK_MDC800       0xa800          /* MDC-800 digital camera */
 
 /* M-Systems products */
 #define        USB_PRODUCT_MSYSTEMS_DISKONKEY  0x0010          /* DiskOnKey */
+#define        USB_PRODUCT_MSYSTEMS_DISKONKEY2 0x0011          /* DiskOnKey */
 
 /* National Semiconductor */
 #define        USB_PRODUCT_NATIONAL_BEARPAW1200        0x1000          /* BearPaw 1200 */
 #define        USB_PRODUCT_PALM_M500   0x0001          /* Palm m500 */
 #define        USB_PRODUCT_PALM_M505   0x0002          /* Palm m505 */
 #define        USB_PRODUCT_PALM_M515   0x0003          /* Palm m515 */
+#define        USB_PRODUCT_PALM_I705   0x0020          /* Palm i705 */
+#define        USB_PRODUCT_PALM_TUNGSTEN_Z     0x0031          /* Palm Tungsten Z */
 #define        USB_PRODUCT_PALM_M125   0x0040          /* Palm m125 */
+#define        USB_PRODUCT_PALM_M130   0x0050          /* Palm m130 */
+#define        USB_PRODUCT_PALM_TUNGSTEN_T     0x0060          /* Palm Tungsten T */
+#define        USB_PRODUCT_PALM_ZIRE   0x0070          /* Palm Zire */
 
 /* Panasonic products */
+#define        USB_PRODUCT_PANASONIC_KXLRW32AN 0x0d09          /* CD-R Drive KXL-RW32AN */
+#define        USB_PRODUCT_PANASONIC_KXLCB20AN 0x0d0a          /* CD-R Drive KXL-CB20AN */
+#define        USB_PRODUCT_PANASONIC_KXLCB35AN 0x0d0e          /* DVD-ROM & CD-R/RW */
 #define        USB_PRODUCT_PANASONIC_SDCAAE    0x1b00          /* MultiMediaCard Adapter */
 
 /* Peracom products */
 /* PLX products */
 #define        USB_PRODUCT_PLX_TESTBOARD       0x9060          /* test board */
 
+/* PNY products */
+#define        USB_PRODUCT_PNY_ATTACHE 0x1300          /* USB 2.0 Flash Drive */
+
 /* Primax products */
 #define        USB_PRODUCT_PRIMAX_G2X300       0x0300          /* G2-200 scanner */
 #define        USB_PRODUCT_PRIMAX_G2E300       0x0301          /* G2E-300 scanner */
 /* RATOC Systems products */
 #define        USB_PRODUCT_RATOC_REXUSB60      0xb000          /* USB serial adapter REX-USB60 */
 
+/* Samsung products */
+#define        USB_PRODUCT_SAMSUNG_ML6060      0x3008          /* ML-6060 laser printer */
+
 /* SanDisk products */
 #define        USB_PRODUCT_SANDISK_SDDR05A     0x0001          /* ImageMate SDDR-05a */
 #define        USB_PRODUCT_SANDISK_SDDR05      0x0005          /* ImageMate SDDR-05 */
 #define        USB_PRODUCT_SHUTTLE_EUSCSI_B    0x000b          /* eUSCSI Bridge */
 #define        USB_PRODUCT_SHUTTLE_EUSCSI_C    0x000c          /* eUSCSI Bridge */
 #define        USB_PRODUCT_SHUTTLE_CDRW        0x0101          /* CD-RW Device */
+#define        USB_PRODUCT_SHUTTLE_EUSBORCA    0x0325          /* eUSB ORCA Quad Reader */
 
 /* Siemens products */
 #define        USB_PRODUCT_SIEMENS_SPEEDSTREAM 0x1001          /* SpeedStream USB */
 
+/* Sigmatel products */
+#define        USB_PRODUCT_SIGMATEL_I_BEAD100  0x8008          /* i-Bead 100 MP3 Player */
+
 /* SIIG products */
 #define        USB_PRODUCT_SIIG_DIGIFILMREADER 0x0004          /* DigiFilm-Combo Reader */
 
 #define        USB_PRODUCT_SMC_2202USB 0x0200          /* 10/100 ethernet adapter */
 #define        USB_PRODUCT_SMC_2206USB 0x0201          /* EZ Connect USB Ethernet Adapter */
 #define        USB_PRODUCT_SMC2_2020HUB        0x2020          /* USB Hub */
+#define        USB_PRODUCT_SMC3_2662WUSB       0xa002          /* 2662W-AR Wireless Adapter */
 
 /* SOHOware products */
 #define        USB_PRODUCT_SOHOWARE_NUB100     0x9100          /* 10/100 USB Ethernet */
 #define        USB_PRODUCT_SONY_DSC    0x0010          /* DSC cameras */
 #define        USB_PRODUCT_SONY_MSACUS1        0x002d          /* Memorystick MSAC-US1 */
 #define        USB_PRODUCT_SONY_MSC    0x0032          /* MSC memory stick slot */
+#define        USB_PRODUCT_SONY_CLIE_35        0x0038          /* Sony Clie v3.5 */
 #define        USB_PRODUCT_SONY_CLIE_40        0x0066          /* Sony Clie v4.0 */
+#define        USB_PRODUCT_SONY_CLIE_40_MS     0x006d          /* Sony Clie v4.0 Memory Stick slot */
+#define        USB_PRODUCT_SONY_CLIE_S360      0x0095          /* Sony Clie s360 */
+#define        USB_PRODUCT_SONY_CLIE_41_MS     0x0099          /* Sony Clie v4.1 Memory Stick slot */
 #define        USB_PRODUCT_SONY_CLIE_41        0x009a          /* Sony Clie v4.1 */
-#define        USB_PRODUCT_SONY_CLIE_50        0x00da          /* Sony Clie v5.0 */
+#define        USB_PRODUCT_SONY_CLIE_NX60      0x00da          /* Sony Clie nx60 */
+
+/* SOURCENEXT products */
+#define        USB_PRODUCT_SOURCENEXT_KEIKAI8  0x039f          /* KeikaiDenwa 8 */
+#define        USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG      0x012e          /* KeikaiDenwa 8 with charger */
 
 /* STMicroelectronics products */
 #define        USB_PRODUCT_STMICRO_COMMUNICATOR        0x7554          /* USB Communicator */
 
 /* Taugagreining products */
 #define        USB_PRODUCT_TAUGA_CAMERAMATE    0x0005          /* CameraMate (DPCM_USB) */
+
 /* TDK products */
 #define        USB_PRODUCT_TDK_UPA9664 0x0115          /* USB-PDC Adapter UPA9664 */
 #define        USB_PRODUCT_TDK_UCA1464 0x0116          /* USB-cdmaOne Adapter UCA1464 */
 /* Thrustmaster products */
 #define        USB_PRODUCT_THRUST_FUSION_PAD   0xa0a3          /* Fusion Digital Gamepad */
 
+/* Toshiba Corporation products */
+#define        USB_PRODUCT_TOSHIBA_POCKETPC_E740       0x0706          /* PocketPC e740 */
+
 /* Trek Technology products */
 #define        USB_PRODUCT_TREK_THUMBDRIVE     0x1111          /* ThumbDrive */
 #define        USB_PRODUCT_TREK_THUMBDRIVE_8MB 0x9988          /* ThumbDrive_8MB */
 /* Universal Access products */
 #define        USB_PRODUCT_UNIACCESS_PANACHE   0x0101          /* Panache Surf USB ISDN Adapter */
 
+/* VidzMedia products */
+#define        USB_PRODUCT_VIDZMEDIA_MONSTERTV 0x4fb1          /* MonsterTV P2H */
+
 /* Vision products */
 #define        USB_PRODUCT_VISION_VC6452V002   0x0002          /* CPiA Camera */
 
 #define        USB_PRODUCT_VISIONEER_6200      0x0311          /* OneTouch 6200 */
 #define        USB_PRODUCT_VISIONEER_8100      0x0321          /* OneTouch 8100 */
 #define        USB_PRODUCT_VISIONEER_8600      0x0331          /* OneTouch 8600 */
-                                                                      
+
 /* Wacom products */
 #define        USB_PRODUCT_WACOM_CT0405U       0x0000          /* CT-0405-U Tablet */
 #define        USB_PRODUCT_WACOM_GRAPHIRE      0x0010          /* Graphire */
 #define        USB_PRODUCT_WACOM_INTUOSA5      0x0021          /* Intuos A5 */
+#define        USB_PRODUCT_WACOM_GD0912U       0x0022          /* Intuos 9x12 Graphics Tablet */
+
 /* Xirlink products */
 #define        USB_PRODUCT_XIRLINK_PCCAM       0x8080          /* IBM PC Camera */
 
index 5d8339f..634a85e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *     $DragonFly: src/sys/bus/usb/Attic/usbdevs_data.h,v 1.3 2003/08/15 01:19:54 dillon Exp $
- *
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
  *
  */
@@ -40,8 +38,8 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.42 2003/05/11 00:12:29 murray Exp $
- * $DragonFly: src/sys/bus/usb/Attic/usbdevs_data.h,v 1.3 2003/08/15 01:19:54 dillon Exp $
+ * $FreeBSD: src/sys/dev/usb/usbdevs,v 1.11.2.50 2003/12/22 07:52:56 sanpei Exp $
+ * $DragonFly: src/sys/bus/usb/Attic/usbdevs_data.h,v 1.4 2003/12/29 06:42:12 dillon Exp $
  */
 
 /*
@@ -255,6 +253,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "ActiveWire",
            "I/O Board, rev. 1 firmware",
        },
+       {
+           USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_UAT1,
+           0,
+           "Actiontec Electronics",
+           "UAT1 Wireless Ethernet adapter",
+       },
        {
            USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS,
            0,
@@ -429,6 +433,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Asahi Optical",
            "Digital camera",
        },
+       {
+           USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330,
+           0,
+           "Asahi Optical",
+           "Digital camera",
+       },
        {
            USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172,
            0,
@@ -465,6 +475,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Atmel",
            "DWL-120 Wireless adapter",
        },
+       {
+           USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_BW002,
+           0,
+           "Atmel",
+           "BW002 Wireless adapter",
+       },
        {
            USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U,
            0,
@@ -501,6 +517,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Belkin Components",
            "F5U120-PC Hub",
        },
+       {
+           USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U208,
+           0,
+           "Belkin Components",
+           "F5U208 VideoBus II",
+       },
        {
            USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100,
            0,
@@ -541,7 +563,13 @@ struct usb_knowndev usb_knowndevs[] = {
            USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U,
            0,
            "Canon",
-           "CANOSCAN N656U",
+           "CanoScan N656U",
+       },
+       {
+           USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U,
+           0,
+           "Canon",
+           "CanoScan N1240U",
        },
        {
            USB_VENDOR_CANON, USB_PRODUCT_CANON_S10,
@@ -555,6 +583,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Canon",
            "PowerShot S100",
        },
+       {
+           USB_VENDOR_CANON, USB_PRODUCT_CANON_S200,
+           0,
+           "Canon",
+           "PowerShot S200",
+       },
        {
            USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE,
            0,
@@ -675,6 +709,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Cypress Semiconductor",
            "FM Radio",
        },
+       {
+           USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SLIM_HUB,
+           0,
+           "Cypress Semiconductor",
+           "Slim Hub",
+       },
        {
            USB_VENDOR_DAISY, USB_PRODUCT_DAISY_DMC,
            0,
@@ -951,6 +991,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Seiko Epson",
            "Perfection 640U scanner",
        },
+       {
+           USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250,
+           0,
+           "Seiko Epson",
+           "Perfection 1250U / 1250Photo scanner",
+       },
        {
            USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650,
            0,
@@ -963,6 +1009,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Seiko Epson",
            "GT-9700F scanner",
        },
+       {
+           USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9300UF,
+           0,
+           "Seiko Epson",
+           "GT-9300UF scanner",
+       },
        {
            USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260,
            0,
@@ -1041,6 +1093,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Fujitsu",
            "AH-F401U Air H device",
        },
+       {
+           USB_VENDOR_GENERALINSTMNTS, USB_PRODUCT_GENERALINSTMNTS_SB5100,
+           0,
+           "General Instruments (Motorola)",
+           "SURFboard SB5100 Cable modem",
+       },
        {
            USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL650,
            0,
@@ -1059,6 +1117,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Genesys Logic",
            "GL641USB USB-IDE Bridge",
        },
+       {
+           USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001,
+           0,
+           "HAL Corporation",
+           "Crossam2+USB IR commander",
+       },
        {
            USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
            0,
@@ -1083,12 +1147,30 @@ struct usb_knowndev usb_knowndevs[] = {
            "Handspring",
            "Handspring Visor",
        },
+       {
+           USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO,
+           0,
+           "Handspring",
+           "Handspring Treo",
+       },
        {
            USB_VENDOR_HAUPPAUGE, USB_PRODUCT_HAUPPAUGE_WINTV_USB_FM,
            0,
            "Hauppauge Computer Works",
            "WinTV USB FM",
        },
+       {
+           USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100,
+           0,
+           "Hawking Technologies",
+           "10/100 USB Ethernet",
+       },
+       {
+           USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB,
+           0,
+           "Hitachi, Ltd.",
+           "DVDCAM USB HS Interface",
+       },
        {
            USB_VENDOR_HP, USB_PRODUCT_HP_895C,
            0,
@@ -1233,6 +1315,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Hewlett Packard",
            "Scanjet 5300C",
        },
+       {
+           USB_VENDOR_HP, USB_PRODUCT_HP_4400C,
+           0,
+           "Hewlett Packard",
+           "Scanjet 4400C",
+       },
        {
            USB_VENDOR_HP, USB_PRODUCT_HP_970CSE,
            0,
@@ -1269,6 +1357,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Hewlett Packard",
            "Photosmart P1100",
        },
+       {
+           USB_VENDOR_HP, USB_PRODUCT_HP_HN210E,
+           0,
+           "Hewlett Packard",
+           "Ethernet HN210E",
+       },
        {
            USB_VENDOR_HP2, USB_PRODUCT_HP2_C500,
            0,
@@ -1329,6 +1423,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Intel",
            "82930 test board",
        },
+       {
+           USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_2X,
+           0,
+           "Intersil",
+           "Prism2.x or Atmel WLAN",
+       },
        {
            USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT,
            0,
@@ -1365,6 +1465,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Iomega",
            "Zip 250",
        },
+       {
+           USB_VENDOR_JVC, USB_PRODUCT_JVC_GR_DX95,
+           0,
+           "JVC",
+           "GR-DX95",
+       },
        {
            USB_VENDOR_JRC, USB_PRODUCT_JRC_AH_J3001V_J3002V,
            0,
@@ -1713,12 +1819,24 @@ struct usb_knowndev usb_knowndevs[] = {
            "Logitech",
            "Cordless keyboard",
        },
+       {
+           USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MX700,
+           0,
+           "Logitech",
+           "Cordless optical mouse",
+       },
        {
            USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO2,
            0,
            "Logitech",
            "QuickCam Pro",
        },
+       {
+           USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2,
+           0,
+           "Logitec Corp",
+           "DVD Multi-plus unit LDR-H443U2",
+       },
        {
            USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT,
            0,
@@ -1827,6 +1945,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Microsoft",
            "Sidewinder Precision Racing Wheel",
        },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO,
+           0,
+           "Microsoft",
+           "Internet Keyboard Pro",
+       },
        {
            USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIEYE,
            0,
@@ -1834,11 +1958,17 @@ struct usb_knowndev usb_knowndevs[] = {
            "IntelliEye mouse",
        },
        {
-           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO,
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO2,
            0,
            "Microsoft",
            "Internet Keyboard Pro",
        },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110,
+           0,
+           "Microsoft",
+           "10/100 USB NIC",
+       },
        {
            USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
            0,
@@ -1929,6 +2059,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Minolta",
            "Dimage X",
        },
+       {
+           USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400,
+           0,
+           "Minolta",
+           "Dimage 5400",
+       },
        {
            USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW,
            0,
@@ -1995,6 +2131,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Mustek Systems",
            "BearPaw 1200F scanner",
        },
+       {
+           USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA,
+           0,
+           "Mustek Systems",
+           "BearPaw 1200TA scanner",
+       },
        {
            USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB,
            0,
@@ -2013,6 +2155,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "M-Systems",
            "DiskOnKey",
        },
+       {
+           USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2,
+           0,
+           "M-Systems",
+           "DiskOnKey",
+       },
        {
            USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200,
            0,
@@ -2115,12 +2263,60 @@ struct usb_knowndev usb_knowndevs[] = {
            "Palm Computing",
            "Palm m515",
        },
+       {
+           USB_VENDOR_PALM, USB_PRODUCT_PALM_I705,
+           0,
+           "Palm Computing",
+           "Palm i705",
+       },
+       {
+           USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z,
+           0,
+           "Palm Computing",
+           "Palm Tungsten Z",
+       },
        {
            USB_VENDOR_PALM, USB_PRODUCT_PALM_M125,
            0,
            "Palm Computing",
            "Palm m125",
        },
+       {
+           USB_VENDOR_PALM, USB_PRODUCT_PALM_M130,
+           0,
+           "Palm Computing",
+           "Palm m130",
+       },
+       {
+           USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T,
+           0,
+           "Palm Computing",
+           "Palm Tungsten T",
+       },
+       {
+           USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE,
+           0,
+           "Palm Computing",
+           "Palm Zire",
+       },
+       {
+           USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLRW32AN,
+           0,
+           "Panasonic (Matsushita)",
+           "CD-R Drive KXL-RW32AN",
+       },
+       {
+           USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN,
+           0,
+           "Panasonic (Matsushita)",
+           "CD-R Drive KXL-CB20AN",
+       },
+       {
+           USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN,
+           0,
+           "Panasonic (Matsushita)",
+           "DVD-ROM & CD-R/RW",
+       },
        {
            USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_SDCAAE,
            0,
@@ -2211,6 +2407,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "PLX",
            "test board",
        },
+       {
+           USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE,
+           0,
+           "PNY",
+           "USB 2.0 Flash Drive",
+       },
        {
            USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300,
            0,
@@ -2403,6 +2605,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "RATOC Systems, Inc.",
            "USB serial adapter REX-USB60",
        },
+       {
+           USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ML6060,
+           0,
+           "Samsung Electronics",
+           "ML-6060 laser printer",
+       },
        {
            USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A,
            0,
@@ -2517,12 +2725,24 @@ struct usb_knowndev usb_knowndevs[] = {
            "Shuttle Technology",
            "CD-RW Device",
        },
+       {
+           USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBORCA,
+           0,
+           "Shuttle Technology",
+           "eUSB ORCA Quad Reader",
+       },
        {
            USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM,
            0,
            "Siemens",
            "SpeedStream USB",
        },
+       {
+           USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100,
+           0,
+           "Sigmatel",
+           "i-Bead 100 MP3 Player",
+       },
        {
            USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER,
            0,
@@ -2583,6 +2803,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Standard Microsystems",
            "USB Hub",
        },
+       {
+           USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WUSB,
+           0,
+           "Standard Microsystems",
+           "2662W-AR Wireless Adapter",
+       },
        {
            USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100,
            0,
@@ -2613,12 +2839,36 @@ struct usb_knowndev usb_knowndevs[] = {
            "Sony",
            "MSC memory stick slot",
        },
+       {
+           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35,
+           0,
+           "Sony",
+           "Sony Clie v3.5",
+       },
        {
            USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40,
            0,
            "Sony",
            "Sony Clie v4.0",
        },
+       {
+           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS,
+           0,
+           "Sony",
+           "Sony Clie v4.0 Memory Stick slot",
+       },
+       {
+           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360,
+           0,
+           "Sony",
+           "Sony Clie s360",
+       },
+       {
+           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41_MS,
+           0,
+           "Sony",
+           "Sony Clie v4.1 Memory Stick slot",
+       },
        {
            USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41,
            0,
@@ -2626,10 +2876,22 @@ struct usb_knowndev usb_knowndevs[] = {
            "Sony Clie v4.1",
        },
        {
-           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_50,
+           USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60,
            0,
            "Sony",
-           "Sony Clie v5.0",
+           "Sony Clie nx60",
+       },
+       {
+           USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8,
+           0,
+           "SOURCENEXT",
+           "KeikaiDenwa 8",
+       },
+       {
+           USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG,
+           0,
+           "SOURCENEXT",
+           "KeikaiDenwa 8 with charger",
        },
        {
            USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR,
@@ -2763,6 +3025,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Thrustmaster",
            "Fusion Digital Gamepad",
        },
+       {
+           USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_POCKETPC_E740,
+           0,
+           "Toshiba Corporation",
+           "PocketPC e740",
+       },
        {
            USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE,
            0,
@@ -2823,6 +3091,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Universal Access",
            "Panache Surf USB ISDN Adapter",
        },
+       {
+           USB_VENDOR_VIDZMEDIA, USB_PRODUCT_VIDZMEDIA_MONSTERTV,
+           0,
+           "VidzMedia Pte Ltd",
+           "MonsterTV P2H",
+       },
        {
            USB_VENDOR_VISION, USB_PRODUCT_VISION_VC6452V002,
            0,
@@ -2889,6 +3163,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "WACOM",
            "Intuos A5",
        },
+       {
+           USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GD0912U,
+           0,
+           "WACOM",
+           "Intuos 9x12 Graphics Tablet",
+       },
        {
            USB_VENDOR_XIRLINK, USB_PRODUCT_XIRLINK_PCCAM,
            0,
@@ -3213,6 +3493,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Compaq Computers",
            NULL,
        },
+       {
+           USB_VENDOR_HITACHI, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Hitachi, Ltd.",
+           NULL,
+       },
        {
            USB_VENDOR_ACERP, 0,
            USB_KNOWNDEV_NOPROD,
@@ -3393,12 +3679,24 @@ struct usb_knowndev usb_knowndevs[] = {
            "Shuttle Technology",
            NULL,
        },
+       {
+           USB_VENDOR_SAMSUNG, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Samsung Electronics",
+           NULL,
+       },
        {
            USB_VENDOR_ANNABOOKS, 0,
            USB_KNOWNDEV_NOPROD,
            "Annabooks",
            NULL,
        },
+       {
+           USB_VENDOR_JVC, 0,
+           USB_KNOWNDEV_NOPROD,
+           "JVC",
+           NULL,
+       },
        {
            USB_VENDOR_CHICONY, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4053,6 +4351,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "SanDisk Corp",
            NULL,
        },
+       {
+           USB_VENDOR_LOGITEC, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Logitec Corp",
+           NULL,
+       },
        {
            USB_VENDOR_BRIMAX, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4119,6 +4423,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Microtech",
            NULL,
        },
+       {
+           USB_VENDOR_GENERALINSTMNTS, 0,
+           USB_KNOWNDEV_NOPROD,
+           "General Instruments (Motorola)",
+           NULL,
+       },
        {
            USB_VENDOR_OLYMPUS, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4227,6 +4537,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Palm Computing",
            NULL,
        },
+       {
+           USB_VENDOR_SOURCENEXT, 0,
+           USB_KNOWNDEV_NOPROD,
+           "SOURCENEXT",
+           NULL,
+       },
        {
            USB_VENDOR_ACCTON, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4359,6 +4675,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "American Biometric Company",
            NULL,
        },
+       {
+           USB_VENDOR_TOSHIBA, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Toshiba Corporation",
+           NULL,
+       },
        {
            USB_VENDOR_YANO, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4401,6 +4723,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Beckhoff",
            NULL,
        },
+       {
+           USB_VENDOR_INTERSIL, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Intersil",
+           NULL,
+       },
        {
            USB_VENDOR_ALTIUS, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4515,6 +4843,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "Todos Data System",
            NULL,
        },
+       {
+           USB_VENDOR_HAL, 0,
+           USB_KNOWNDEV_NOPROD,
+           "HAL Corporation",
+           NULL,
+       },
        {
            USB_VENDOR_NEC2, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4557,6 +4891,24 @@ struct usb_knowndev usb_knowndevs[] = {
            "Luwen",
            NULL,
        },
+       {
+           USB_VENDOR_SMC3, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Standard Microsystems",
+           NULL,
+       },
+       {
+           USB_VENDOR_PNY, 0,
+           USB_KNOWNDEV_NOPROD,
+           "PNY",
+           NULL,
+       },
+       {
+           USB_VENDOR_HAWKING, 0,
+           USB_KNOWNDEV_NOPROD,
+           "Hawking Technologies",
+           NULL,
+       },
        {
            USB_VENDOR_MOTOROLA, 0,
            USB_KNOWNDEV_NOPROD,
@@ -4647,6 +4999,12 @@ struct usb_knowndev usb_knowndevs[] = {
            "D-Link",
            NULL,
        },
+       {
+           USB_VENDOR_VIDZMEDIA, 0,
+           USB_KNOWNDEV_NOPROD,
+           "VidzMedia Pte Ltd",
+           NULL,
+       },
        {
            USB_VENDOR_DAISY, 0,
            USB_KNOWNDEV_NOPROD,
index b6ea3a9..53002d0 100644 (file)
@@ -58,8 +58,8 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/usb/ubsa.c,v 1.2.2.1 2002/12/11 20:54:47 kan Exp $
- * $DragonFly: src/sys/dev/usbmisc/ubsa/ubsa.c,v 1.3 2003/08/07 21:17:14 dillon Exp $
+ * $FreeBSD: src/sys/dev/usb/ubsa.c,v 1.2.2.2 2003/11/30 12:53:40 akiyama Exp $
+ * $DragonFly: src/sys/dev/usbmisc/ubsa/ubsa.c,v 1.4 2003/12/29 06:42:13 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -237,7 +237,7 @@ Static device_method_t ubsa_methods[] = {
 };
 
 Static driver_t ubsa_driver = {
-       "ubsa",
+       "ucom",
        ubsa_methods,
        sizeof (struct ubsa_softc)
 };
index 3b0fa6a..4813625 100644 (file)
@@ -1,6 +1,6 @@
 /*     $NetBSD: ucom.c,v 1.39 2001/08/16 22:31:24 augustss Exp $       */
-/*     $FreeBSD: src/sys/dev/usb/ucom.c,v 1.24.2.2 2003/01/17 17:32:10 joe Exp $       */
-/*     $DragonFly: src/sys/dev/usbmisc/ucom/ucom.c,v 1.8 2003/08/07 21:17:14 dillon Exp $      */
+/*     $FreeBSD: src/sys/dev/usb/ucom.c,v 1.24.2.5 2003/11/30 12:48:52 akiyama Exp $
+/*     $DragonFly: src/sys/dev/usbmisc/ucom/ucom.c,v 1.9 2003/12/29 06:42:15 dillon Exp $      */
 
 /*-
  * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
@@ -348,7 +348,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr td)
                err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
                                     &sc->sc_bulkin_pipe);
                if (err) {
-                       printf("%s: open bulk out error (addr %d): %s\n",
+                       printf("%s: open bulk in error (addr %d): %s\n",
                               USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no, 
                               usbd_errstr(err));
                        error = EIO;
@@ -358,7 +358,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr td)
                err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
                                     USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
                if (err) {
-                       printf("%s: open bulk in error (addr %d): %s\n",
+                       printf("%s: open bulk out error (addr %d): %s\n",
                               USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no,
                               usbd_errstr(err));
                        error = EIO;
@@ -563,19 +563,23 @@ ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
        DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd));
 
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
-       if (error >= 0) {
+       if (error != ENOIOCTL) {
                DPRINTF(("ucomioctl: l_ioctl: error = %d\n", error));
                return (error);
        }
 
+       s = spltty();
+
        error = ttioctl(tp, cmd, data, flag);
        disc_optim(tp, &tp->t_termios, sc);
-       if (error >= 0) {
+       if (error != ENOIOCTL) {
+               splx(s);
                DPRINTF(("ucomioctl: ttioctl: error = %d\n", error));
                return (error);
        }
 
        if (sc->sc_callback->ucom_ioctl != NULL) {
+               /* XXX splx(s) ? */
                error = sc->sc_callback->ucom_ioctl(sc->sc_parent,
                                                    sc->sc_portno,
                                                    cmd, data, flag, p);
@@ -587,8 +591,6 @@ ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
 
        DPRINTF(("ucomioctl: our cmd = 0x%08lx\n", cmd));
 
-       s = spltty();
-
        switch (cmd) {
        case TIOCSBRK:
                DPRINTF(("ucomioctl: TIOCSBRK\n"));
@@ -983,6 +985,11 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
 
        usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
        DPRINTF(("ucomwritecb: cc = %d\n", cc));
+       if (cc <= sc->sc_opkthdrlen) {
+               printf("%s: sent size too small, cc = %d\n",
+                       USBDEVNAME(sc->sc_dev), cc);
+               goto error;
+       }
 
        /* convert from USB bytes to tty bytes */
        cc -= sc->sc_opkthdrlen;
@@ -1058,9 +1065,21 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
 
        usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL);
        DPRINTF(("ucomreadcb: got %d chars, tp = %p\n", cc, tp));
-       if (sc->sc_callback->ucom_read != NULL)
+       if (cc == 0)
+               goto resubmit;
+
+       if (sc->sc_callback->ucom_read != NULL) {
                sc->sc_callback->ucom_read(sc->sc_parent, sc->sc_portno,
                                           &cp, &cc);
+       }
+
+       if (cc > sc->sc_ibufsize) {
+               printf("%s: invalid receive data size, %d chars\n",
+                       USBDEVNAME(sc->sc_dev), cc);
+               goto resubmit;
+       }
+       if (cc < 1)
+               goto resubmit;
 
        s = spltty();
        if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
@@ -1084,18 +1103,21 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
                               lostcc);
        } else {
                /* Give characters to tty layer. */
-               while (cc-- > 0) {
-                       DPRINTFN(7,("ucomreadcb: char = 0x%02x\n", *cp));
-                       if ((*rint)(*cp++, tp) == -1) {
+               while (cc > 0) {
+                       DPRINTFN(7, ("ucomreadcb: char = 0x%02x\n", *cp));
+                       if ((*rint)(*cp, tp) == -1) {
                                /* XXX what should we do? */
                                printf("%s: lost %d chars\n",
                                       USBDEVNAME(sc->sc_dev), cc);
                                break;
                        }
+                       cc--;
+                       cp++;
                }
        }
        splx(s);
 
+resubmit:
        err = ucomstartread(sc);
        if (err) {
                printf("%s: read start failed\n", USBDEVNAME(sc->sc_dev));
@@ -1141,11 +1163,11 @@ ucomstopread(struct ucom_softc *sc)
        DPRINTF(("ucomstopread: enter\n"));
 
        if (!(sc->sc_state & UCS_RXSTOP)) {
+               sc->sc_state |= UCS_RXSTOP;
                if (sc->sc_bulkin_pipe == NULL) {
                        DPRINTF(("ucomstopread: bulkin pipe NULL\n"));
                        return;
                }
-               sc->sc_state |= UCS_RXSTOP;
                err = usbd_abort_pipe(sc->sc_bulkin_pipe);
                if (err) {
                        DPRINTF(("ucomstopread: err = %s\n",
index df252b4..15223c5 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: uftdi.c,v 1.12 2002/07/18 14:44:10 scw Exp $   */
-/*     $FreeBSD: src/sys/dev/usb/uftdi.c,v 1.3.2.1 2002/11/21 01:28:17 ticso Exp $     */
-/*     $DragonFly: src/sys/dev/usbmisc/uftdi/uftdi.c,v 1.3 2003/08/07 21:17:14 dillon Exp $    */
+/*
+ * $NetBSD: uftdi.c,v 1.12 2002/07/18 14:44:10 scw Exp $
+ * $FreeBSD: src/sys/dev/usb/uftdi.c,v 1.3.2.3 2003/07/21 11:50:06 akiyama Exp $
+ * $DragonFly: src/sys/dev/usbmisc/uftdi/uftdi.c,v 1.4 2003/12/29 06:42:16 dillon Exp $
+ */
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * FTDI FT8U100AX serial adapter driver
  */
 
-/*
- * XXX This driver will not support multiple serial ports.
- * XXX The ucom layer needs to be extended first.
- */
-
 #include <sys/cdefs.h>
 
 #include <sys/param.h>
@@ -121,8 +118,6 @@ struct uftdi_softc {
        u_char                  sc_msr;
        u_char                  sc_lsr;
 
-       u_char                  sc_dying;
-
        u_int                   last_lcr;
 };
 
@@ -295,7 +290,7 @@ uftdi_activate(device_ptr_t self, enum devact act)
        case DVACT_DEACTIVATE:
                if (sc->sc_subdev != NULL)
                        rv = config_deactivate(sc->sc_subdev);
-               sc->sc_dying = 1;
+               sc->sc_ucom.sc_dying = 1;
                break;
        }
        return (rv);
@@ -309,7 +304,7 @@ USB_DETACH(uftdi)
        int rv = 0;
 
        DPRINTF(("uftdi_detach: sc=%p\n", sc));
-       sc->sc_dying = 1;
+       sc->sc_ucom.sc_dying = 1;
        rv = ucom_detach(&sc->sc_ucom);
 
        return rv;
@@ -319,14 +314,14 @@ Static int
 uftdi_open(void *vsc, int portno)
 {
        struct uftdi_softc *sc = vsc;
-       struct ucom_softc *ucom = (struct ucom_softc *) vsc;
+       struct ucom_softc *ucom = &sc->sc_ucom;
        usb_device_request_t req;
        usbd_status err;
        struct termios t;
 
        DPRINTF(("uftdi_open: sc=%p\n", sc));
 
-       if (sc->sc_dying)
+       if (ucom->sc_dying)
                return (EIO);
 
        /* Perform a full reset on the device */
@@ -445,14 +440,14 @@ Static int
 uftdi_param(void *vsc, int portno, struct termios *t)
 {
        struct uftdi_softc *sc = vsc;
-       struct ucom_softc *ucom = vsc;
+       struct ucom_softc *ucom = &sc->sc_ucom;
        usb_device_request_t req;
        usbd_status err;
        int rate=0, data, flow;
 
        DPRINTF(("uftdi_param: sc=%p\n", sc));
 
-       if (sc->sc_dying)
+       if (ucom->sc_dying)
                return (EIO);
 
        switch (sc->sc_type) {
index 6349435..bd5571b 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: ulpt.c,v 1.29 1999/11/17 23:00:50 augustss Exp $       */
-/*     $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.26.2.13 2002/11/06 20:23:50 joe Exp $      */
-/*     $DragonFly: src/sys/dev/usbmisc/ulpt/ulpt.c,v 1.5 2003/08/07 21:17:14 dillon Exp $      */
+/*
+ * $NetBSD: ulpt.c,v 1.29 1999/11/17 23:00:50 augustss Exp $
+ * $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.26.2.14 2003/06/22 13:54:30 iedowse Exp $
+ * $DragonFly: src/sys/dev/usbmisc/ulpt/ulpt.c,v 1.6 2003/12/29 06:42:17 dillon Exp $
+ */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -410,8 +412,13 @@ ulptopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
 #endif
 
 
-       if ((flags & ULPT_NOPRIME) == 0)
+       if ((flags & ULPT_NOPRIME) == 0) {
                ulpt_reset(sc);
+               if (sc->sc_dying) {
+                       sc->sc_state = 0;
+                       return (ENXIO);
+               }
+       }
 
        for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
                if (spin >= TIMEOUT) {
index 523a8b1..d814ff1 100644 (file)
@@ -24,9 +24,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/usb/umass.c,v 1.11.2.19 2003/05/17 21:45:27 njl Exp $
- *     $DragonFly: src/sys/dev/usbmisc/umass/umass.c,v 1.4 2003/11/15 21:05:42 dillon Exp $
- *     $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
+ * $FreeBSD: src/sys/dev/usb/umass.c,v 1.11.2.22 2003/12/22 20:30:25 sanpei Exp $
+ * $DragonFly: src/sys/dev/usbmisc/umass/umass.c,v 1.5 2003/12/29 06:42:19 dillon Exp $
+ * $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
  */
 
 /*
@@ -613,6 +613,12 @@ umass_match_proto(struct umass_softc *sc, usbd_interface_handle iface,
                return(UMATCH_VENDOR_PRODUCT);
        }
 
+       if (UGETW(dd->idVendor) == USB_VENDOR_SIGMATEL &&
+           UGETW(dd->idProduct) == USB_PRODUCT_SIGMATEL_I_BEAD100) {
+               /* XXX Really need SHUTTLE_INIT quirk from FreeBSD-current */
+               sc->drive = SHUTTLE_EUSB;
+       }
+
        /*
         * The Pentax Optio cameras require RS_NO_CLEAR_UA
         * PR: kern/46369, kern/50271
@@ -688,8 +694,29 @@ umass_match_proto(struct umass_softc *sc, usbd_interface_handle iface,
            UGETW(dd->idProduct) == USB_PRODUCT_MELCO_DUBPXXG) {
                sc->quirks |= FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE;
        }
-       
-       
+
+       if (UGETW(dd->idVendor) == USB_VENDOR_MSYSTEMS &&
+           UGETW(dd->idProduct) == USB_PRODUCT_MSYSTEMS_DISKONKEY2) {
+               sc->proto = UMASS_PROTO_ATAPI | UMASS_PROTO_BBB;
+       }
+       /* Logitec DVD multi plus unit */
+       if (UGETW(dd->idVendor) == USB_VENDOR_LOGITEC &&
+           UGETW(dd->idProduct) == USB_PRODUCT_LOGITEC_LDR_H443U2) {
+               sc->proto = UMASS_PROTO_SCSI;
+       }
+       if (UGETW(dd->idVendor) == USB_VENDOR_PANASONIC &&
+           UGETW(dd->idProduct) == USB_PRODUCT_PANASONIC_KXLCB20AN) {
+               sc->proto = UMASS_PROTO_SCSI | UMASS_PROTO_BBB;
+       }
+       if (UGETW(dd->idVendor) == USB_VENDOR_PANASONIC &&
+           UGETW(dd->idProduct) == USB_PRODUCT_PANASONIC_KXLCB35AN) {
+               sc->proto = UMASS_PROTO_SCSI | UMASS_PROTO_BBB;
+       }
+       if (UGETW(dd->idVendor) == USB_VENDOR_PNY &&
+           UGETW(dd->idProduct) == USB_PRODUCT_PNY_ATTACHE) {
+               sc->proto = UMASS_PROTO_SCSI | UMASS_PROTO_BBB;
+               sc->quirks |= IGNORE_RESIDUE;
+       }
        
        switch (id->bInterfaceSubClass) {
        case UISUBCLASS_SCSI:
@@ -2358,7 +2385,7 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
                cpi->version_num = 1;
                cpi->hba_inquiry = 0;
                cpi->target_sprt = 0;
-               cpi->hba_misc = 0;
+               cpi->hba_misc = PIM_NO_6_BYTE;
                cpi->hba_eng_cnt = 0;
                cpi->max_target = UMASS_SCSIID_MAX;     /* one target */
                if (sc == NULL)
index fd91234..e5e7d18 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: uplcom.c,v 1.20 2001/07/31 12:33:11 ichiro Exp $       */
-/*     $FreeBSD: src/sys/dev/usb/uplcom.c,v 1.8.2.1 2002/08/08 18:45:04 joe Exp $      */
-/*     $DragonFly: src/sys/dev/usbmisc/uplcom/uplcom.c,v 1.3 2003/08/07 21:17:15 dillon Exp $  */
+/*
+ * $NetBSD: uplcom.c,v 1.20 2001/07/31 12:33:11 ichiro Exp $
+ * $FreeBSD: src/sys/dev/usb/uplcom.c,v 1.8.2.5 2003/11/30 13:05:37 akiyama Exp $
+ * $DragonFly: src/sys/dev/usbmisc/uplcom/uplcom.c,v 1.4 2003/12/29 06:42:20 dillon Exp $
+ */
 
 /*-
  * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
 
 #include "../ucom/ucomvar.h"
 
+SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
 #ifdef USB_DEBUG
 static int     uplcomdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
 SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW,
           &uplcomdebug, 0, "uplcom debug level");
 
@@ -123,7 +125,9 @@ SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW,
 #define        UPLCOM_IFACE_INDEX              0
 #define        UPLCOM_SECOND_IFACE_INDEX       1
 
+#ifndef UPLCOM_INTR_INTERVAL
 #define UPLCOM_INTR_INTERVAL           100     /* ms */
+#endif
 
 #define        UPLCOM_SET_REQUEST              0x01
 #define        UPLCOM_SET_CRTSCTS              0x41
@@ -205,6 +209,12 @@ static const struct uplcom_product {
        { USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60 },
        /* ELECOM UC-SGT */
        { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT },
+       /* SOURCENEXT KeikaiDenwa 8 */
+       { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8 },
+       /* SOURCENEXT KeikaiDenwa 8 with charger */
+       { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG },
+       /* HAL Corporation Crossam2+USB */
+       { USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001 },
        { 0, 0 }
 };
 
@@ -221,7 +231,7 @@ Static device_method_t uplcom_methods[] = {
 };
 
 Static driver_t uplcom_driver = {
-       "uplcom",
+       "ucom",
        uplcom_methods,
        sizeof (struct uplcom_softc)
 };
@@ -231,6 +241,29 @@ MODULE_DEPEND(uplcom, usb, 1, 1, 1);
 MODULE_DEPEND(uplcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
 MODULE_VERSION(uplcom, UPLCOM_MODVER);
 
+static int     uplcominterval = UPLCOM_INTR_INTERVAL;
+
+static int
+sysctl_hw_usb_uplcom_interval(SYSCTL_HANDLER_ARGS)
+{
+       int err, val;
+
+       val = uplcominterval;
+       err = sysctl_handle_int(oidp, &val, sizeof(val), req);
+       if (err != 0 || req->newptr == NULL)
+               return (err);
+       if (0 < val && val <= 1000)
+               uplcominterval = val;
+       else
+               err = EINVAL;
+
+       return (err);
+}
+
+SYSCTL_PROC(_hw_usb_uplcom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
+       0, sizeof(int), sysctl_hw_usb_uplcom_interval,
+       "I", "uplcom interrpt pipe interval");
+
 USB_MATCH(uplcom)
 {
        USB_MATCH_START(uplcom, uaa);
@@ -695,7 +728,7 @@ uplcom_open(void *addr, int portno)
                                          sc->sc_intr_buf,
                                          sc->sc_isize,
                                          uplcom_intr,
-                                         UPLCOM_INTR_INTERVAL);
+                                         uplcominterval);
                if (err) {
                        printf("%s: cannot open interrupt pipe (addr %d)\n",
                               USBDEVNAME(sc->sc_ucom.sc_dev),
index c793d29..ab5032e 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: uscanner.c,v 1.26 2001/12/31 12:15:22 augustss Exp $   */
-/*     $FreeBSD: src/sys/dev/usb/uscanner.c,v 1.2.2.12 2003/01/27 09:48:57 joe Exp $   */
-/*     $DragonFly: src/sys/dev/usbmisc/uscanner/uscanner.c,v 1.4 2003/08/07 21:17:15 dillon Exp $      */
+/* 
+ * $NetBSD: uscanner.c,v 1.26 2001/12/31 12:15:22 augustss Exp $
+ * $FreeBSD: src/sys/dev/usb/uscanner.c,v 1.2.2.16 2003/12/22 20:00:55 sanpei Exp $
+ * $DragonFly: src/sys/dev/usbmisc/uscanner/uscanner.c,v 1.5 2003/12/29 06:42:21 dillon Exp $
+ */
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -140,9 +142,13 @@ static const struct uscan_info uscanner_devs[] = {
  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 }, 0 },
  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL }, 0 },
 
+  /* Minolta */
+ {{ USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400 }, 0 },
+
   /* Mustek */
  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 0 },
+ {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA }, 0 },
  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB }, 0 },
  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU }, 0 },
  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB }, 0 },
@@ -174,6 +180,7 @@ static const struct uscan_info uscanner_devs[] = {
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 },
@@ -181,6 +188,7 @@ static const struct uscan_info uscanner_devs[] = {
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260 }, 0 },
  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9300UF }, 0 },
 
   /* UMAX */
  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
index 42d1874..011c51b 100644 (file)
@@ -1,6 +1,8 @@
-/*     $NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $      */
-/*      $FreeBSD: src/sys/dev/usb/uvisor.c,v 1.7.2.3 2002/08/27 13:46:28 joe Exp $     */
-/*      $DragonFly: src/sys/dev/usbmisc/uvisor/uvisor.c,v 1.3 2003/08/07 21:17:15 dillon Exp $ */
+/*
+ * $NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $
+ * $FreeBSD: src/sys/dev/usb/uvisor.c,v 1.7.2.7 2003/11/12 00:19:50 joe Exp $
+ * $DragonFly: src/sys/dev/usbmisc/uvisor/uvisor.c,v 1.4 2003/12/29 06:42:22 dillon Exp $
+ */
 
 /* This version of uvisor is heavily based upon the version in NetBSD
  * but is missing the following patches:
@@ -144,7 +146,17 @@ struct uvisor_connection_info {
 #define UVISOR_GET_PALM_INFORMATION_LEN                0x14
 
 
-#define UVISORIBUFSIZE 1024
+/*
+ * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
+ * the Palm device and the USB host controller deadlock. The USB host
+ * controller is expecting an early-end-of-transmission packet with 0
+ * data, and the Palm doesn't send one because it's already
+ * communicated the amount of data it's going to send in a header
+ * (which ucom/uvisor are oblivious to). This is the problem that has
+ * been known on the pilot-link lists as the "[Free]BSD USB problem",
+ * but not understood.
+ */
+#define UVISORIBUFSIZE 64
 #define UVISOROBUFSIZE 1024
 
 struct uvisor_softc {
@@ -186,6 +198,7 @@ Static driver_t uvisor_driver = {
 };
 
 DRIVER_MODULE(uvisor, uhub, uvisor_driver, ucom_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(uvisor, usb, 1, 1, 1);
 MODULE_DEPEND(uvisor, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
 MODULE_VERSION(uvisor, UVISOR_MODVER);
 
@@ -196,12 +209,20 @@ struct uvisor_type {
 };
 static const struct uvisor_type uvisor_devs[] = {
        {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, 0 },
+       {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M515 }, PALM4 },
+       {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_I705 }, PALM4 },
        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
-       {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
+       {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M130 }, PALM4 },
+       {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
+       {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
+       {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
+       {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, 0 },
        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, 0 },
+       {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
+       {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
 /*     {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
 };
 #define uvisor_lookup(v, p) ((const struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
index 086b4e4..2355797 100644 (file)
@@ -23,8 +23,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/kern/subr_taskqueue.c,v 1.1.2.2 2001/03/31 03:33:44 hsu Exp $
- *     $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.3 2003/06/29 03:28:44 dillon Exp $
+ *      $FreeBSD: src/sys/kern/subr_taskqueue.c,v 1.1.2.3 2003/09/10 00:40:39 ken Exp $
+ *     $DragonFly: src/sys/kern/subr_taskqueue.c,v 1.4 2003/12/29 06:42:06 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/taskqueue.h>
 #include <sys/interrupt.h>
 #include <sys/malloc.h>
+#include <sys/kthread.h>
+
 #include <machine/ipl.h>
 
 MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues");
 
 static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues;
+static struct thread *taskqueue_thread_td;
 
 struct taskqueue {
        STAILQ_ENTRY(taskqueue) tq_link;
@@ -200,5 +203,28 @@ taskqueue_swi_run(void *arg)
        taskqueue_run(taskqueue_swi);
 }
 
+static void
+taskqueue_kthread(void *arg)
+{
+       int s;
+
+       for (;;) {
+               taskqueue_run(taskqueue_thread);
+               s = splhigh();
+               if (STAILQ_EMPTY(&taskqueue_thread->tq_queue))
+                       tsleep(&taskqueue_thread, 0, "tqthr", 0);
+               splx(s);
+       }
+}
+
+static void
+taskqueue_thread_enqueue(void *context)
+{
+       wakeup(&taskqueue_thread);
+}
+
 TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0,
                 register_swi(SWI_TQ, taskqueue_swi_run, NULL, "swi_taskq"));
+TASKQUEUE_DEFINE(thread, taskqueue_thread_enqueue, 0,
+                kthread_create(taskqueue_kthread, NULL,
+                &taskqueue_thread_td, "taskqueue"));
index d4f4a77..213d651 100644 (file)
@@ -23,8 +23,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/sys/taskqueue.h,v 1.3.2.1 2000/07/18 21:12:41 dfr Exp $
- * $DragonFly: src/sys/sys/taskqueue.h,v 1.2 2003/06/17 04:28:59 dillon Exp $
+ * $FreeBSD: src/sys/sys/taskqueue.h,v 1.3.2.2 2003/09/10 00:40:39 ken Exp $
+ * $DragonFly: src/sys/sys/taskqueue.h,v 1.3 2003/12/29 06:42:07 dillon Exp $
  */
 
 #ifndef _SYS_TASKQUEUE_H_
@@ -113,4 +113,10 @@ struct __hack
  */
 TASKQUEUE_DECLARE(swi);
 
+/*
+ * This queue is serviced by a kernel thread.  To enqueue a task, call
+ * taskqueue_enqueue(taskqueue_thread, &task).
+ */
+TASKQUEUE_DECLARE(thread);
+
 #endif /* !_SYS_TASKQUEUE_H_ */