Hi, I'm afraid I'm too busy with other stuff to comment on this atm, luckily we have a lot of other other capable contributors so I'll let those evaluate this :)
The reason I'm still responding is that if I've understood correctly, the thing sparking this discussion is a property of winusb to treat short packet reads as errors. I would like to turn out that this is not unique to windows / winusb. Linux has a similar flag, for Linux it is per urb / transfer, and the current libusb Linux code already uses it in case of large bulk transfers which it splits in multiple smaller ones. Which brings us to the general use of such a per transfer flag, if using the async API an app can queue up multiple transfers, and from a speed pov this is desirable, but if in transfers ending with less data then requested are considered an error by the app, then it may want the processing of the endpoint queue to stop as soon as a short packet is encountered (*). So this winusb flag seems to be a more general applicable thing, and something which we maybe should not solve in an os specific manner. This assumes that the winusb flag causes the ep to halt when the short read is encountered, if it does not do that, the flag is useless, since the sort read condition can be easily detected in the completion handler without needing the use of said flag. Regards, Hans *) Note that realizing this under Linux is non trivial, since the ep processing continues as soon as the packet complete handler runs inside the kernel! But it can be done if we want to export this functionality. On 08/31/2012 02:20 AM, Pete Batard wrote: > OK, let's try to strike the iron while it's hot, and get an idea of how > we could implement these platform/OS specific calls. And since I'm > interested in finding out if there exists a best approach for these kind > of implementations, I'm gonna use a fairly concrete example of what we > may want to contend with, so that it's hopefully easier to point out > what works or doesn't work. > > So let's say we want to add a call for OS1 to be able to set/get > prop_os1_a, prop_os1_b and prop_os1_c, with prop_os1_[a-c] ranging from > regular C type, such as int, to platform specific structs or enums. > Now, unlike what will be the case in this example set and get are never > gonna be balanced, but it may help the discussion to consider we have > both a get and set for the same attribute. > > Now, let's assume: > - prop_os1_a = int value, not relying on additional external header > (i.e. straight numeric) > - prop_os1_b = os1_enum, defined in os1_enum.h > - prop_os1_c = struct os1_struct_t = { os1_enum, os1_type, char* }, with > os1_struct (and os1_type) defined in os1_types.h. > > We may also want to consider that there's a fair chance os1_struct could > be extended in the next iteration of the OS. More specifically, I'm > thinking about the obnoxious _EX Microsoftisms, which we had to contend > with internally in the Windows backend, with regards to retrieving USB > speeds (For an idea of the typical Windows landscape in that matter, > just know that there currently exists an > USB_NODE_CONNECTION_INFORMATION, an USB_NODE_CONNECTION_INFORMATION_EX > as well as an USB_NODE_CONNECTION_INFORMATION_EX_V2). > > And to make things even more fun, I'm gonna add that, on get, the char* > of prop_os1 is a string allocated by the OS, through the > os1_get_string_prop() API call, and that the OS requires us to free it > with an os1_free_string_prop() OS API call. > > For the sake of completion, I'm also gonna add OS2, with a single > prop_os2 value, as a numeric int, that we also want to be able to get/set. > > At the moment, my take on this would be to go with the following (bear > in mind that this is only an RFC) > > ------------------------------------------------------------------- > #if defined(OS1) > #include <os1_type.h> > #include <os1_enum.h> > > enum { > libusb_get_prop_os1_a, // Some of those would be dropped > libusb_set_prop_os1_a, // according to what we can get/set > libusb_get_prop_os1_b, > libusb_set_prop_os1_b, > libusb_get_prop_os1_c, > libusb_set_prop_os1_c, > } libusb_os_prop_op; > > struct { > enum libusb_os_prop_op op; > int *prop_os1_a; > int *prop_os1_b; > struct os1_struct *prop_os1_c; > // + whatever additional attributes may need to be > // fed to the OS to get some props. eg: > int *prop_os1_c_query_params; > } libusb_os_props; > > #elif defined(OS2) > #include <os2_whatever.h> > > enum { > libusb_get_prop_os2, > libusb_set_prop_os2, > } libusb_os_prop_op; > > struct { > enum libusb_os_prop_op op; > int *prop_os2; > // + additional props query specifics > } libusb_os_props; > > #endif > > // common prototypes > int libusb_rw_os_props(struct libusb_os_props *props); > > libusb_os_props *libusb_allocate_os_props(libusb_os_prop_op op); > > void libusb_free_os_props(libusb_os_props *props); > ------------------------------------------------------------------- > > Then a libusbx app using OS1, that wants to retrieve the string in > prop_os1_c would proceed as follows: > > ------------------------------------------------------------------- > struct libusb_os_props *props; > > props = libusb_allocate_os_props(libusb_get_prop_os1_c); > // The call above will allocate a new libusb_os_props struct, > // with op set to libusb_get_prop_os1_c, and with any attribute > // needed for the underlying get_prop_os1_c call also allocated > // In this case, that would be an int for prop_os1_c_query_params > // All other pointers, including prop_os1_c, would be NULL. > > // If needed, set the attribute(s) needed for get_prop_os1_c. eg: > props->prop_os1_c_query_params = OS1_PROP_C_QUERY_ENUM_VAL; > > // The following then relies on the backend to call > // os1_get_string_prop() and allocate a struct for the returned > // data in prop_os1_c (along with a string in prop_os1_c itself) > if (libusb_rw_os_props(props) == LIBUSB_SUCCESS) { > // PROCESS props->prop_os1_c.string > } > libusb_free_os_props(props); > // Besides freeing all elements that were allocated by libusbx, > // the above would also call os1_free_string_prop() > ------------------------------------------------------------------- > > Now, you might wonder why I choose to allocate pointers for everything, > including integers. This is mostly because that the 32 bit int bitmask > that the OS uses today may very well be extended to a 64 bit bitmask > tomorrow, and in case a shared libusbx library is replaced with an older > version, we might as well limit breakage due to shifted props > attributes. In short, we want our props struct to be able to grow, as > well as evolve some of its attribute in accordance to how the OS evolves > them, this using pointers everywhere should allow us to evolve our props > less disruptively. > > Finally, depending on the target of the underlying OS prop API call, we > may need to add a libusbx device, or transfer, or any other relevant > libusbx parameter to our props struct, but I don't consider this as much > of a concern. Also, though in the Windows backend, we currently set some > of the OS/driver specific properties during init, I don't exactly see a > need to extent init to accept props, which we could do, when we can just > issue an OS props call before or after. In other words, I don't > currently envision an OS props call that would absolutely have to be > carried out during init, but maybe someone can think of one. > > Anyway, at this stage, I'd appreciate comments on what you think the > most appropriate method would be, or where you think the above proposal > can break, as well as any alternative proposals you have. > > Regards, > > /Pete > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > libusbx-devel mailing list > libusbx-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/libusbx-devel > ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ libusbx-devel mailing list libusbx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libusbx-devel