svn commit: r283174 - in stable/9: share/man/man4 sys/dev/usb sys/dev/usb/quirk
Hans Petter Selasky
hselasky at FreeBSD.org
Thu May 21 06:53:57 UTC 2015
Author: hselasky
Date: Thu May 21 06:53:55 2015
New Revision: 283174
URL: https://svnweb.freebsd.org/changeset/base/283174
Log:
MFC r282577:
Add support for DYMO LabelWriter PnP.
Modified:
stable/9/share/man/man4/usb_quirk.4
stable/9/sys/dev/usb/quirk/usb_quirk.c
stable/9/sys/dev/usb/quirk/usb_quirk.h
stable/9/sys/dev/usb/usb_device.c
stable/9/sys/dev/usb/usb_msctest.c
stable/9/sys/dev/usb/usb_msctest.h
stable/9/sys/dev/usb/usbdevs
Directory Properties:
stable/9/share/ (props changed)
stable/9/share/man/ (props changed)
stable/9/share/man/man4/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/share/man/man4/usb_quirk.4
==============================================================================
--- stable/9/share/man/man4/usb_quirk.4 Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/share/man/man4/usb_quirk.4 Thu May 21 06:53:55 2015 (r283174)
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 8, 2012
+.Dd May 7, 2015
.Dt USB_QUIRK 4
.Os
.Sh NAME
@@ -170,6 +170,9 @@ ejects after Huawei SCSI command
.It UQ_MSC_EJECT_TCT
ejects after TCT SCSI command
.Dv 0x06f504025270
+.It UQ_MSC_DYMO_EJECT
+ejects after HID command
+.Dv 0x1b5a01
.El
.Pp
See
Modified: stable/9/sys/dev/usb/quirk/usb_quirk.c
==============================================================================
--- stable/9/sys/dev/usb/quirk/usb_quirk.c Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/quirk/usb_quirk.c Thu May 21 06:53:55 2015 (r283174)
@@ -522,6 +522,9 @@ static struct usb_quirk_entry usb_quirks
USB_QUIRK(FEIYA, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
USB_QUIRK(REALTEK, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
USB_QUIRK(INITIO, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
+
+ /* DYMO LabelManager Pnp */
+ USB_QUIRK(DYMO, LABELMANAGERPNP, 0x0000, 0xffff, UQ_MSC_DYMO_EJECT),
};
#undef USB_QUIRK_VP
#undef USB_QUIRK
@@ -592,6 +595,7 @@ static const char *usb_quirk_str[USB_QUI
[UQ_BAD_MIDI] = "UQ_BAD_MIDI",
[UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS",
[UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI",
+ [UQ_MSC_DYMO_EJECT] = "UQ_MSC_DYMO_EJECT",
};
/*------------------------------------------------------------------------*
Modified: stable/9/sys/dev/usb/quirk/usb_quirk.h
==============================================================================
--- stable/9/sys/dev/usb/quirk/usb_quirk.h Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/quirk/usb_quirk.h Thu May 21 06:53:55 2015 (r283174)
@@ -109,6 +109,7 @@ enum {
UQ_BAD_MIDI, /* device claims MIDI class, but isn't */
UQ_AU_VENDOR_CLASS, /* audio device uses vendor and not audio class */
UQ_SINGLE_CMD_MIDI, /* at most one command per USB packet */
+ UQ_MSC_DYMO_EJECT, /* ejects Dymo MSC device */
USB_QUIRK_MAX
};
Modified: stable/9/sys/dev/usb/usb_device.c
==============================================================================
--- stable/9/sys/dev/usb/usb_device.c Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/usb_device.c Thu May 21 06:53:55 2015 (r283174)
@@ -1313,6 +1313,12 @@ usb_probe_and_attach(struct usb_device *
*/
if (iface_index == USB_IFACE_INDEX_ANY) {
+ if (usb_test_quirk(&uaa, UQ_MSC_DYMO_EJECT) != 0 &&
+ usb_dymo_eject(udev, 0) == 0) {
+ /* success, mark the udev as disappearing */
+ uaa.dev_state = UAA_DEV_EJECTING;
+ }
+
EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
if (uaa.dev_state != UAA_DEV_READY) {
Modified: stable/9/sys/dev/usb/usb_msctest.c
==============================================================================
--- stable/9/sys/dev/usb/usb_msctest.c Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/usb_msctest.c Thu May 21 06:53:55 2015 (r283174)
@@ -173,6 +173,7 @@ static usb_callback_t bbb_data_rd_cs_cal
static usb_callback_t bbb_data_write_callback;
static usb_callback_t bbb_data_wr_cs_callback;
static usb_callback_t bbb_status_callback;
+static usb_callback_t bbb_raw_write_callback;
static void bbb_done(struct bbb_transfer *, int);
static void bbb_transfer_start(struct bbb_transfer *, uint8_t);
@@ -180,7 +181,7 @@ static void bbb_data_clear_stall_callbac
uint8_t);
static int bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
void *, size_t, void *, size_t, usb_timeout_t);
-static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t);
+static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t, uint8_t);
static void bbb_detach(struct bbb_transfer *);
static const struct usb_config bbb_config[ST_MAX] = {
@@ -243,6 +244,19 @@ static const struct usb_config bbb_confi
},
};
+static const struct usb_config bbb_raw_config[1] = {
+
+ [0] = {
+ .type = UE_BULK_INTR,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .bufsize = SCSI_MAX_LEN,
+ .flags = {.ext_buffer = 1,.proxy_buffer = 1,},
+ .callback = &bbb_raw_write_callback,
+ .timeout = 1 * USB_MS_HZ, /* 1 second */
+ },
+};
+
static void
bbb_done(struct bbb_transfer *sc, int error)
{
@@ -463,6 +477,47 @@ bbb_status_callback(struct usb_xfer *xfe
}
}
+static void
+bbb_raw_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ struct bbb_transfer *sc = usbd_xfer_softc(xfer);
+ usb_frlength_t max_bulk = usbd_xfer_max_len(xfer);
+ int actlen, sumlen;
+
+ usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ sc->data_rem -= actlen;
+ sc->data_ptr += actlen;
+ sc->actlen += actlen;
+
+ if (actlen < sumlen) {
+ /* short transfer */
+ sc->data_rem = 0;
+ }
+ case USB_ST_SETUP:
+ DPRINTF("max_bulk=%d, data_rem=%d\n",
+ max_bulk, sc->data_rem);
+
+ if (sc->data_rem == 0) {
+ bbb_done(sc, 0);
+ break;
+ }
+ if (max_bulk > sc->data_rem) {
+ max_bulk = sc->data_rem;
+ }
+ usbd_xfer_set_timeout(xfer, sc->data_timeout);
+ usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
+ usbd_transfer_submit(xfer);
+ break;
+
+ default: /* Error */
+ bbb_done(sc, error);
+ break;
+ }
+}
+
/*------------------------------------------------------------------------*
* bbb_command_start - execute a SCSI command synchronously
*
@@ -498,13 +553,45 @@ bbb_command_start(struct bbb_transfer *s
return (sc->error);
}
+/*------------------------------------------------------------------------*
+ * bbb_raw_write - write a raw BULK message synchronously
+ *
+ * Return values
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+static int
+bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len,
+ usb_timeout_t data_timeout)
+{
+ sc->data_ptr = __DECONST(void *, data_ptr);
+ sc->data_len = data_len;
+ sc->data_rem = data_len;
+ sc->data_timeout = (data_timeout + USB_MS_HZ);
+ sc->actlen = 0;
+ sc->error = 0;
+
+ DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
+ (const char *)data_ptr, ":");
+
+ mtx_lock(&sc->mtx);
+ usbd_transfer_start(sc->xfer[0]);
+ while (usbd_transfer_pending(sc->xfer[0]))
+ cv_wait(&sc->cv, &sc->mtx);
+ mtx_unlock(&sc->mtx);
+ return (sc->error);
+}
+
static struct bbb_transfer *
-bbb_attach(struct usb_device *udev, uint8_t iface_index)
+bbb_attach(struct usb_device *udev, uint8_t iface_index,
+ uint8_t bInterfaceClass)
{
struct usb_interface *iface;
struct usb_interface_descriptor *id;
+ const struct usb_config *pconfig;
struct bbb_transfer *sc;
usb_error_t err;
+ int nconfig;
uint8_t do_unlock;
/* Prevent re-enumeration */
@@ -524,22 +611,39 @@ bbb_attach(struct usb_device *udev, uint
return (NULL);
id = iface->idesc;
- if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+ if (id == NULL || id->bInterfaceClass != bInterfaceClass)
return (NULL);
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- case UISUBCLASS_UFI:
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
+ switch (id->bInterfaceClass) {
+ case UICLASS_MASS:
+ switch (id->bInterfaceSubClass) {
+ case UISUBCLASS_SCSI:
+ case UISUBCLASS_UFI:
+ case UISUBCLASS_SFF8020I:
+ case UISUBCLASS_SFF8070I:
+ break;
+ default:
+ return (NULL);
+ }
+ switch (id->bInterfaceProtocol) {
+ case UIPROTO_MASS_BBB_OLD:
+ case UIPROTO_MASS_BBB:
+ break;
+ default:
+ return (NULL);
+ }
+ pconfig = bbb_config;
+ nconfig = ST_MAX;
break;
- default:
- return (NULL);
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
+ case UICLASS_HID:
+ switch (id->bInterfaceSubClass) {
+ case 0:
+ break;
+ default:
+ return (NULL);
+ }
+ pconfig = bbb_raw_config;
+ nconfig = 1;
break;
default:
return (NULL);
@@ -549,22 +653,27 @@ bbb_attach(struct usb_device *udev, uint
mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF);
cv_init(&sc->cv, "WBBB");
- err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
- ST_MAX, sc, &sc->mtx);
+ err = usbd_transfer_setup(udev, &iface_index, sc->xfer, pconfig,
+ nconfig, sc, &sc->mtx);
if (err) {
bbb_detach(sc);
return (NULL);
}
- /* store pointer to DMA buffers */
- sc->buffer = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_DATA_RD], 0);
- sc->buffer_size =
- usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
- sc->cbw = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_COMMAND], 0);
- sc->csw = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_STATUS], 0);
-
+ switch (id->bInterfaceClass) {
+ case UICLASS_MASS:
+ /* store pointer to DMA buffers */
+ sc->buffer = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_DATA_RD], 0);
+ sc->buffer_size =
+ usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
+ sc->cbw = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_COMMAND], 0);
+ sc->csw = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_STATUS], 0);
+ break;
+ default:
+ break;
+ }
return (sc);
}
@@ -593,7 +702,7 @@ usb_iface_is_cdrom(struct usb_device *ud
uint8_t sid_type;
int err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (0);
@@ -649,7 +758,7 @@ usb_msc_auto_quirk(struct usb_device *ud
uint8_t sid_type;
int err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (0);
@@ -818,7 +927,7 @@ usb_msc_eject(struct usb_device *udev, u
struct bbb_transfer *sc;
usb_error_t err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (USB_ERR_INVAL);
@@ -877,3 +986,19 @@ usb_msc_eject(struct usb_device *udev, u
bbb_detach(sc);
return (0);
}
+
+usb_error_t
+usb_dymo_eject(struct usb_device *udev, uint8_t iface_index)
+{
+ static const uint8_t data[3] = { 0x1b, 0x5a, 0x01 };
+ struct bbb_transfer *sc;
+ usb_error_t err;
+
+ sc = bbb_attach(udev, iface_index, UICLASS_HID);
+ if (sc == NULL)
+ return (USB_ERR_INVAL);
+ err = bbb_raw_write(sc, data, sizeof(data), USB_MS_HZ);
+ bbb_detach(sc);
+ return (err);
+}
+
Modified: stable/9/sys/dev/usb/usb_msctest.h
==============================================================================
--- stable/9/sys/dev/usb/usb_msctest.h Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/usb_msctest.h Thu May 21 06:53:55 2015 (r283174)
@@ -43,5 +43,7 @@ usb_error_t usb_msc_eject(struct usb_dev
uint8_t iface_index, int method);
usb_error_t usb_msc_auto_quirk(struct usb_device *udev,
uint8_t iface_index);
+usb_error_t usb_dymo_eject(struct usb_device *udev,
+ uint8_t iface_index);
#endif /* _USB_MSCTEST_H_ */
Modified: stable/9/sys/dev/usb/usbdevs
==============================================================================
--- stable/9/sys/dev/usb/usbdevs Thu May 21 06:47:20 2015 (r283173)
+++ stable/9/sys/dev/usb/usbdevs Thu May 21 06:53:55 2015 (r283174)
@@ -452,6 +452,7 @@ vendor GLOBESPAN 0x0915 Globespan
vendor CONCORDCAMERA 0x0919 Concord Camera
vendor GARMIN 0x091e Garmin International
vendor GOHUBS 0x0921 GoHubs
+vendor DYMO 0x0922 DYMO
vendor XEROX 0x0924 Xerox
vendor BIOMETRIC 0x0929 American Biometric Company
vendor TOSHIBA 0x0930 Toshiba
@@ -1670,6 +1671,9 @@ product DRESDENELEKTRONIK WIRELESSHANDHE
product DRESDENELEKTRONIK DE_RFNODE 0x001c deRFnode
product DRESDENELEKTRONIK LEVELSHIFTERSTICKLOWCOST 0x0022 Levelshifter Stick Low Cost
+/* DYMO */
+product DYMO LABELMANAGERPNP 0x1001 DYMO LabelManager PnP
+
/* Dynastream Innovations */
product DYNASTREAM ANTDEVBOARD 0x1003 ANT dev board
product DYNASTREAM ANT2USB 0x1004 ANT2USB
More information about the svn-src-stable-9
mailing list