To achieve this with Borland Turbo C++, one must pass the -mt compiler option. In Bret's example source code (usbdevic.cpp) this options is passed as a #pragma directive directly in the source file.
Yet, passing the -mt compiler option as a #pragma directive like this does not work !
#pragma option -a -d -mt
// : : :
// : : +.. tiny memory model
// : +..... merge duplicate strings
// +........ word alignment
Your options will be silently disregarded by the compiler, without a single warning message, and your program will not behave appropriately.
Why did it seem to work in Bret's example ? That's because Bret's example (usbdevic.cpp) only enumerates the USB busses by asking the USBUHCI[L] driver to report back the information it has, it doesn't exactly send or receive anything to or from a USB peripheral. And in such a setup, no callback function to retrieve USB packet data is ever called.
So, if you start off with usbdevic.cpp and start modifying it, and you add an int14h call that specifies a callback function, you'll pull your hair out trying to finding out why it doesn't work.
I couldn't understand why my callback function wasn't called. I spent 4 days on this. Simply passing those compiler options in the command-line rather than in a #pragma directive instantly resolved my problem.
Now you're probably thinking: "dude, if you had disassembled your output you'd have seen the obvious, that it was not compiled in the tiny memory model". Well, I didn't bother, because not all of us know enough of low-level programming to understand 16-bit assembly listing headers.

Save yourself some headache and take good note of this...