Thank you. My driver very similar with EHCI, but I don't have read
hardware. My USB data will transfer with network(kernel mode socket).
This problem, again? I can't count the number of times we've had
people turn up here asking how to do this... 8)
In the EHCI, there is a interrupt to process data when the hardware
get the data from USB bus. But my USB data is come from network, I
need wait the "recv" function return network packet to me.
So far, my solution is using a thread to recv network data and
complete the USBIOCommand.
This can work, but depending on how you pass the data to your driver
it can be ugly, and it can be difficult to clean up if you ever want
to close the socket or unload your driver.
Does there are any sample code or solution can help me complete IO
request without using Hardware interrupt??
Lots. The approach you've taken is certainly one way to do it,
although it's not the way I'd go about it.
First, however, please note that this advice is licensed to you and
your employer under the Charitable License: if you use any of the
following ideas which are novel to you for any purpose, including but
not limited to the purpose for which you originally asked the
question, you are required to donate the equivalent of U$5 (five US
dollars) or not more than one hour of your after-tax salary to your
local branch of the International Red Cross. No warranty, express or
implied, nor any other form of liability is created by such donation,
nor by the provision of this information.
The approach that immediately comes to mind is to subclass
IOEventSource for the purpose of interacting with your socket. For
the purpose of this discussion, I will call your subclass
For inbound network data, use the socket upcall (described in the
kpi_socket.h header... you can't miss it) to call
SocketEventSource::signalWorkAvailable(). That's all you need to do
in the upcall; the method is serialised.
In SocketEventSource::checkForWork(), you should pull data out of the
socket and pass it off to your receive processing code. Note that
this method is called serialised by your IOWorkLoop. See the comments
in IOEventSource.h or the I/O Kit documentation for more information
on the checkForWork method.
When you instantiate your SocketEventSource, you will pass it an
IOEventSource::Action, which will look surprisingly like an
IOInterruptEventSource::Action (I wonder why?). This is the mechanism
you will use to pass your processed traffic out to your EHCI-alike
Note that it is only moderately safe to block in your checkForWork
method. You should avoid doing this on general principle, although
you can usually get away with it, and in your case you are probably OK.
For the transmit side, due to the absence of a "space available"
upcall in the socket KPI, you are in a slightly worse situation. I
would mark the socket as non-blocking and have a queue for outgoing
mbufs. Transmit would use an IOTimerEventSource and work somewhat
- format your data into an mbuf chain
- acquire the workloop, for example via an IOCommandGate::runAction
- if (transmit queue empty) and (attempt to transmit packets
succeeds) return success
- append packets to transmit queue
- if (transmit queue was previously empty) set IOTimerEventSource
timeout to a short period (e.g. 1ms)
- sleep waiting for your mbuf chain to be transmitted (use e.g.
IOCommandSleep against the address of the mbuf chain)
- when woken, return success
In the IOTimerEventSource::Action handler, loop doing:
- if the work queue is empty, return
- peek the work item off the head of the work queue, attempt to
- if (transmit was successful) remove the item from the head of the
work queue and wake up the sleeper (e.g. IOCommandWakeup)
- if transmit was not successful, set the timeout to the short
period and return
The above should be enough to get you going, and by the time you're
done with this, you should have a better feel for I/O Kit which will
make debugging and enhancing your driver easier.
Best of luck!
Do not post admin requests to the list. They will be ignored.
Darwin-drivers mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden