I am writing a driver for the CATC Netmate USB to ethernet chipset.
I am also going insane.
The basic principle of operation is that a USB interrupt gets delivered when there is a
packet to be received. Then I read it the packet with a bulk transfer. However
everytime I
submit the bulk URB, the whole machine locks up solid. No Magic SysReq, nothing except
a
power cycle (and fsck).
A gzip'd copy of the driver is attached for reference, but AFAICT, the offending code
is:
/****************************************************************
* catc_irq - usb interrupt handler
****************************************************************/
static void catc_irq(struct urb *urb)
{
struct catc_device *catc = urb->context;
int res;
if (catc->intr_buffer & USB_CATC_LINK_BAD_MASK) {
dbg("Link beat dropped");
}
if (catc->intr_buffer & USB_CATC_LINK_GOOD_MASK) {
dbg("Link beat good");
}
if (catc->intr_buffer & USB_CATC_PACKET_MASK) {
dbg("Packet received!");
memset(catc->rx_buf, 0, sizeof(*catc->rx_buf));
FILL_BULK_URB(catc->rx_urb,
catc->usb,
usb_rcvbulkpipe(catc->usb, USB_CATC_BULK_EP),
catc->rx_buf,
USB_CATC_BUFF_SIZE,
catc_bulkurb_receive_complete,
catc);
if((res = usb_submit_urb(catc->rx_urb))){
warn("failed rx_urb %d", res);
catc->stats.tx_errors++;
}
}
dbg("IRQ says %x", catc->intr_buffer);
}
If I comment out the FILL_BULK_URB macro and the following usb_submit_urb code, then
the
driver runs OK - I see interrupts get delivered, including interrupts for packets (but
of
course, I get no networking data delivered). If I run the code as is, it locks up the
machine as soon as there is some networking traffic.
I considered the possibility that the bulk completion routine was causing the problem,
but
I made a couple of versions of that routine, including one that just dbg()'s, and
another
that was empty - made no difference. Still locks up.
Can anyone see what is wrong?
Brad
catc.c.gz