isoc transactions in 2.3.9 vs 2.3.8
Subject : isoc transactions in 2.3.9 vs 2.3.8
From: Jim Chapman <email@hidden >
Date: Tue, 17 May 2005 10:04:58 +0100
Delivered-to: email@hidden
Delivered-to: email@hidden
I have a USB (1.1) device which sends data up an
isoc pipe. The data is bursty, so most/all of the isoc
packets are short.
The attached user space code frag reads the pipe.
(It's derived from the 'simple' example from Apple)
It works fine under 10.3.8, but not on a 10.3.9
system. After about 20 seconds, the initial read
requests complete with underrun's (this is normal,
actually, but the completion should be called in a
more timely manner!)
However, the code works fine if a USB mouse is
moving at all times. If the mouse stops moving, the
requests stop flowing.
Does anyone have any ideas?
Jim Chapman
--------------------
#define ISO_PIPEREF 5 // iso pipe
#define ISO_PIPESIZE 512 // iso endpoint packet size
#define ISO_REQCOUNT 10 // concurrent active requests
#define ISO_REQFRAMES 10 // frames per request
#define ISO_FUTURE 10 // delay to first frame
#define FRAME_COUNT 10000
mach_port_t masterPort = 0; // requires <mach/mach.h>
unsigned frameCounter = 0;
UInt64 nextFrame;
typedef struct
{
IOUSBInterfaceInterface **interface;
IOUSBIsocFrame frames[ISO_REQFRAMES];
unsigned char buffer[ISO_REQFRAMES * ISO_PIPESIZE];
} IsoRequest;
static IsoRequest isoRequests[ISO_REQCOUNT];
void isoCallback(void *dummy, IOReturn result, void *arg0)
{
IsoRequest *r = (IsoRequest *)dummy;
unsigned j;
IOReturn err;
printf("isoCallback: %d, %08x, %d\n", (int)dummy, result,
(int)arg0);
if(result != kIOReturnSuccess && result != kIOReturnUnderrun)
{
CFRunLoopStop(CFRunLoopGetCurrent());
return;
}
/*
if(++frameCounter >= FRAME_COUNT)
{
CFRunLoopStop(CFRunLoopGetCurrent());
return;
}
*/
for(j=0;j<ISO_REQFRAMES;j++)
{
r->frames[j].frStatus=2;
r->frames[j].frReqCount=ISO_PIPESIZE;
r->frames[j].frActCount=0;
}
err =
(*(r->interface))->ReadIsochPipeAsync(r->interface,ISO_PIPEREF,r-
>buffer,nextFrame,ISO_REQFRAMES,r->frames, isoCallback, r);
if (err)
{
printf("isoCallback: ReadISochPipeAsync failed, err = %08x\n",
err);
CFRunLoopStop(CFRunLoopGetCurrent());
return;
}
nextFrame+=ISO_REQFRAMES;
}
void startISO(IOUSBInterfaceInterface **intf)
{
IOReturn err;
UInt8 direction, number, transferType, interval;
UInt16 maxPacketSize;
unsigned i,j;
AbsoluteTime time;
CFRunLoopSourceRef source;
err = (*intf)->GetPipeProperties(intf, ISO_PIPEREF, &direction,
&number, &transferType, &maxPacketSize, &interval);
if (err)
{
printf("startISO: unable to get pipe properties for pipe %d,
err = %08x\n", ISO_PIPEREF, err);
return;
}
if(transferType!=kUSBIsoc || interval!=1 ||
maxPacketSize!=ISO_PIPESIZE || direction!=kUSBIn)
{
printf("startISO: pipe %d is unexpected type\n", ISO_PIPEREF);
return;
}
printf("startISO: pipe %d is OK\n", ISO_PIPEREF);
err = (*intf)->CreateInterfaceAsyncEventSource(intf, &source);
if (err)
{
printf("transferData: unable to create event source, err = %08x\n",
err);
return;
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
err = (*intf)->GetBusFrameNumber(intf,&nextFrame,&time);
if (err)
{
printf("transferData: can't get current frame, err = %08x\n", err);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
return;
}
nextFrame += ISO_FUTURE;
frameCounter = 0;
for(i=0;i<ISO_REQCOUNT;i++)
{
isoRequests[i].interface = intf;
for(j=0;j<ISO_REQFRAMES;j++)
{
isoRequests[i].frames[j].frStatus=2;
isoRequests[i].frames[j].frReqCount=ISO_PIPESIZE;
isoRequests[i].frames[j].frActCount=0;
}
err =
(*intf)-
>ReadIsochPipeAsync(intf,ISO_PIPEREF,isoRequests[i].buffer,nextFrame,ISO
_REQFRAMES,isoRequests[i].frames, isoCallback, &isoRequests[i]);
if (err)
{
printf("transferData: ReadISochPipeAsync failed, err =
%08x\n", err);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
return;
}
nextFrame+=ISO_REQFRAMES;
}
printf("starting runloop\n");
CFRunLoopRun();
printf("runloop exited\n");
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Usb mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/usb/email@hidden
This email sent to email@hidden
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE
Contact Apple | Terms of Use | Privacy Policy
Copyright © 2007 Apple Inc. All rights reserved.