Changeset View
Changeset View
Standalone View
Standalone View
multimedia/pwcbsd/files/extra-patch-pwc.c
--- ./pwc.c.orig 2007-10-09 09:14:01.000000000 +0200 | --- ./pwc.c.orig 2007-10-09 00:14:01.000000000 -0700 | ||||
+++ ./pwc.c 2010-10-01 23:03:54.190935331 +0200 | +++ ./pwc.c 2022-07-26 09:44:50.872775000 -0700 | ||||
@@ -28,7 +28,8 @@ | @@ -28,7 +28,8 @@ | ||||
#include "pwc-dec1.h" | #include "pwc-dec1.h" | ||||
#include "pwc-dec23.h" | #include "pwc-dec23.h" | ||||
-static void pwc_isoc_handler(usbd_xfer_handle xfer, usbd_private_handle addr,usbd_status status); | -static void pwc_isoc_handler(usbd_xfer_handle xfer, usbd_private_handle addr,usbd_status status); | ||||
+static void pwc_isoc_rx_callback(struct usb_xfer *xfer, usb_error_t err); | +static void pwc_isoc_rx_callback(struct usb_xfer *xfer, usb_error_t err); | ||||
+static void pwc_isoc_handler(struct usb_xfer *xfer, void *addr); | +static void pwc_isoc_handler(struct usb_xfer *xfer, void *addr); | ||||
static void pwc_reset_buffers(struct pwc_softc *sc); | static void pwc_reset_buffers(struct pwc_softc *sc); | ||||
static void pwc_free_buffers(struct pwc_softc *sc, int detach); | static void pwc_free_buffers(struct pwc_softc *sc, int detach); | ||||
@@ -57,55 +58,70 @@ | @@ -57,55 +58,68 @@ | ||||
.d_mmap = pwc_mmap, | .d_mmap = pwc_mmap, | ||||
.d_name = "pwc", | .d_name = "pwc", | ||||
}; | }; | ||||
- | - | ||||
-struct pwc_info { | -struct pwc_info { | ||||
- struct usb_devno devno; | - struct usb_devno devno; | ||||
- int type; | - int type; | ||||
- char *name; | - char *name; | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
-#define pwc_lookup(v, p) ((const struct pwc_info *)usb_lookup(pwc_devs, v, p)) | -#define pwc_lookup(v, p) ((const struct pwc_info *)usb_lookup(pwc_devs, v, p)) | ||||
-#define PWCUNIT(n) (minor(n)) | -#define PWCUNIT(n) (minor(n)) | ||||
-static device_probe_t pwc_match; | -static device_probe_t pwc_match; | ||||
+static device_probe_t pwc_probe; | +static device_probe_t pwc_probe; | ||||
static device_attach_t pwc_attach; | static device_attach_t pwc_attach; | ||||
static device_detach_t pwc_detach; | static device_detach_t pwc_detach; | ||||
static devclass_t pwc_devclass; | -static devclass_t pwc_devclass; | ||||
- | |||||
static device_method_t pwc_methods[] = { | static device_method_t pwc_methods[] = { | ||||
- DEVMETHOD(device_probe, pwc_match), | - DEVMETHOD(device_probe, pwc_match), | ||||
+ DEVMETHOD(device_probe, pwc_probe), | + DEVMETHOD(device_probe, pwc_probe), | ||||
DEVMETHOD(device_attach, pwc_attach), | DEVMETHOD(device_attach, pwc_attach), | ||||
DEVMETHOD(device_detach, pwc_detach), | DEVMETHOD(device_detach, pwc_detach), | ||||
{0,0}, | {0,0}, | ||||
@@ -120,41 +136,25 @@ | @@ -120,41 +134,25 @@ | ||||
MODULE_DEPEND(pwc, usb, 1, 1, 1); | MODULE_DEPEND(pwc, usb, 1, 1, 1); | ||||
static int | static int | ||||
-pwc_match(device_t self) | -pwc_match(device_t self) | ||||
+pwc_probe(device_t self) | +pwc_probe(device_t self) | ||||
{ | { | ||||
- struct usb_attach_arg *uaa = device_get_ivars(self); | - struct usb_attach_arg *uaa = device_get_ivars(self); | ||||
- usb_interface_descriptor_t *id; | - usb_interface_descriptor_t *id; | ||||
+ struct usb_attach_arg *uaa = device_get_ivars(self); | + struct usb_attach_arg *uaa = device_get_ivars(self); | ||||
- Trace(TRACE_PROBE,"pwc_match: vendor=0x%x, product=0x%x release=%04x\n",uaa->vendor, uaa->product,uaa->release); | - Trace(TRACE_PROBE,"pwc_match: vendor=0x%x, product=0x%x release=%04x\n",uaa->vendor, uaa->product,uaa->release); | ||||
- | - | ||||
- if(pwc_lookup(uaa->vendor, uaa->product) == NULL) | - if(pwc_lookup(uaa->vendor, uaa->product) == NULL) | ||||
- return UMATCH_NONE; | - return UMATCH_NONE; | ||||
+ Trace(TRACE_PROBE,"pwc_probe:\n"); | + Trace(TRACE_PROBE,"pwc_probe:\n"); | ||||
+ | |||||
+ if (uaa->usb_mode != USB_MODE_HOST) | |||||
+ return (ENXIO); | |||||
- /* Driver loaded when device was already plugged in, we have to claim all interfaces or get none... */ | - /* Driver loaded when device was already plugged in, we have to claim all interfaces or get none... */ | ||||
- if(uaa->usegeneric) | - if(uaa->usegeneric) | ||||
- return UMATCH_VENDOR_PRODUCT; | - return UMATCH_VENDOR_PRODUCT; | ||||
- | - | ||||
- /* We don't want all interfaces */ | - /* We don't want all interfaces */ | ||||
- if(uaa->iface == NULL) | - if(uaa->iface == NULL) | ||||
- return UMATCH_NONE; | - return UMATCH_NONE; | ||||
- | - | ||||
- id = usbd_get_interface_descriptor(uaa->iface); | - id = usbd_get_interface_descriptor(uaa->iface); | ||||
- if(id == NULL) { | - if(id == NULL) { | ||||
- printf("pwc: failed to get interface descriptor\n"); | - printf("pwc: failed to get interface descriptor\n"); | ||||
- return UMATCH_NONE; | - return UMATCH_NONE; | ||||
- } | - } | ||||
- | - | ||||
- Trace(TRACE_PROBE,"pwc_match: iface=%d\n",id->bInterfaceNumber); | - Trace(TRACE_PROBE,"pwc_match: iface=%d\n",id->bInterfaceNumber); | ||||
- | - | ||||
+ if (uaa->usb_mode != USB_MODE_HOST) | |||||
+ return (ENXIO); | |||||
+ | |||||
/* Interface 0 is the video interface | /* Interface 0 is the video interface | ||||
* Interface 1 is supposed to be audiocontrol | * Interface 1 is supposed to be audiocontrol | ||||
* Interface 2 is supposed to be audio | * Interface 2 is supposed to be audio | ||||
*/ | */ | ||||
- if(id->bInterfaceNumber != 0) | - if(id->bInterfaceNumber != 0) | ||||
- return UMATCH_NONE; | - return UMATCH_NONE; | ||||
- | - | ||||
- return UMATCH_VENDOR_PRODUCT; | - return UMATCH_VENDOR_PRODUCT; | ||||
- | - | ||||
+ if (uaa->info.bIfaceIndex != 0) | + if (uaa->info.bIfaceIndex != 0) | ||||
+ return (ENXIO); | + return (ENXIO); | ||||
+ | + | ||||
+ return (usbd_lookup_id_by_uaa(pwc_devs, sizeof(pwc_devs), uaa)); | + return (usbd_lookup_id_by_uaa(pwc_devs, sizeof(pwc_devs), uaa)); | ||||
+ | + | ||||
+ return (0); /* success */ | + return (0); /* success */ | ||||
} | } | ||||
static int | static int | ||||
@@ -162,43 +162,26 @@ | @@ -162,43 +160,26 @@ | ||||
{ | { | ||||
struct pwc_softc *sc = device_get_softc(self); | struct pwc_softc *sc = device_get_softc(self); | ||||
struct usb_attach_arg *uaa = device_get_ivars(self); | struct usb_attach_arg *uaa = device_get_ivars(self); | ||||
- char devinfo[1024]; | - char devinfo[1024]; | ||||
- const char *tmpstr; | - const char *tmpstr; | ||||
- const struct pwc_info *info; | - const struct pwc_info *info; | ||||
char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; | char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; | ||||
- int i, err; | - int i, err; | ||||
+ const char *tmpstr; | + const char *tmpstr; | ||||
+ int i; | + int i; | ||||
- info = pwc_lookup(uaa->vendor, uaa->product); | - info = pwc_lookup(uaa->vendor, uaa->product); | ||||
- if(info == NULL) { | - if(info == NULL) { | ||||
- printf("%s: attach error vendor/product mismatch (vendor=0x%x product=0x%x)\n", | - printf("%s: attach error vendor/product mismatch (vendor=0x%x product=0x%x)\n", | ||||
- device_get_nameunit(sc->sc_dev),uaa->vendor,uaa->product); | - device_get_nameunit(sc->sc_dev),uaa->vendor,uaa->product); | ||||
- return ENXIO; | - return ENXIO; | ||||
- } | - } | ||||
+ device_set_usb_desc(self); | + device_set_usb_desc(self); | ||||
- usbd_devinfo(uaa->device, 0, devinfo); | - usbd_devinfo(uaa->device, 0, devinfo); | ||||
sc->sc_dev = self; | sc->sc_dev = self; | ||||
- device_set_desc_copy(self, devinfo); | - device_set_desc_copy(self, devinfo); | ||||
- device_printf(self, "%s\n", devinfo); | - device_printf(self, "%s\n", devinfo); | ||||
- | |||||
- err = usbd_device2interface_handle(uaa->device,0,&sc->sc_iface); | - err = usbd_device2interface_handle(uaa->device,0,&sc->sc_iface); | ||||
- if(err) { | - if(err) { | ||||
- printf("%s: failed to get interface handle\n",device_get_nameunit(sc->sc_dev)); | - printf("%s: failed to get interface handle\n",device_get_nameunit(sc->sc_dev)); | ||||
- return ENXIO; | - return ENXIO; | ||||
- } | - } | ||||
- | |||||
sc->udev = uaa->device; | sc->udev = uaa->device; | ||||
- sc->type = info->type; | - sc->type = info->type; | ||||
- sc->name = info->name; | - sc->name = info->name; | ||||
- sc->release = uaa->release; | - sc->release = uaa->release; | ||||
+ sc->type = USB_GET_DRIVER_INFO(uaa); | + sc->type = USB_GET_DRIVER_INFO(uaa); | ||||
+ sc->release = uaa->info.bcdDevice; | + sc->release = uaa->info.bcdDevice; | ||||
sc->power_save = 0; | sc->power_save = 0; | ||||
- | - | ||||
+ | + | ||||
strcpy(sc->serial,"000-000-000-000"); | strcpy(sc->serial,"000-000-000-000"); | ||||
- if(uaa->vendor == 0x046D) { | - if(uaa->vendor == 0x046D) { | ||||
- if(uaa->product == 0x08B4) { | - if(uaa->product == 0x08B4) { | ||||
+ if(uaa->info.idVendor == 0x046D) { | + if(uaa->info.idVendor == 0x046D) { | ||||
+ if(uaa->info.idProduct == 0x08B4) { | + if(uaa->info.idProduct == 0x08B4) { | ||||
sc->power_save = 1; | sc->power_save = 1; | ||||
} | } | ||||
- else if(uaa->product == 0x08B5) { | - else if(uaa->product == 0x08B5) { | ||||
+ else if(uaa->info.idProduct == 0x08B5) { | + else if(uaa->info.idProduct == 0x08B5) { | ||||
/* Logitech QuickCam Orbit */ | /* Logitech QuickCam Orbit */ | ||||
sc->features |= FEATURE_MOTOR_PANTILT; | sc->features |= FEATURE_MOTOR_PANTILT; | ||||
@@ -215,6 +198,8 @@ | @@ -215,6 +196,8 @@ | ||||
resource_string_value("pwc",device_get_unit(self),"devname",&tmpstr); | resource_string_value("pwc",device_get_unit(self),"devname",&tmpstr); | ||||
sc->sc_dev_t = make_dev(&pwc_cdevsw, device_get_unit(self),UID_ROOT, GID_OPERATOR, | sc->sc_dev_t = make_dev(&pwc_cdevsw, device_get_unit(self),UID_ROOT, GID_OPERATOR, | ||||
0666, "%s%d",tmpstr,device_get_unit(self)); | 0666, "%s%d",tmpstr,device_get_unit(self)); | ||||
+ if (sc->sc_dev_t != NULL) | + if (sc->sc_dev_t != NULL) | ||||
+ sc->sc_dev_t->si_drv1 = sc; | + sc->sc_dev_t->si_drv1 = sc; | ||||
resource_int_value("pwc",device_get_unit(self),"power_save",&sc->power_save); | resource_int_value("pwc",device_get_unit(self),"power_save",&sc->power_save); | ||||
@@ -273,7 +258,6 @@ | @@ -273,7 +256,6 @@ | ||||
resource_int_value("pwc",device_get_unit(self),"pad",&sc->pwc_pad); | resource_int_value("pwc",device_get_unit(self),"pad",&sc->pwc_pad); | ||||
pwc_construct(sc); | pwc_construct(sc); | ||||
- printf("%s: %s USB webcam\n",device_get_nameunit(sc->sc_dev),sc->name); | - printf("%s: %s USB webcam\n",device_get_nameunit(sc->sc_dev),sc->name); | ||||
if(pwc_get_cmos_sensor(sc, &i) >= 0) { | if(pwc_get_cmos_sensor(sc, &i) >= 0) { | ||||
@@ -299,7 +283,6 @@ | @@ -299,7 +281,6 @@ | ||||
if(sc->power_save) | if(sc->power_save) | ||||
pwc_camera_power(sc, 0); | pwc_camera_power(sc, 0); | ||||
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->udev,sc->sc_dev); | - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->udev,sc->sc_dev); | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -309,12 +292,8 @@ | @@ -309,13 +290,9 @@ | ||||
struct pwc_softc *sc = device_get_softc(self); | struct pwc_softc *sc = device_get_softc(self); | ||||
Trace(TRACE_PROBE,"pwc_detach: sc=%p\n",sc); | Trace(TRACE_PROBE,"pwc_detach: sc=%p\n",sc); | ||||
- | - | ||||
- if(sc->sc_videopipe != NULL) { | - if(sc->sc_videopipe != NULL) { | ||||
- usbd_abort_pipe(sc->sc_videopipe); | - usbd_abort_pipe(sc->sc_videopipe); | ||||
- usbd_close_pipe(sc->sc_videopipe); | - usbd_close_pipe(sc->sc_videopipe); | ||||
- sc->sc_videopipe = NULL; | - sc->sc_videopipe = NULL; | ||||
- } | - } | ||||
+ | |||||
+ usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | |||||
+ usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | |||||
+ | |||||
sc->error_status = EPIPE; | sc->error_status = EPIPE; | ||||
@@ -334,21 +313,17 @@ | if(sc->vopen) { | ||||
@@ -334,21 +311,17 @@ | |||||
mtx_destroy(&sc->ptrlock); | mtx_destroy(&sc->ptrlock); | ||||
pwc_free_buffers(sc,1); | pwc_free_buffers(sc,1); | ||||
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->udev,sc->sc_dev); | - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->udev,sc->sc_dev); | ||||
return 0; | return 0; | ||||
} | } | ||||
int | int | ||||
Show All 9 Lines | |||||
- return ENXIO; | - return ENXIO; | ||||
- | - | ||||
+#ifdef USB_DEBUG | +#ifdef USB_DEBUG | ||||
+ int unit = device_get_unit(sc->sc_dev); | + int unit = device_get_unit(sc->sc_dev); | ||||
+#endif | +#endif | ||||
Trace(TRACE_OPEN,"pwc_open: flag=%d, mode=%d, unit=%d\n",flag, mode, unit); | Trace(TRACE_OPEN,"pwc_open: flag=%d, mode=%d, unit=%d\n",flag, mode, unit); | ||||
if(sc->error_status == EPIPE) | if(sc->error_status == EPIPE) | ||||
@@ -419,23 +394,6 @@ | @@ -419,23 +392,6 @@ | ||||
for (i = 0; i < sc->pwc_mbufs; i++) | for (i = 0; i < sc->pwc_mbufs; i++) | ||||
sc->image_used[i] = 0; | sc->image_used[i] = 0; | ||||
- /* Allocate iso transfers */ | - /* Allocate iso transfers */ | ||||
- for (i = 0; i < MAX_ISO_BUFS; i++) { | - for (i = 0; i < MAX_ISO_BUFS; i++) { | ||||
- sc->sbuf[i].sc = sc; | - sc->sbuf[i].sc = sc; | ||||
- sc->sbuf[i].xfer = usbd_alloc_xfer(sc->udev); | - sc->sbuf[i].xfer = usbd_alloc_xfer(sc->udev); | ||||
- | - | ||||
- if(sc->sbuf[i].xfer == NULL) { | - if(sc->sbuf[i].xfer == NULL) { | ||||
- printf("%s: Failed to allocate transfer\n",device_get_nameunit(sc->sc_dev)); | - printf("%s: Failed to allocate transfer\n",device_get_nameunit(sc->sc_dev)); | ||||
- goto bad; | - goto bad; | ||||
- } | - } | ||||
- | - | ||||
- sc->sbuf[i].data = usbd_alloc_buffer(sc->sbuf[i].xfer, ISO_BUFFER_SIZE); | - sc->sbuf[i].data = usbd_alloc_buffer(sc->sbuf[i].xfer, ISO_BUFFER_SIZE); | ||||
- if(sc->sbuf[i].data == NULL) { | - if(sc->sbuf[i].data == NULL) { | ||||
- printf("%s: Failed to allocate transferbuffer\n",device_get_nameunit(sc->sc_dev)); | - printf("%s: Failed to allocate transferbuffer\n",device_get_nameunit(sc->sc_dev)); | ||||
- goto bad; | - goto bad; | ||||
- } | - } | ||||
- } | - } | ||||
- | - | ||||
sc->state = 0; | sc->state = 0; | ||||
sc->vframe_count = 0; | sc->vframe_count = 0; | ||||
sc->vframes_dumped = 0; | sc->vframes_dumped = 0; | ||||
@@ -476,10 +434,10 @@ | @@ -476,10 +432,10 @@ | ||||
int | int | ||||
pwc_close(struct cdev *dev, int flag, int mode, struct thread *p) | pwc_close(struct cdev *dev, int flag, int mode, struct thread *p) | ||||
{ | { | ||||
- struct pwc_softc *sc; | - struct pwc_softc *sc; | ||||
- int unit = PWCUNIT(dev); | - int unit = PWCUNIT(dev); | ||||
- | - | ||||
- sc = devclass_get_softc(pwc_devclass, unit); | - sc = devclass_get_softc(pwc_devclass, unit); | ||||
+ struct pwc_softc *sc = dev->si_drv1; | + struct pwc_softc *sc = dev->si_drv1; | ||||
+#ifdef USB_DEBUG | +#ifdef USB_DEBUG | ||||
+ int unit = device_get_unit(sc->sc_dev); | + int unit = device_get_unit(sc->sc_dev); | ||||
+#endif | +#endif | ||||
Trace(TRACE_OPEN,"pwc_close: flag=%d, mode=%d, unit=%d\n", flag, mode, unit); | Trace(TRACE_OPEN,"pwc_close: flag=%d, mode=%d, unit=%d\n", flag, mode, unit); | ||||
/* Dump statistics, but only if a reasonable amount of frames were | /* Dump statistics, but only if a reasonable amount of frames were | ||||
@@ -495,19 +453,14 @@ | @@ -495,19 +451,14 @@ | ||||
pwc_dec1_exit(); | pwc_dec1_exit(); | ||||
else | else | ||||
pwc_dec23_exit(); /* Timon & Kiara */ | pwc_dec23_exit(); /* Timon & Kiara */ | ||||
- | - | ||||
- if(sc->sc_videopipe != NULL) { | - if(sc->sc_videopipe != NULL) { | ||||
- usbd_abort_pipe(sc->sc_videopipe); | - usbd_abort_pipe(sc->sc_videopipe); | ||||
- usbd_close_pipe(sc->sc_videopipe); | - usbd_close_pipe(sc->sc_videopipe); | ||||
- sc->sc_videopipe = NULL; | - sc->sc_videopipe = NULL; | ||||
- } | - } | ||||
pwc_free_buffers(sc,0); | pwc_free_buffers(sc,0); | ||||
/* Turn off LEDS and power down camera, but only when not unplugged */ | /* Turn off LEDS and power down camera, but only when not unplugged */ | ||||
if(sc->error_status != EPIPE) { | if(sc->error_status != EPIPE) { | ||||
- | - | ||||
- usbd_set_interface(sc->sc_iface, 0); | - usbd_set_interface(sc->sc_iface, 0); | ||||
+ | + | ||||
+ usbd_set_alt_interface_index(sc->udev, sc->sc_iface_index, 0); | + usbd_set_alt_interface_index(sc->udev, sc->sc_iface_index, 0); | ||||
+ | + | ||||
pwc_set_leds(sc,0,0); | pwc_set_leds(sc,0,0); | ||||
if(sc->power_save) { | if(sc->power_save) { | ||||
@@ -523,15 +476,16 @@ | @@ -523,15 +474,16 @@ | ||||
int | int | ||||
pwc_read(struct cdev *dev, struct uio *uio, int flag) | pwc_read(struct cdev *dev, struct uio *uio, int flag) | ||||
{ | { | ||||
- struct pwc_softc *sc; | - struct pwc_softc *sc; | ||||
- int unit = PWCUNIT(dev); | - int unit = PWCUNIT(dev); | ||||
+ struct pwc_softc *sc = dev->si_drv1; | + struct pwc_softc *sc = dev->si_drv1; | ||||
+#ifdef USB_DEBUG | +#ifdef USB_DEBUG | ||||
+ int unit = device_get_unit(sc->sc_dev); | + int unit = device_get_unit(sc->sc_dev); | ||||
+#endif | +#endif | ||||
int bytes_to_read; | int bytes_to_read; | ||||
int count = uio->uio_resid; | int count = uio->uio_resid; | ||||
int err; | int err; | ||||
Trace(TRACE_READ,"pwc_read: flag=%d, unit=%d\n", flag, unit); | Trace(TRACE_READ,"pwc_read: flag=%d, unit=%d\n", flag, unit); | ||||
- sc = devclass_get_softc(pwc_devclass, unit); | - sc = devclass_get_softc(pwc_devclass, unit); | ||||
if (sc->error_status) | if (sc->error_status) | ||||
return sc->error_status; | return sc->error_status; | ||||
@@ -565,7 +519,7 @@ | @@ -565,7 +517,7 @@ | ||||
if(count + sc->image_read_pos > bytes_to_read) | if(count + sc->image_read_pos > bytes_to_read) | ||||
count = bytes_to_read - sc->image_read_pos; | count = bytes_to_read - sc->image_read_pos; | ||||
- Trace(TRACE_READ_VERBOSE, "pwc_read: wants: %d bytes, reading: %d bytes\n",uio->uio_resid,count); | - Trace(TRACE_READ_VERBOSE, "pwc_read: wants: %d bytes, reading: %d bytes\n",uio->uio_resid,count); | ||||
+ Trace(TRACE_READ_VERBOSE, "pwc_read: wants: %d bytes, reading: %d bytes\n",(int)uio->uio_resid,count); | + Trace(TRACE_READ_VERBOSE, "pwc_read: wants: %d bytes, reading: %d bytes\n",(int)uio->uio_resid,count); | ||||
err = uiomove(sc->images[sc->fill_image].bufmem + sc->image_read_pos,count,uio); | err = uiomove(sc->images[sc->fill_image].bufmem + sc->image_read_pos,count,uio); | ||||
if(err) | if(err) | ||||
@@ -583,10 +537,9 @@ | @@ -583,10 +535,9 @@ | ||||
int | int | ||||
pwc_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p) | pwc_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p) | ||||
{ | { | ||||
- struct pwc_softc *sc; | - struct pwc_softc *sc; | ||||
- int unit = PWCUNIT(dev); | - int unit = PWCUNIT(dev); | ||||
+ struct pwc_softc *sc = dev->si_drv1; | + struct pwc_softc *sc = dev->si_drv1; | ||||
+ int unit = device_get_unit(sc->sc_dev); | + int unit = device_get_unit(sc->sc_dev); | ||||
- sc = devclass_get_softc(pwc_devclass, unit); | - sc = devclass_get_softc(pwc_devclass, unit); | ||||
if (sc->error_status) | if (sc->error_status) | ||||
return sc->error_status; | return sc->error_status; | ||||
@@ -596,11 +549,9 @@ | @@ -596,11 +547,9 @@ | ||||
int | int | ||||
pwc_poll(struct cdev *dev, int events, struct thread *p) | pwc_poll(struct cdev *dev, int events, struct thread *p) | ||||
{ | { | ||||
- struct pwc_softc *sc; | - struct pwc_softc *sc; | ||||
- int unit = PWCUNIT(dev); | - int unit = PWCUNIT(dev); | ||||
+ struct pwc_softc *sc = dev->si_drv1; | + struct pwc_softc *sc = dev->si_drv1; | ||||
int revents = 0; | int revents = 0; | ||||
- sc = devclass_get_softc(pwc_devclass, unit); | - sc = devclass_get_softc(pwc_devclass, unit); | ||||
if(sc->error_status) | if(sc->error_status) | ||||
return sc->error_status; | return sc->error_status; | ||||
@@ -625,16 +576,17 @@ | @@ -625,16 +574,17 @@ | ||||
} | } | ||||
int | int | ||||
+#ifdef D_VERSION_03 | +#ifdef D_VERSION_03 | ||||
+pwc_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, | +pwc_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, | ||||
+ __unused vm_memattr_t *memattr) | + __unused vm_memattr_t *memattr) | ||||
+#else | +#else | ||||
pwc_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) | pwc_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) | ||||
+#endif | +#endif | ||||
{ | { | ||||
#ifdef USE_MMAP | #ifdef USE_MMAP | ||||
- struct pwc_softc *sc; | - struct pwc_softc *sc; | ||||
- int unit = PWCUNIT(dev); | - int unit = PWCUNIT(dev); | ||||
+ struct pwc_softc *sc = dev->si_drv1; | + struct pwc_softc *sc = dev->si_drv1; | ||||
+ /* int unit = device_get_unit(sc->sc_dev); */ | + /* int unit = device_get_unit(sc->sc_dev); */ | ||||
- sc = devclass_get_softc(pwc_devclass, unit); | - sc = devclass_get_softc(pwc_devclass, unit); | ||||
- if(sc == NULL) | - if(sc == NULL) | ||||
- return ENXIO; | - return ENXIO; | ||||
- | - | ||||
if (sc->error_status) | if (sc->error_status) | ||||
return sc->error_status; | return sc->error_status; | ||||
@@ -652,16 +604,10 @@ | @@ -652,16 +602,10 @@ | ||||
int | int | ||||
pwc_try_video_mode(struct pwc_softc *sc, int width, int height, int new_fps, int new_compression, int new_snapshot) | pwc_try_video_mode(struct pwc_softc *sc, int width, int height, int new_fps, int new_compression, int new_snapshot) | ||||
{ | { | ||||
- usb_endpoint_descriptor_t *edesc = NULL; | - usb_endpoint_descriptor_t *edesc = NULL; | ||||
- u_int8_t nendpt; | - u_int8_t nendpt; | ||||
- int i, j, err, ret; | - int i, j, err, ret; | ||||
+ int i, err, ret; | + int i, err, ret; | ||||
+ | |||||
+ usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | |||||
- if(sc->sc_videopipe != NULL) { | - if(sc->sc_videopipe != NULL) { | ||||
- usbd_abort_pipe(sc->sc_videopipe); | - usbd_abort_pipe(sc->sc_videopipe); | ||||
- usbd_close_pipe(sc->sc_videopipe); | - usbd_close_pipe(sc->sc_videopipe); | ||||
- sc->sc_videopipe = NULL; | - sc->sc_videopipe = NULL; | ||||
- } | - } | ||||
- | - | ||||
+ usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | |||||
+ | |||||
pwc_reset_buffers(sc); | pwc_reset_buffers(sc); | ||||
/* Try to set video mode... if that fails fallback to previous mode */ | /* Try to set video mode... if that fails fallback to previous mode */ | ||||
@@ -678,52 +624,21 @@ | @@ -678,52 +622,21 @@ | ||||
sc->drop_frames++; /* try to avoid garbage during switch */ | sc->drop_frames++; /* try to avoid garbage during switch */ | ||||
sc->vsync = 0; | sc->vsync = 0; | ||||
- err = usbd_set_interface(sc->sc_iface,sc->valternate); | - err = usbd_set_interface(sc->sc_iface,sc->valternate); | ||||
- if(err != USBD_NORMAL_COMPLETION) { | - if(err != USBD_NORMAL_COMPLETION) { | ||||
+ err = usbd_set_alt_interface_index(sc->udev, sc->sc_iface_index, sc->valternate); | + err = usbd_set_alt_interface_index(sc->udev, sc->sc_iface_index, sc->valternate); | ||||
+ if(err != USB_ERR_NORMAL_COMPLETION) { | + if(err != USB_ERR_NORMAL_COMPLETION) { | ||||
printf("%s: Failed to set alternate interface to: %d (%d)\n",device_get_nameunit(sc->sc_dev),sc->valternate,err); | printf("%s: Failed to set alternate interface to: %d (%d)\n",device_get_nameunit(sc->sc_dev),sc->valternate,err); | ||||
return -err; | return -err; | ||||
} | } | ||||
- err = usbd_endpoint_count(sc->sc_iface, &nendpt); | - err = usbd_endpoint_count(sc->sc_iface, &nendpt); | ||||
- if(err != USBD_NORMAL_COMPLETION) { | - if(err != USBD_NORMAL_COMPLETION) { | ||||
- printf("%s: Failed to get endpoint count (%d)\n",device_get_nameunit(sc->sc_dev),err); | - printf("%s: Failed to get endpoint count (%d)\n",device_get_nameunit(sc->sc_dev),err); | ||||
- return -err; | + /* Allocate iso transfers */ | ||||
- } | + if (usbd_transfer_setup(sc->udev, &sc->sc_iface_index, sc->sc_xfer, | ||||
+ pwc_config, MAX_ISO_BUFS, sc, &Giant)) { | |||||
+ printf("%s: Failed to setup USB transfers\n", device_get_nameunit(sc->sc_dev)); | |||||
return -err; | |||||
} | |||||
- for (i = 0; i < nendpt; i++) { | - for (i = 0; i < nendpt; i++) { | ||||
- edesc = usbd_interface2endpoint_descriptor(sc->sc_iface, i); | - edesc = usbd_interface2endpoint_descriptor(sc->sc_iface, i); | ||||
- if(edesc != NULL && UE_GET_ADDR(edesc->bEndpointAddress) == sc->vendpoint) | - if(edesc != NULL && UE_GET_ADDR(edesc->bEndpointAddress) == sc->vendpoint) | ||||
- break; | - break; | ||||
- } | - } | ||||
- if(i == nendpt) { | - if(i == nendpt) { | ||||
- printf("%s: Failed to find videoendpoint\n",device_get_nameunit(sc->sc_dev)); | - printf("%s: Failed to find videoendpoint\n",device_get_nameunit(sc->sc_dev)); | ||||
- return -EINVAL; | - return -EINVAL; | ||||
- } | - } | ||||
- | - | ||||
- sc->vmax_packet_size = UGETW(edesc->wMaxPacketSize); | - sc->vmax_packet_size = UGETW(edesc->wMaxPacketSize); | ||||
- if(sc->vmax_packet_size < 0 || sc->vmax_packet_size > ISO_MAX_FRAME_SIZE) { | - if(sc->vmax_packet_size < 0 || sc->vmax_packet_size > ISO_MAX_FRAME_SIZE) { | ||||
- printf("%s: Invalid packetsize (%d) for endpoint %d\n",device_get_nameunit(sc->sc_dev), | - printf("%s: Invalid packetsize (%d) for endpoint %d\n",device_get_nameunit(sc->sc_dev), | ||||
- sc->vmax_packet_size,edesc->bEndpointAddress); | - sc->vmax_packet_size,edesc->bEndpointAddress); | ||||
- return -EINVAL; | - return -EINVAL; | ||||
- } | - } | ||||
- | - | ||||
- err = usbd_open_pipe(sc->sc_iface,edesc->bEndpointAddress, 0, &sc->sc_videopipe); | - err = usbd_open_pipe(sc->sc_iface,edesc->bEndpointAddress, 0, &sc->sc_videopipe); | ||||
- if(err != USBD_NORMAL_COMPLETION) { | - if(err != USBD_NORMAL_COMPLETION) { | ||||
- printf("%s: Failed to open videopipe (%d)\n",device_get_nameunit(sc->sc_dev),err); | - printf("%s: Failed to open videopipe (%d)\n",device_get_nameunit(sc->sc_dev),err); | ||||
+ /* Allocate iso transfers */ | - return -err; | ||||
+ if (usbd_transfer_setup(sc->udev, &sc->sc_iface_index, sc->sc_xfer, | - } | ||||
+ pwc_config, MAX_ISO_BUFS, sc, &Giant)) { | |||||
+ printf("%s: Failed to setup USB transfers\n", device_get_nameunit(sc->sc_dev)); | |||||
return -err; | |||||
} | |||||
for (i = 0; i < MAX_ISO_BUFS; i++) { | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||||
- | - | ||||
- for(j = 0; j < ISO_FRAMES_PER_DESC; ++j) | - for(j = 0; j < ISO_FRAMES_PER_DESC; ++j) | ||||
- sc->sbuf[i].sizes[j] = sc->vmax_packet_size; | - sc->sbuf[i].sizes[j] = sc->vmax_packet_size; | ||||
- | - | ||||
- usbd_setup_isoc_xfer(sc->sbuf[i].xfer, sc->sc_videopipe, | - usbd_setup_isoc_xfer(sc->sbuf[i].xfer, sc->sc_videopipe, | ||||
- &sc->sbuf[i],sc->sbuf[i].sizes, | - &sc->sbuf[i],sc->sbuf[i].sizes, | ||||
- ISO_FRAMES_PER_DESC, | - ISO_FRAMES_PER_DESC, | ||||
- USBD_NO_COPY|USBD_SHORT_XFER_OK, | - USBD_NO_COPY|USBD_SHORT_XFER_OK, | ||||
- pwc_isoc_handler); | - pwc_isoc_handler); | ||||
- | - | ||||
- usbd_transfer(sc->sbuf[i].xfer); | - usbd_transfer(sc->sbuf[i].xfer); | ||||
+ usbd_transfer_start(sc->sc_xfer[i]); | + usbd_transfer_start(sc->sc_xfer[i]); | ||||
} | } | ||||
if(sc->state & PWC_INIT) | if(sc->state & PWC_INIT) | ||||
@@ -767,37 +682,41 @@ | @@ -767,38 +680,42 @@ | ||||
} | } | ||||
static void | static void | ||||
-pwc_isoc_handler(usbd_xfer_handle xfer, usbd_private_handle addr,usbd_status status) | -pwc_isoc_handler(usbd_xfer_handle xfer, usbd_private_handle addr,usbd_status status) | ||||
+pwc_isoc_rx_callback(struct usb_xfer *xfer, usb_error_t err) | +pwc_isoc_rx_callback(struct usb_xfer *xfer, usb_error_t err) | ||||
{ | { | ||||
- struct pwc_iso_buf *req = addr; | - struct pwc_iso_buf *req = addr; | ||||
- struct pwc_softc *sc = req->sc; | - struct pwc_softc *sc = req->sc; | ||||
Show All 36 Lines | |||||
+ usbd_transfer_submit(xfer); | + usbd_transfer_submit(xfer); | ||||
+ break; | + break; | ||||
+ default: | + default: | ||||
+ if (xfer->error != USB_ERR_CANCELLED) | + if (xfer->error != USB_ERR_CANCELLED) | ||||
+ goto tr_setup; | + goto tr_setup; | ||||
+ break; | + break; | ||||
} | } | ||||
+} | +} | ||||
+ | |||||
+static void | +static void | ||||
+pwc_isoc_handler(struct usb_xfer *xfer, void *addr) | +pwc_isoc_handler(struct usb_xfer *xfer, void *addr) | ||||
+{ | +{ | ||||
+ struct pwc_softc *sc = addr; | + struct pwc_softc *sc = addr; | ||||
+ struct pwc_frame_buf *fbuf; | + struct pwc_frame_buf *fbuf; | ||||
+ unsigned char *fillptr = NULL; | + unsigned char *fillptr = NULL; | ||||
+ int awake = 0; | + int awake = 0; | ||||
+ int i; | + int i; | ||||
+ | + | ||||
+ Trace(TRACE_ISOC_VERBOSE, "pwc_isoc_handler: count=%u\n", xfer->actlen); | + Trace(TRACE_ISOC_VERBOSE, "pwc_isoc_handler: count=%u\n", xfer->actlen); | ||||
+ | |||||
/* Reset ISOC error counter. We did get here, after all. */ | /* Reset ISOC error counter. We did get here, after all. */ | ||||
sc->visoc_errors = 0; | sc->visoc_errors = 0; | ||||
@@ -816,8 +735,8 @@ | |||||
@@ -816,8 +733,8 @@ | |||||
/* XXX there is no individual framestatus in FreeBSD usbstack | /* XXX there is no individual framestatus in FreeBSD usbstack | ||||
* so just assume all frames are good | * so just assume all frames are good | ||||
*/ | */ | ||||
- u_int16_t flen = req->sizes[i]; | - u_int16_t flen = req->sizes[i]; | ||||
- unsigned char *iso_buf = req->data + sc->vmax_packet_size * i; | - unsigned char *iso_buf = req->data + sc->vmax_packet_size * i; | ||||
+ u_int16_t flen = xfer->frlengths[i]; | + u_int16_t flen = xfer->frlengths[i]; | ||||
+ u_int32_t iso_buf = xfer->max_frame_size * i; | + u_int32_t iso_buf = xfer->max_frame_size * i; | ||||
if (flen > 0) { /* if valid data... */ | if (flen > 0) { /* if valid data... */ | ||||
if(sc->vsync > NOCOPY) { /* ...and we are not sync-hunting... */ | if(sc->vsync > NOCOPY) { /* ...and we are not sync-hunting... */ | ||||
@@ -830,7 +749,7 @@ | @@ -830,7 +747,7 @@ | ||||
sc->vframes_error++; | sc->vframes_error++; | ||||
} | } | ||||
else { | else { | ||||
- memcpy(fillptr, iso_buf, flen); | - memcpy(fillptr, iso_buf, flen); | ||||
+ usbd_copy_out(xfer->frbuffers, iso_buf, fillptr, flen); | + usbd_copy_out(xfer->frbuffers, iso_buf, fillptr, flen); | ||||
fillptr += flen; | fillptr += flen; | ||||
} | } | ||||
} | } | ||||
@@ -943,7 +862,6 @@ | @@ -943,7 +860,6 @@ | ||||
sc->vlast_packet_size = flen; | sc->vlast_packet_size = flen; | ||||
} | } | ||||
-handler_end: | -handler_end: | ||||
if(awake) { | if(awake) { | ||||
if(sc->state & PWC_ASLEEP) { | if(sc->state & PWC_ASLEEP) { | ||||
wakeup(sc); | wakeup(sc); | ||||
@@ -953,16 +871,6 @@ | @@ -953,16 +869,6 @@ | ||||
selwakeuppri(&sc->rsel, PZERO); | selwakeuppri(&sc->rsel, PZERO); | ||||
} | } | ||||
} | } | ||||
- /* setup size for next transfer */ | - /* setup size for next transfer */ | ||||
- for (i = 0; i < ISO_FRAMES_PER_DESC; i++) | - for (i = 0; i < ISO_FRAMES_PER_DESC; i++) | ||||
- req->sizes[i] = sc->vmax_packet_size; | - req->sizes[i] = sc->vmax_packet_size; | ||||
- | - | ||||
- usbd_setup_isoc_xfer(xfer, sc->sc_videopipe, req, req->sizes, | - usbd_setup_isoc_xfer(xfer, sc->sc_videopipe, req, req->sizes, | ||||
- ISO_FRAMES_PER_DESC, | - ISO_FRAMES_PER_DESC, | ||||
- USBD_NO_COPY|USBD_SHORT_XFER_OK, | - USBD_NO_COPY|USBD_SHORT_XFER_OK, | ||||
- pwc_isoc_handler); | - pwc_isoc_handler); | ||||
- | - | ||||
- usbd_transfer(xfer); | - usbd_transfer(xfer); | ||||
} | } | ||||
int | int | ||||
@@ -1050,6 +958,9 @@ | @@ -1050,6 +956,9 @@ | ||||
{ | { | ||||
int i; | int i; | ||||
Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", sc); | Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", sc); | ||||
+ | + | ||||
+ usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | + usbd_transfer_unsetup(sc->sc_xfer, MAX_ISO_BUFS); | ||||
+ | + | ||||
if (sc->fbuf != NULL) { | if (sc->fbuf != NULL) { | ||||
for (i = 0; i < sc->pwc_fbufs; i++) { | for (i = 0; i < sc->pwc_fbufs; i++) { | ||||
if (sc->fbuf[i].data != NULL) { | if (sc->fbuf[i].data != NULL) { | ||||
@@ -1074,13 +985,6 @@ | @@ -1074,13 +983,12 @@ | ||||
free(sc->image_data,M_USBDEV); | free(sc->image_data,M_USBDEV); | ||||
sc->image_data = NULL; | sc->image_data = NULL; | ||||
} | } | ||||
- | - | ||||
- for (i = 0; i < MAX_ISO_BUFS; i++) { | - for (i = 0; i < MAX_ISO_BUFS; i++) { | ||||
- if (sc->sbuf[i].xfer != NULL) { | - if (sc->sbuf[i].xfer != NULL) { | ||||
- usbd_free_xfer(sc->sbuf[i].xfer); /* implicit buffer free */ | - usbd_free_xfer(sc->sbuf[i].xfer); /* implicit buffer free */ | ||||
- sc->sbuf[i].xfer = NULL; | - sc->sbuf[i].xfer = NULL; | ||||
- } | - } | ||||
- } | - } | ||||
} | } | ||||
-DRIVER_MODULE(pwc, uhub, pwc_driver, pwc_devclass, usbd_driver_load, 0); | -DRIVER_MODULE(pwc, uhub, pwc_driver, pwc_devclass, usbd_driver_load, 0); | ||||
+#if __FreeBSD_version >= 1400058 | |||||
+DRIVER_MODULE(pwc, uhub, pwc_driver, NULL, NULL); | |||||
+#else | |||||
+static devclass_t pwc_devclass; | |||||
+ | |||||
+DRIVER_MODULE(pwc, uhub, pwc_driver, pwc_devclass, NULL, 0); | +DRIVER_MODULE(pwc, uhub, pwc_driver, pwc_devclass, NULL, 0); | ||||
+#endif |