mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 06:32:44 +00:00
Sync with NetBSD:
Add USB_SET_REPORT ioctl. Add FIOASYNC, TIOCSPGRP ioctl. Change some debugging output
This commit is contained in:
parent
e30ce7f9de
commit
23f027a0bc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=60551
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uhid.c,v 1.27 1999/11/12 00:34:57 augustss Exp $ */
|
||||
/* $NetBSD: uhid.c,v 1.38 2000/04/27 15:26:48 augustss Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -46,6 +46,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/signalvar.h>
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -83,6 +84,7 @@ int uhiddebug = 0;
|
||||
|
||||
struct uhid_softc {
|
||||
USBBASEDEVICE sc_dev; /* base device */
|
||||
usbd_device_handle sc_udev;
|
||||
usbd_interface_handle sc_iface; /* interface */
|
||||
usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
|
||||
int sc_ep_addr;
|
||||
@ -94,14 +96,15 @@ struct uhid_softc {
|
||||
u_int8_t sc_oid;
|
||||
u_int8_t sc_fid;
|
||||
|
||||
char *sc_ibuf;
|
||||
char *sc_obuf;
|
||||
u_char *sc_ibuf;
|
||||
u_char *sc_obuf;
|
||||
|
||||
void *sc_repdesc;
|
||||
int sc_repdesc_size;
|
||||
|
||||
struct clist sc_q;
|
||||
struct selinfo sc_rsel;
|
||||
struct proc *sc_async; /* process that wants SIGIO */
|
||||
u_char sc_state; /* driver state */
|
||||
#define UHID_OPEN 0x01 /* device is open */
|
||||
#define UHID_ASLP 0x02 /* waiting for device data */
|
||||
@ -184,6 +187,7 @@ USB_ATTACH(uhid)
|
||||
usbd_status err;
|
||||
char devinfo[1024];
|
||||
|
||||
sc->sc_udev = uaa->device;
|
||||
sc->sc_iface = iface;
|
||||
id = usbd_get_interface_descriptor(iface);
|
||||
usbd_devinfo(uaa->device, 0, devinfo);
|
||||
@ -327,9 +331,18 @@ uhid_intr(xfer, addr, status)
|
||||
{
|
||||
struct uhid_softc *sc = addr;
|
||||
|
||||
DPRINTFN(5, ("uhid_intr: status=%d\n", status));
|
||||
DPRINTFN(5, ("uhid_intr: data = %02x %02x %02x\n",
|
||||
sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
|
||||
#ifdef UHID_DEBUG
|
||||
if (uhiddebug > 5) {
|
||||
u_int32_t cc, i;
|
||||
|
||||
usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
|
||||
DPRINTF(("uhid_intr: status=%d cc=%d\n", status, cc));
|
||||
DPRINTF(("uhid_intr: data ="));
|
||||
for (i = 0; i < cc; i++)
|
||||
DPRINTF((" %02x", sc->sc_ibuf[i]));
|
||||
DPRINTF(("\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status == USBD_CANCELLED)
|
||||
return;
|
||||
@ -348,6 +361,10 @@ uhid_intr(xfer, addr, status)
|
||||
wakeup(&sc->sc_q);
|
||||
}
|
||||
selwakeup(&sc->sc_rsel);
|
||||
if (sc->sc_async != NULL) {
|
||||
DPRINTFN(3, ("uhid_intr: sending SIGIO %p\n", sc->sc_async));
|
||||
psignal(sc->sc_async, SIGIO);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -394,6 +411,8 @@ uhidopen(dev, flag, mode, p)
|
||||
|
||||
sc->sc_state &= ~UHID_IMMED;
|
||||
|
||||
sc->sc_async = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -423,6 +442,8 @@ uhidclose(dev, flag, mode, p)
|
||||
|
||||
sc->sc_state &= ~UHID_OPEN;
|
||||
|
||||
sc->sc_async = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -481,7 +502,7 @@ uhid_do_read(sc, uio, flag)
|
||||
|
||||
/* Remove a small chunk from the input queue. */
|
||||
(void) q_to_b(&sc->sc_q, buffer, length);
|
||||
DPRINTFN(5, ("uhidread: got %d chars\n", length));
|
||||
DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
|
||||
|
||||
/* Copy the data to the user process. */
|
||||
if ((error = uiomove(buffer, length, uio)) != 0)
|
||||
@ -584,6 +605,24 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
|
||||
/* All handled in the upper FS layer. */
|
||||
break;
|
||||
|
||||
case FIOASYNC:
|
||||
if (*(int *)addr) {
|
||||
if (sc->sc_async != NULL)
|
||||
return (EBUSY);
|
||||
sc->sc_async = p;
|
||||
DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", p));
|
||||
} else
|
||||
sc->sc_async = NULL;
|
||||
break;
|
||||
|
||||
/* XXX this is not the most general solution. */
|
||||
case TIOCSPGRP:
|
||||
if (sc->sc_async == NULL)
|
||||
return (EINVAL);
|
||||
if (*(int *)addr != sc->sc_async->p_pgid)
|
||||
return (EPERM);
|
||||
break;
|
||||
|
||||
case USB_GET_REPORT_DESC:
|
||||
rd = (struct usb_ctl_report_desc *)addr;
|
||||
size = min(sc->sc_repdesc_size, sizeof rd->data);
|
||||
@ -628,6 +667,30 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
|
||||
return (EIO);
|
||||
break;
|
||||
|
||||
case USB_SET_REPORT:
|
||||
re = (struct usb_ctl_report *)addr;
|
||||
switch (re->report) {
|
||||
case UHID_INPUT_REPORT:
|
||||
size = sc->sc_isize;
|
||||
id = sc->sc_iid;
|
||||
break;
|
||||
case UHID_OUTPUT_REPORT:
|
||||
size = sc->sc_osize;
|
||||
id = sc->sc_oid;
|
||||
break;
|
||||
case UHID_FEATURE_REPORT:
|
||||
size = sc->sc_fsize;
|
||||
id = sc->sc_fid;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
err = usbd_set_report(sc->sc_iface, re->report, id, re->data,
|
||||
size);
|
||||
if (err)
|
||||
return (EIO);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -387,6 +387,8 @@ typedef struct {
|
||||
#define UPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
|
||||
#define UPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
|
||||
#define UPROTO_DATA_VENDOR 0xff /* Vendor specific */
|
||||
#define UCLASS_VENDOR_DA 0xfe /* Doug Ambrisko */
|
||||
#define USUBCLASS_DA 0xda /* Doug Ambrisko */
|
||||
|
||||
|
||||
#define USB_HUB_MAX_DEPTH 5
|
||||
@ -538,6 +540,7 @@ struct usb_event {
|
||||
#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc)
|
||||
#define USB_SET_IMMED _IOW ('U', 22, int)
|
||||
#define USB_GET_REPORT _IOWR('U', 23, struct usb_ctl_report)
|
||||
#define USB_SET_REPORT _IOW ('U', 24, struct usb_ctl_report)
|
||||
|
||||
/* Generic USB device */
|
||||
#define USB_GET_CONFIG _IOR ('U', 100, int)
|
||||
|
Loading…
Reference in New Issue
Block a user