From: Matthew Dillon Date: Mon, 29 Dec 2003 06:42:22 +0000 (+0000) Subject: Synchronize the USB, CAM, and TASKQUEUE subsystems with FreeBSD RELENG_4. X-Git-Tag: v2.0.1~12437 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/62ade75199835623e4339bbce90407aac30101f0 Synchronize the USB, CAM, and TASKQUEUE subsystems with FreeBSD RELENG_4. 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. --- diff --git a/sys/bus/cam/cam_ccb.h b/sys/bus/cam/cam_ccb.h index 3893ac46b7..5ff49290cd 100644 --- a/sys/bus/cam/cam_ccb.h +++ b/sys/bus/cam/cam_ccb.h @@ -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 */ diff --git a/sys/bus/cam/scsi/scsi_all.c b/sys/bus/cam/scsi/scsi_all.c index bfe520314d..0d7e98b43c 100644 --- a/sys/bus/cam/scsi/scsi_all.c +++ b/sys/bus/cam/scsi/scsi_all.c @@ -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 @@ -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. */ diff --git a/sys/bus/cam/scsi/scsi_all.h b/sys/bus/cam/scsi/scsi_all.h index 1fee3687cf..3de4ba4b1a 100644 --- a/sys/bus/cam/scsi/scsi_all.h +++ b/sys/bus/cam/scsi/scsi_all.h @@ -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, diff --git a/sys/bus/cam/scsi/scsi_cd.c b/sys/bus/cam/scsi/scsi_cd.c index f5c001348b..da1938753f 100644 --- a/sys/bus/cam/scsi/scsi_cd.c +++ b/sys/bus/cam/scsi/scsi_cd.c @@ -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 #include #include +#include #include #include @@ -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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.flags &= ~CD_PA_SOTC; - data->page.audio.flags |= CD_PA_IMMED; - error = cdsetmode(periph, data); - free(data, M_TEMP); + page = cdgetpage(¶ms); + + page->audio.flags &= ~CD_PA_SOTC; + page->audio.flags |= CD_PA_IMMED; + error = cdsetmode(periph, ¶ms); + free(params.mode_buf, M_TEMP); if (error) break; - if (softc->quirks & CD_Q_BCD_TRACKS) { - args->start_track = bin2bcd(args->start_track); - args->end_track = bin2bcd(args->end_track); + + /* + * This was originally implemented with the PLAY + * AUDIO TRACK INDEX command, but that command was + * deprecated after SCSI-2. Most (all?) SCSI CDROM + * drives support it but ATAPI and ATAPI-derivative + * drives don't seem to support it. So we keep a + * cache of the table of contents and translate + * track numbers to MSF format. + */ + if (softc->flags & CD_FLAG_VALID_TOC) { + union msf_lba *sentry, *eentry; + int st, et; + + if (args->end_track < + softc->toc.header.ending_track + 1) + args->end_track++; + if (args->end_track > + softc->toc.header.ending_track + 1) + args->end_track = + softc->toc.header.ending_track + 1; + st = args->start_track - + softc->toc.header.starting_track; + et = args->end_track - + softc->toc.header.starting_track; + if ((st < 0) + || (et < 0) + || (st > (softc->toc.header.ending_track - + softc->toc.header.starting_track))) { + error = EINVAL; + break; + } + sentry = &softc->toc.entries[st].addr; + eentry = &softc->toc.entries[et].addr; + error = cdplaymsf(periph, + sentry->msf.minute, + sentry->msf.second, + sentry->msf.frame, + eentry->msf.minute, + eentry->msf.second, + eentry->msf.frame); + } else { + /* + * If we don't have a valid TOC, try the + * play track index command. It is part of + * the SCSI-2 spec, but was removed in the + * MMC specs. ATAPI and ATAPI-derived + * drives don't support it. + */ + if (softc->quirks & CD_Q_BCD_TRACKS) { + args->start_track = + bin2bcd(args->start_track); + args->end_track = + bin2bcd(args->end_track); + } + error = cdplaytracks(periph, + args->start_track, + args->start_index, + args->end_track, + args->end_index); } - error = cdplaytracks(periph, - args->start_track, - args->start_index, - args->end_track, - args->end_index); } break; case CDIOCPLAYMSF: { struct ioc_play_msf *args = (struct ioc_play_msf *) addr; - struct cd_mode_data *data; + struct cd_mode_params params; + union cd_pages *page; - data = malloc(sizeof(struct cd_mode_data), M_TEMP, - M_WAITOK); + params.alloc_len = sizeof(union cd_mode_data_6_10); + params.mode_buf = malloc(params.alloc_len, M_TEMP, + M_WAITOK | M_ZERO); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYMSF\n")); - error = cdgetmode(periph, data, AUDIO_PAGE); + error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.flags &= ~CD_PA_SOTC; - data->page.audio.flags |= CD_PA_IMMED; - error = cdsetmode(periph, data); - free(data, M_TEMP); + page = cdgetpage(¶ms); + + page->audio.flags &= ~CD_PA_SOTC; + page->audio.flags |= CD_PA_IMMED; + error = cdsetmode(periph, ¶ms); + free(params.mode_buf, M_TEMP); if (error) break; error = cdplaymsf(periph, @@ -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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.flags &= ~CD_PA_SOTC; - data->page.audio.flags |= CD_PA_IMMED; - error = cdsetmode(periph, data); - free(data, M_TEMP); + page = cdgetpage(¶ms); + + page->audio.flags &= ~CD_PA_SOTC; + page->audio.flags |= CD_PA_IMMED; + error = cdsetmode(periph, ¶ms); + free(params.mode_buf, M_TEMP); if (error) break; error = cdplay(periph, args->blk, args->len); @@ -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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.port[LEFT_PORT].channels = + page = cdgetpage(¶ms); + + 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, ¶ms); + 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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } + page = cdgetpage(¶ms); + 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, ¶ms, 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(¶ms); + + 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, ¶ms); + 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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.port[LEFT_PORT].channels = + page = cdgetpage(¶ms); + + 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, ¶ms); + 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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(params.mode_buf, M_TEMP); break; } - data->page.audio.port[LEFT_PORT].channels = + page = cdgetpage(¶ms); + + 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, ¶ms); + 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, ¶ms, AUDIO_PAGE); if (error) { - free(data, M_TEMP); + free(¶ms, 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(¶ms); + + 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, ¶ms); + 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, ¶ms, 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(¶ms); + + 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, ¶ms); + 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, ¶ms, 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(¶ms); + + 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, ¶ms); + 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); diff --git a/sys/bus/cam/scsi/scsi_cd.h b/sys/bus/cam/scsi/scsi_cd.h index 154e26d79e..f7cced7c33 100644 --- a/sys/bus/cam/scsi/scsi_cd.h +++ b/sys/bus/cam/scsi/scsi_cd.h @@ -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 *), diff --git a/sys/bus/cam/scsi/scsi_da.c b/sys/bus/cam/scsi/scsi_da.c index b9110bf4f2..f7d5fb02da 100644 --- a/sys/bus/cam/scsi/scsi_da.c +++ b/sys/bus/cam/scsi/scsi_da.c @@ -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 #include #include +#include #endif /* _KERNEL */ #include @@ -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) diff --git a/sys/bus/cam/scsi/scsi_low.c b/sys/bus/cam/scsi/scsi_low.c index c02e733fff..3d57a78555 100644 --- a/sys/bus/cam/scsi/scsi_low.c +++ b/sys/bus/cam/scsi/scsi_low.c @@ -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 diff --git a/sys/bus/cam/scsi/scsi_targ_bh.c b/sys/bus/cam/scsi/scsi_targ_bh.c index 7e6aef672d..8fb2e436f3 100644 --- a/sys/bus/cam/scsi/scsi_targ_bh.c +++ b/sys/bus/cam/scsi/scsi_targ_bh.c @@ -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 #include @@ -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");; } } diff --git a/sys/bus/usb/uhci.c b/sys/bus/usb/uhci.c index cd4995c450..b379495a57 100644 --- a/sys/bus/usb/uhci.c +++ b/sys/bus/usb/uhci.c @@ -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 */ diff --git a/sys/bus/usb/usbdevs b/sys/bus/usb/usbdevs index e205fcd473..4af2b9c7a3 100644 --- a/sys/bus/usb/usbdevs +++ b/sys/bus/usb/usbdevs @@ -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 diff --git a/sys/bus/usb/usbdevs.h b/sys/bus/usb/usbdevs.h index ae4f787b93..c0109a45a4 100644 --- a/sys/bus/usb/usbdevs.h +++ b/sys/bus/usb/usbdevs.h @@ -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 $ */ /* @@ -122,6 +120,7 @@ #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 */ @@ -152,7 +151,9 @@ #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 */ @@ -262,6 +263,7 @@ #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 */ @@ -273,6 +275,7 @@ #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 */ @@ -291,6 +294,7 @@ #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 */ @@ -313,6 +317,7 @@ #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 */ @@ -320,6 +325,7 @@ #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 */ @@ -339,6 +345,7 @@ #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 */ @@ -346,6 +353,9 @@ #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 */ @@ -361,6 +371,7 @@ #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 */ @@ -409,6 +420,9 @@ #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 */ @@ -462,6 +476,7 @@ /* 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 */ @@ -474,6 +489,7 @@ /* 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 */ @@ -485,6 +501,7 @@ #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 */ @@ -499,9 +516,11 @@ #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 */ @@ -544,6 +563,7 @@ #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 */ @@ -613,8 +633,10 @@ #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 */ @@ -649,11 +671,17 @@ /* 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 */ @@ -661,10 +689,17 @@ /* 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 */ @@ -690,12 +725,14 @@ #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 */ @@ -717,6 +754,9 @@ #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 */ @@ -727,6 +767,9 @@ #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 */ @@ -816,8 +859,12 @@ #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 */ @@ -849,8 +896,10 @@ #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 */ @@ -874,6 +923,7 @@ #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 */ @@ -893,11 +943,13 @@ #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 */ @@ -933,9 +985,17 @@ #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 */ @@ -962,6 +1022,9 @@ /* 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 */ @@ -1014,6 +1077,9 @@ /* 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 */ @@ -1040,10 +1106,14 @@ #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 */ @@ -1063,6 +1133,7 @@ #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 */ @@ -1074,9 +1145,17 @@ #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 */ @@ -1103,7 +1182,7 @@ /* 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 */ @@ -1123,6 +1202,9 @@ /* 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 */ @@ -1141,6 +1223,9 @@ /* 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 */ @@ -1152,12 +1237,13 @@ #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 */ diff --git a/sys/bus/usb/usbdevs_data.h b/sys/bus/usb/usbdevs_data.h index 5d8339ff3f..634a85e02c 100644 --- a/sys/bus/usb/usbdevs_data.h +++ b/sys/bus/usb/usbdevs_data.h @@ -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, diff --git a/sys/dev/usbmisc/ubsa/ubsa.c b/sys/dev/usbmisc/ubsa/ubsa.c index b6ea3a990a..53002d00f1 100644 --- a/sys/dev/usbmisc/ubsa/ubsa.c +++ b/sys/dev/usbmisc/ubsa/ubsa.c @@ -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 @@ -237,7 +237,7 @@ Static device_method_t ubsa_methods[] = { }; Static driver_t ubsa_driver = { - "ubsa", + "ucom", ubsa_methods, sizeof (struct ubsa_softc) }; diff --git a/sys/dev/usbmisc/ucom/ucom.c b/sys/dev/usbmisc/ucom/ucom.c index 3b0fa6aadc..48136253e9 100644 --- a/sys/dev/usbmisc/ucom/ucom.c +++ b/sys/dev/usbmisc/ucom/ucom.c @@ -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 . @@ -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", diff --git a/sys/dev/usbmisc/uftdi/uftdi.c b/sys/dev/usbmisc/uftdi/uftdi.c index df252b4a57..15223c5145 100644 --- a/sys/dev/usbmisc/uftdi/uftdi.c +++ b/sys/dev/usbmisc/uftdi/uftdi.c @@ -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. @@ -42,11 +44,6 @@ * FTDI FT8U100AX serial adapter driver */ -/* - * XXX This driver will not support multiple serial ports. - * XXX The ucom layer needs to be extended first. - */ - #include #include @@ -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) { diff --git a/sys/dev/usbmisc/ulpt/ulpt.c b/sys/dev/usbmisc/ulpt/ulpt.c index 63494358b9..bd5571b781 100644 --- a/sys/dev/usbmisc/ulpt/ulpt.c +++ b/sys/dev/usbmisc/ulpt/ulpt.c @@ -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) { diff --git a/sys/dev/usbmisc/umass/umass.c b/sys/dev/usbmisc/umass/umass.c index 523a8b116a..d814ff14bb 100644 --- a/sys/dev/usbmisc/umass/umass.c +++ b/sys/dev/usbmisc/umass/umass.c @@ -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) diff --git a/sys/dev/usbmisc/uplcom/uplcom.c b/sys/dev/usbmisc/uplcom/uplcom.c index fd91234a50..e5e7d18663 100644 --- a/sys/dev/usbmisc/uplcom/uplcom.c +++ b/sys/dev/usbmisc/uplcom/uplcom.c @@ -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 . @@ -102,9 +104,9 @@ #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), diff --git a/sys/dev/usbmisc/uscanner/uscanner.c b/sys/dev/usbmisc/uscanner/uscanner.c index c793d2950b..ab5032e586 100644 --- a/sys/dev/usbmisc/uscanner/uscanner.c +++ b/sys/dev/usbmisc/uscanner/uscanner.c @@ -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 }, diff --git a/sys/dev/usbmisc/uvisor/uvisor.c b/sys/dev/usbmisc/uvisor/uvisor.c index 42d1874ab8..011c51bd9d 100644 --- a/sys/dev/usbmisc/uvisor/uvisor.c +++ b/sys/dev/usbmisc/uvisor/uvisor.c @@ -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)) diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index 086b4e4aaa..23557970ab 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -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 @@ -34,11 +34,14 @@ #include #include #include +#include + #include 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")); diff --git a/sys/sys/taskqueue.h b/sys/sys/taskqueue.h index d4f4a77112..213d651227 100644 --- a/sys/sys/taskqueue.h +++ b/sys/sys/taskqueue.h @@ -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_ */