“Kevin Chiles” <kchiles@qnx.com> wrote in message news:99a8od$g17$1@nntp.qnx.com…
Rex Lam <> Rex.Lam@igt.com> > wrote:
The SIGSEGV does not happen in a consistent place. Here are some of the
places it happens:
I am guessing that your class driver is corrupting the allocator. Can you
post the source to your class driver or send it to Randy Martin?
Here is the code I am running. Please look through it and let me know if I did something wrong. The problems I am encountering do not always happen. When it crashes, it happens when I insert and remove a usb device rapidly. The SIGSEGV always ends up happening in the same place - offset 0xA1 in the memchunk module of libusbdi.a.
#include “usb_device.h”
#include <share.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/resmgr.h>
#include <sys/procmgr.h>
#include <sys/dcmd_chr.h>
#include <sys/rsrcdbmgr.h>
usb_device_ctrl_t usb_device_ctrl;
int usb_device_free (usb_device_t *usb_device)
{
int status = 0;
printf (“usb_device_free\n”);
if (!usb_device)
return 0;
else
{
printf (“rsrcdbmgr_devno_detach\n”);
rsrcdbmgr_devno_detach (usb_device->attr.rdev, 0);
printf (“resmgr_detach\n”);
resmgr_detach (usb_device_ctrl.dispatch, usb_device->resmgr_id, _RESMGR_DETACH_ALL | _RESMGR_DETACH_CLOSE);
}
if (usb_device->urb)
{
printf (“usbd_free_urb\n”);
usbd_free_urb (usb_device->urb);
usb_device->urb = 0;
}
if (usb_device->ep_cntl)
{
printf (“free ep_cntl\n”);
usbd_abort_pipe (usb_device->ep_cntl);
usb_device->ep_cntl = 0;
}
if (usb_device->int_urb)
{
printf (“usbd_free_int_urb\n”);
usbd_free_urb (usb_device->int_urb);
usb_device->int_urb = 0;
}
if (usb_device->ep_intr)
{
printf (“free ep_intr\n”);
usbd_abort_pipe (usb_device->ep_intr);
usb_device->ep_intr = 0;
}
if (usb_device->buffer)
{
printf (“free buffer\n”);
usbd_free (usb_device->buffer);
usb_device->buffer = 0;
}
if (usb_device->int_buf)
{
printf (“free int_buf\n”);
usbd_free (usb_device->int_buf);
usb_device->int_buf = 0;
}
TAILQ_REMOVE (&usb_device_ctrl.dlist, usb_device, dlink);
if (usb_device->device)
{
printf (“usbd_detach: usb_device = %p\n”, usb_device);
if ((status = usbd_detach( usb_device->device )))
{
fprintf (stderr, “usb_device_free: usbd_detach %d = %s\n”, status, strerror (status));
}
}
printf (“end usb_device_free\n”);
return (status);
}
void usb_device_signal_handler (void)
{
siginfo_t info;
sigset_t set;
usb_device_t *usb_device;
usb_device_t *nusb_device;
printf (“usb_device_signal_handler\n”);
sigfillset (&set);
while (SignalWaitinfo( &set, &info) == -1)
;
for (usb_device = TAILQ_FIRST (&usb_device_ctrl.dlist); usb_device; usb_device = nusb_device)
{
nusb_device = TAILQ_NEXT (usb_device, dlink);
usb_device_free (usb_device);
}
}
int usb_device_parse_descriptors (usb_device_t *usb_device)
{
_uint32 eix;
_uint32 scan;
_uint32 found;
usbd_descriptors_t *desc;
struct usbd_desc_node *ifc, *ept;
#ifdef DEBUG
usbd_device_descriptor_t *device;
usbd_configuration_descriptor_t *cfg;
usbd_interface_descriptor_t *interface;
usbd_endpoint_descriptor_t *endpoint;
_uint8 num_endpoints = 0;
int i;
#endif
scan = USB_DEVICE_CONTROL_EP | USB_DEVICE_INTIN_EP;
found = 0;
printf (“usb_device_parse_descriptors (%p)\n”, usb_device);
#ifdef DEBUG
printf (“usbd_interface_descriptor (%p, %d, %d, %d, %p)\n”, usb_device->device, usb_device->instance.config,
usb_device->instance.iface, usb_device->instance.alternate, &ifc);
if ((interface = usbd_interface_descriptor (usb_device->device, usb_device->instance.config, usb_device->instance.iface,
usb_device->instance.alternate, &ifc)) != NULL)
{
printf (“usbd_interface_descriptor succeeded\n”);
if ((device = usbd_device_descriptor (usb_device->device, &ept)) != NULL)
{
printf ("\n");
printf (“Device Descriptor\n\n”);
printf (“Vendor ID = 0x%04X\n”, device->idVendor);
printf (“Product ID = 0x%04X\n”, device->idProduct);
printf (“USB spec = %04X\n”, device->bcdUSB);
printf (“Product rel. = %04X\n”, device->bcdDevice);
printf (“Max Packet = %02X\n”, device->bMaxPacketSize0);
if (device->iManufacturer)
printf (“Manufacturer = %s\n”, usbd_string (usb_device->device, device->iManufacturer, 0));
if (device->iProduct)
printf (“Product Name = %s\n”, usbd_string (usb_device->device, device->iProduct, 0));
if (device->iSerialNumber)
printf (“Serial Number = %s\n”, usbd_string (usb_device->device, device->iSerialNumber, 0));
printf ("\n");
}
if ((cfg = usbd_configuration_descriptor (usb_device->device, 1, &ept)) != NULL)
{
printf (“Device Configuration\n\n”);
printf (“Cfg: Attributes = 0x%02X (0x80 = Bus Powered, 0xC0 = Self Powered)\n”, cfg->bmAttributes);
if (cfg->iConfiguration)
printf (“Cfg: Desc = %s\n”, usbd_string (usb_device->device, cfg->iConfiguration, 0));
printf ("\n");
}
{
printf (“Device Interface\n\n”);
printf (“Interface Number = 0x%02X\n”, interface->bInterfaceNumber);
printf (“Alternate Setting = 0x%02X\n”, interface->bAlternateSetting);
printf (“Number of endpoints = 0x%02X\n”, interface->bNumEndpoints);
num_endpoints = interface->bNumEndpoints;
if (interface->iInterface)
printf (“Interface description = %s\n”, usbd_string (usb_device->device, interface->iInterface, 0));
printf ("\n");
}
for (i = 0; i <= num_endpoints; i++)
{
_uint8 ep = 0x80 | (i);
if ((endpoint = usbd_endpoint_descriptor (usb_device->device, usb_device->instance.config,
usb_device->instance.iface, usb_device->instance.alternate, ep, &ifc)) != NULL)
{
printf (“Device Endpoint %d\n\n”, i);
printf (“Transfer Type = 0x%02X (00 = Control, 01 = Isochronous, 02 = Bulk, 03 = Interrupt)\n”, endpoint->bmAttributes);
printf (“Max Packet Size = 0x%04X\n”, endpoint->wMaxPacketSize);
printf (“Polling Interval = 0x%02X\n”, endpoint->bInterval);
printf ("\n");
}
}
}
#endif
if (usbd_interface_descriptor (usb_device->device, usb_device->instance.config, usb_device->instance.iface, usb_device->instance.alternate, &ifc))
{
for (eix = 0; (desc = usbd_parse_descriptors (usb_device->device, ifc, USB_DESC_ENDPOINT, eix, &ept)) != NULL; ++eix)
{
switch (desc->endpoint.bmAttributes)
{
case USB_ATTRIB_CONTROL:
printf(“attrib control\n”);
if (usbd_open_pipe (usb_device->device, desc, &usb_device->ep_cntl) == EOK)
{
printf (“usb_device = %p, pipe = %p\n”, usb_device, usb_device->ep_cntl);
found |= USB_DEVICE_CONTROL_EP;
usb_device->ep_data_size = desc->endpoint.wMaxPacketSize;
}
break;
case USB_ATTRIB_ISOCHRONOUS:
printf(“attrib isoch\n”);
break;
case USB_ATTRIB_BULK:
printf(“attrib bulk\n”);
break;
case USB_ATTRIB_INTERRUPT:
printf(“attrib int\n”);
switch( desc->endpoint.bEndpointAddress & USB_ENDPOINT_IN )
{
case USB_ENDPOINT_OUT:
break;
case USB_ENDPOINT_IN:
if (usbd_open_pipe (usb_device->device, desc, &usb_device->ep_intr) == EOK)
{
printf (“usb_device = %p, pipe = %p\n”, usb_device, usb_device->ep_intr);
found |= USB_DEVICE_INTIN_EP;
usb_device->ep_intr_size = desc->endpoint.wMaxPacketSize;
}
break;
}
break;
}
}
}
return ((found & scan) ? EOK : ENODEV);
}
void usb_device_insertion (struct usbd_connection *connection, usbd_device_instance_t *instance)
{
usb_device_t *usb_device;
struct usbd_device *device;
int status;
usbd_device_ident_t *ident;
printf (“usb_device_insertion\n”);
ident = &instance->ident;
printf( “USB enum Insertion: addr %x, dev: %x, vid %x, class %x, sclass %x, proto %x\n”,
instance->devno, ident->device, ident->vendor, ident->usb_class, ident->subclass, ident->protocol );
if (ident->usb_class != USB_CLASS_HUB && (status = usbd_attach (connection, instance, sizeof (usb_device_t), &device)) == EOK)
{
printf (" device attached\n");
usb_device = usbd_device_extra (device);
usb_device->device = device;
usb_device->instance = *instance;
if (usb_device_parse_descriptors (usb_device) == EOK)
{
if (usb_device_init (usb_device))
{
// if (usb_device_resmgr_attach (usb_device) == EOK)
{
TAILQ_INSERT_TAIL (&usb_device_ctrl.dlist, usb_device, dlink);
return;
}
}
usbd_detach (device);
}
}
}
int usb_device_init (usb_device_t *usb_device)
{
int rv = 1;
printf (“usb_device_init\n”);
if (!usb_device)
rv = 0;
if (rv && usb_device->ep_cntl)
{
if ((usb_device->buffer = usbd_alloc (64)) != 0)
{
if ((usb_device->urb = usbd_alloc_urb (NULL)) == NULL)
{
rv = 0;
}
}
else
rv = 0;
}
// Now allocate for interrupt transfer
if (rv && usb_device->ep_intr)
{
if ((usb_device->int_buf = usbd_alloc (64)) != 0)
{
if ((usb_device->int_urb = usbd_alloc_urb (NULL)) == NULL)
{
rv = 0;
}
}
else
rv = 0;
}
if (!rv)
{
// Free up interrupt buffers.
if (usb_device->int_urb)
{
usbd_free_urb (usb_device->int_urb);
usb_device->int_urb = 0;
}
if (usb_device->int_buf)
{
usbd_free (usb_device->int_buf);
usb_device->int_buf = 0;
}
// Free up control buffers.
if (usb_device->urb)
{
usbd_free_urb (usb_device->urb);
usb_device->urb = 0;
}
if (usb_device->buffer)
{
usbd_free (usb_device->buffer);
usb_device->buffer = 0;
}
}
return rv;
}
void usb_device_removal (struct usbd_connection *connection, usbd_device_instance_t *instance)
{
struct usbd_device *device;
usb_device_t *usb_device;
printf ("\nusb_device_removal\n");
if ((device = usbd_device_lookup (connection, instance)) != NULL)
{
usb_device = usbd_device_extra (device);
usb_device_free (usb_device);
}
usb_device = TAILQ_FIRST (&usb_device_ctrl.dlist);
printf (“usb_device = %p\n\n”, usb_device);
}
int main (int argc, char *argv[])
{
struct usbd_connection *connection;
usbd_funcs_t funcs = { _USBDI_NFUNCS, usb_device_insertion,
usb_device_removal, NULL };
usbd_device_ident_t interest = { USBD_CONNECT_WILDCARD, // Vendor
USBD_CONNECT_WILDCARD, // Product
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD };
usbd_connect_parm_t parm = { NULL, USB_VERSION, USBD_VERSION, 0, argc,
argv, 0, &interest, &funcs };
int status;
int opt;
sigset_t signals;
printf (“main\n”);
sigfillset (&signals); // No signals to resmgr threads
pthread_sigmask (SIG_BLOCK, &signals, NULL);
TAILQ_INIT (&usb_device_ctrl.dlist);
usb_device_ctrl.prefix = “usbd”;
while ((opt = getopt (argc, argv, “vn:”)) != -1)
{
switch (opt)
{
case ‘n’:
usb_device_ctrl.prefix = optarg;
break;
case ‘v’:
usb_device_ctrl.verbose++;
break;
default:
break;
}
}
if ((usb_device_ctrl.chid = ChannelCreate (_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK)) == -1 ||
(usb_device_ctrl.coid = ConnectAttach (0, 0, usb_device_ctrl.chid, 0, _NTO_SIDE_CHANNEL)) == -1)
{
fprintf (stderr, “Unable to attach channel and connection\n”);
exit (EXIT_FAILURE);
}
if ((status = usbd_connect (&parm, &connection)) != EOK)
{
fprintf (stderr, “USB Device Class/init - %s\n”, strerror (status));
exit (EXIT_FAILURE);
}
usb_device_signal_handler ();
exit (EXIT_SUCCESS);
}