WWDC2001 Session 203

Transcript

Kind: captions Language: en good afternoon and welcome to the USB overview session I'm Craig Keithley I'm the USB and firewire technology manager within Apple's Worldwide Developer Relations organization and a pleased to see you here today this session will cover some of the basics of usb on Mac OS 10 before I bring up the engineers to have them do the presentation I want to talk a little bit about the things that we like about USB in 10 and in general with our digital hub strategy one of those things is nature of powering devices over USB and more importantly than powering devices recharging devices so I brought with me here today a new cable this is a USB adapter cable for a palm 5 has a sync button in it and it charges the palm 5 you think about our iBook commercial we're running where the gentleman's sitting in the middle seat and he's playing with all's neat devices at 35,000 feet it wouldn't be too cool if all those devices required a power strip on the floor of the plane with a hundred and 10 volt to 12 volt converter to run all those devices so we really want you to look very carefully at powering your devices over USB and charging them over USB some devices that are good about this are things like the zip drive some of the floppy drives they receive power over the USB bus they operate without the need for an AC adapter this is a great way to go and if you can charge them that would be even better now as you know we've been doing USB for about 4 years now we've got a lot of experience in it we've got some of the best engineers in the business working on USB for Mac OS 10 we've made great progress we know we have more to get more distance to go on this so I want to leave you with a couple of thoughts with regard to helping us move forward on USB on 10 the first one is please use the bug reporting system we do look at those bug reports very seriously don't assume that we've seen a bug report don't assume that if it's happening to you we must have seen it and we must be fixing it we want to have those in the database we want to be working on them we want to know about them the other thought that I would share with you is that we are working very aggressively on providing updates you've watched us produce three updates in the last 58 days we will be doing more so if you get your bug reports in there's a very good chance we'll be able to move forward on them so with that I'd like to bring up Rhodes Halliwell and Dave Ferguson Dave is the software engineering manager for USB development on Mac os10 the ROS Halliwell is our lead engineer on USB development thanks very much good morning Thank You Craig well what we're gonna talk about today maybe there we go so what you're going to learn in this session is we're going to go over the USB hardware architecture as delivered in Macintosh models that we ship today I'll talk a little bit about where the different ports go numbers of controllers compatibility with different controllers that sort of stuff we'll talk about the driver architecture in Mac OS 10 specifically how it fits in with IO kit and and how that family fits with other families we will talk about converting your mac os9 drivers into ten so obviously you have a lot of experience developing mac OS 9 USB drivers we have a lot of devices and a lot of drivers and so I know that people have things and they want to get them converted over to OS 10 and so what's the same what's different what do you need to do to get started in doing that we'll detail a little bit of the differences between kernel mode and user mode drivers and we'll talk about what happens today when you have classic and you have support for existing USB drivers which USB devices can be operated in classic how do they work how does classic and native OS 10 drivers work together and finally we'll do a quick review of apples class drivers the drivers that we deliver so you can deliver USB products that don't have any software component at all that you need to use ur needs to install just drivers that we bring so Universal Serial bus Hardware has included in every Macintosh model since we introduced the iMac in August of 98 today every single machine that we ship has two independent USB buses both of those are ohci open host controller interface compatible our software is compatible with ohci controllers so in fact in addition to the two buses that we are supplying it's also possible to install install PCI cards or card bus cards that have ohci compliant controllers and our software will detect those cards and support the USB bus on that now other USB hardware that we have included with every machine in addition to the two independent buses we are also including hubs in both our monitors as well as the keyboards now the hubs that are in the monitors are all self powered hubs they provide more high power ports just like the ports on the back of a machine and the hubs that are in the keyboards are bus powered hubs so they can only supply the hundred milliamps of power and are useful for some some bus powered devices usually other self powered devices that it's just more convenient to plug them in right on the keyboard so controllers mice and stuff attached to a keyboard other high-powered devices we've made it convenient to put ports on the back or on the sides of of monitors so let's talk about how the i/o USB family and Mac os10 fits into the i/o kit family architecture this slide shows basically i/o kit as a large field with a whole series of families we've denoted some of these families with different colors indicating the type of family they are the i/o USB family is one of these on the Left which is a transport family it's one that actually transports data over some type of bus so IO USB family firewire family scuzzy family are all capable of transporting data over a specific bus things such as the IO serial family the scuzzy architecture family the audio family don't necessarily have a specific hardware component associated with them they're responsible more for managing and converting data to transport over some other families transport mechanism IO kit includes a lot more families than this I'm just trying to give you a sense of where USB fits into that family architecture ok thank you Dave so we're gonna talk a little bit about the i/o kernel drivers stack what happens when the system detects that USB is present so at the very early stage of USB initialization there is an i/o PCI device that the system detects and the PCI family is responsible for detecting this fan this this device and that device is the USB controller chip a the USB driver is then matched against that controller chip and the name of that the class of that driver is IO USB controller now this driver then initializes the USB controller chip and and and instantiates an IO USB device this device represents the root hub inside the controller chip so that USB PCI device is then matched by i/o kit and it loads another driver and the name of that driver is the Apple USB hub driver so this driver loads against any hub in the system including the root hub but in the case of the early initialization of the root hub it then scans the bus looking for USB devices so let's say we have a pair of speakers plugged into this bus well the i/o USB controller can have more than one child or client that it is a provider for and so it instantiates another kernel object c++ kernel object the in i/o kit called that is an i/o USB device representing these speakers there's a driver inside the in inside the system the matches against this device because it's a composite device and that driver sets the configuration inside the device which causes the interfaces to appear so one of these interfaces is the audio channel for this for these speakers and so this IOUs B interface appears and IO kit then matches a driver against it and in this case that driver is the Apple USB audio driver so this is just a quick overview of the stack of the i/o kit objects we will go into some more detail today and we will go into even more detail on this tomorrow now USB drivers are not members of the USB family they use the USB family for their transport mechanism and so they are clients of the USB family or in other words the USB family objects are the providers for these drivers so here for example is that same audio driver and it's provider is an i/o USB interface object but the driver is itself subclassed from the i/o audio device class which is a subclass of i/o service io service being the base class for all IO kit objects and so this driver is a member of the audio family and in turn this driver may have its own clients for what to do with this audio stream another example would be the a hid interface which then loads the hid driver which is a member of the hid family we represent this with these puzzle pieces because there can be a different hid driver that is a subclass of the i/o hid device class which uses a different transport mechanism than USB now how do the how does the API for USB and Mac os10 compare with the API and Mac OS 9 well many of the function names are similar but in fact they they're the API is vastly different in in the respect that in nine you have a parameter block interface whereas in 10 you have a series of C++ methods that you call you know with C++ so it and and and also in 10 in 9 all calls to the API are asynchronous calls you must provide a callback routine and everything happens asynchronously in 10 there is a capability for making synchronous calls to the USB stack however you must be careful about making these synchronous calls because it is there is a potential to deadlock the system finally in 9 everything is all memory buffers are passed as held and locked memory buffers whereas in 10 it's possible to pass buffers using an i/o kit object class called IO memory descriptor which we will get into in a little more detail now in the kernel the USB family provides 3 basic object classes that represent the the contents of a USB device these three classes are IOUs B device which is an encapsulation if you will of the device descriptor inside the physical device then there's the i/o USB interface class this is an encapsulation of the interface descriptor within a particular configuration of the device so if a configuration has 3 interface descriptors within it there will be 3 io USB interface objects which are created to represent those 3 interface descriptors finally there is the i/o USB pipe object this object encapsulate the the contents of an endpoint within an interface descriptor and it also provides the channel between the client software and the endpoint on the device from user space because Apple recommends that that you write your drivers in user space if at all possible we provide access to these same objects but we do them using the IO CF plug-in model that is part of i/o kit and we have to plug-in types that we provide in user space the IO USB device interface and the IO USB interface interface now these names can become a mouthful the i/o kit team decided to call these plugins device interfaces and of course in USB there is already the concept of a device as in a device descriptor and an interface as in an interface descriptor and so we actually had device device interfaces and interface device interfaces and that got to be a little much so we call them the i/o USB device interface and the i/o USB interface interface how do the memory buffers compare well as I said before in Mac OS 9 when you passed a memory buffer to USB because it was it needed to use DMA to transfer the actual data you would have to lock the memory and make sure that it was physically held in resident and pass a pointer to this memory in Mac OS 10 the this is handled with a concept called an i/o memory descriptor io memory descriptors are more flexible than just straight memory buffers because they can provide access to memory that is not necessarily contiguous a piece of the memory can be over here and then the next piece of the memory can be over here and then another piece can be somewhere else and the memory descriptor can describe that and then the USB engine can then transfer the data into into disjoint buffers also if you are accessing to passing the memory and from user space the memory does not necessarily need to be wired into the kernel address space in order to be used these memory descriptors can describe memory that is inaccessible from the kernel directly but is excess using DMA and this is a benefit because wiring memory into kernel address space is a very expensive operation and one that we hope that to avoid at all costs now user mode code that accesses USB does in fact pass these buffers as straight memory buffers just pointers but within the kernel the memory descriptors are used to manipulate them and to get the physical address for the DMA engine as I said before with OS 10 it's possible to use synchronous i/o as opposed to having every call in the API be asynchronous this means that you can make a call that will block your thread until the call completes if you are writing a user land driver this is something that is always safe to do you make a synchronous call your thread blocks and when the call completes your thread picks up again if you are running a kernel mode driver you must be careful that this synchronous call does not deadlock your thread and there are specific guidelines to help do that and we're learning more about how to document that as we go along if you do make asynchronous calls then there's two methods for continuing the processing once your call once your callback routine is called within the kernel your callback routine will be called immediately upon the completion of the routine and and your execution thread will in fact pick up at your callback routine once the processing is done it's slightly different in user mode there is no mechanism with Mac os10 and with i/o kit to make direct callbacks from kernel run threads to user threads and so what happens is a mock message is posted on a port the colonel side and then there's a user thread that will check that port using the CF run loop technology for that callback ret message and trend and at that point dispatch the callback routine so how do drivers get matched and loaded with Mac OS 10 well the first thing that happens is when a device is plugged in the hub driver that is controlling the hub to which that device is attached notice as the port turns it on does typical USB enumeration things and creates the i/o USB device based on the information it finds in the device descriptor it then tells i/o kit I have I have this new device please find a driver for it so first I oak it looks through its entire table of drivers that it knows about and it creates a pool of drivers that are capable of driving an i/o USB device object it then passes the information from the i/o USB device object into each of the into the USB family with the information from the driver and it says tell me what you think about this driver running with this device and the USB family does a scoring system where the different drivers are scored based on the criteria specified by the USB common class specification this creates a ranked list and then the in an i/o kit goes through the drivers and can call the probe method such that any driver in the list can say no I'm not interested in controlling that device so this is a three level matching system and at the end there is an ordered list of drivers with a ranking ioq it then takes the top driver in that ranking and says okay it's your device and as long as that driver comes back and says I got it it's mine then that's it if the driver comes back and says oh no I changed my mind I'm not interested in that device anymore then the next driver and the list is tried so what happens when a driver when a USB device is removed do you unplug it well the hub driver again notices that the device has gone away and it is a terminate message to the i/o USB device object which in turn sends the terminate message or sends a message to each of its children including a driver and potentially any i/o USB interface objects which in turn send messages to their children and so forth so that the leaf node of the tree gets notified hey it's time to go away it cleans up and then that propagates back up so that eventually the i/o USB device object cleans up and goes away so if your driver is the leaf node in this process you get a message saying hey it's time for you to stop doing any i/o because your parent is about to go away the driver then says ok closes the parent terminates its its state machine and i/o kit removes the driver from memory so how do drivers if you will work from user space Apple again recommends that you write your USB Driver code to work in user space however you have to be aware that user space drivers which are really just threads that run in user space and are typically packaged as as libraries but they but in in one sense they will function just like applications in the in in in that they the matching has to you know they have to there's no automatic matching for them so these drivers do not compete with the kernel drivers so if there is a user space driver for a particular device and a kernel mode driver for a particular device the kernel mode driver ends up winning the race and controlling the device user space drivers can code that's running demon code for example that gets notified by i/o kit whenever a new USB device appears in the system however once again this notification doesn't happen until after the kernel drivers get a chance to control the device and so sometimes it may be necessary to create a dummy driver in the kernel which claims the device so that then later on some user land code can take over that device so if you are running in user code how do you find the device you're interested in well there are some i/o kit mat matching io kit service calls that you use to find your device the first one hears here are some some IO kit calls the first one is service matching says I want to create a matching dictionary that looks for any device in the kernel whose type is IO USB device then it calls IO service get matching services and it passes in this matching dictionary and i/o kit returns an iterator of all the devices that it found that match that criteria finally the user code can create a while loop that looks through all the devices of this iterator and decide which one's it is interested in controlling if any so how do we share a device well Dave's gonna talk about this okay so let's talk a little bit about device sharing now the IO kit model for using a particular object down in the kernel whether it's a USB interface or a USB device object is that it's exclusive access only one thing can be accessing that particular object at a time the i/o USB family enforces that by allowing only one entity to open that at a time however there are method and mechanisms by which tasks or threads can cooperatively share a device and as we're all starting to develop drivers and we're getting more user mode drivers people are interested in how we do that and I want to talk a little bit about that the key is a message method that your driver provides whether it's a user mode driver or a kernel mode driver and there are two specific messages that are passed one is and this happens when you have a particular device open one is a message that says io message service is requesting close so this says that another entity is attempting to open this device and it's requesting that the entity that currently has it open please close down now you don't have to close down at that you can know that you have IO active at the time and you don't want to do that but if you are merely keeping the device open let's say in the example that it's modem and you're waiting for a call to come in well the driver that's waiting for a call to come in can go ahead and close up because a call hasn't come in and another entity would like to use it to make an outgoing call so you can close that and you can get notifications whenever someone else closes a particular object and a USB device or a USB interface object the other message that can come in while you have the object open is the IO message service is attempting open so this is where you can find out that another entity is trying to open you but he has not requested that you close down he's not requested to grab the interface he's just tried to open it to see if it's available in general a shared device would want to close down in that particular circumstance as well so requesting closed is kind of a more urgent request to close down attempting open is your clue that someone else would like to access that device and you should close it if at all possible now this sharing mechanism is is really how we intend for user mode control panels that want to set particular states in a device might get to that even though a kernel-mode driver provides most of the transport with the device the user mode driver would attempt to open that thing that that object and would do it with the claim flag we were working on the API to get that set up that generates this services requesting close message and that's how a driver knows now this device sharing model also works with USB in classic classic is nothing more than a particular application that is being a user mode driver okay for one particular USB device object down in the kernel let's talk about the classic side for a moment and then we'll talk about how classic uses Mac OS 10 classic presents the entire mac OS 9.1 operating system to applications that includes things like USB driver our entire mac os9 USB stack is living within the classic environment if you have an existing classic driver for a vendor specific device classic can open that device object using the user mode mechanism and can make that device available just as though it were plugged into an OHA eye controller directly attached to classic and the USB stack will do all of the exact same enumeration discover a device load a classic driver exactly the same way it does in Mac OS 9 right right now so a driver shouldn't see any difference between how a device behaves within classic and how it behaves in pure native Mac OS 9.1 today classic classic attempts to capture two different kinds of devices the first is printer devices and because we have the Print Center inside of Mac OS 10 that has a USB client and already knows to talk to USB printing devices for things that have 10 native imaging drivers available it's already available for applications that want to print in Mac OS 10 some applications such as classic wouldn't have access to the Mac os10 Print Center so we decided to make printers available directly within classic and we just use whatever driver was available within classic whether it be the Apple USB printer class driver that we provide or whether it's a vendor specific printer class driver we allow that to load and match the same way it always does so within a classic application you use the chooser to select which printer it is you want to print to and and printing works by using the classic USB emulation the other type of device that classic will attempt to claim and control our vendor specific devices any vendor specific device that wasn't claimed by a vendor specific OS 10 native driver well it just defaults to going to the classic user mode driver now this can be a little tricky while you're trying to develop your code because you might have classic loaded and classic is loaded and running so that you can run some some legacy application and meanwhile you're trying to do K mod load of of specific drivers and classic keeps grabbing host devices every time you plug it in because because it grabs vendor specific devices and printer devices classic is migrating toward using the sharing model the same one I just talked about right here it's gonna use and support these exact same messages so it's gonna play fair with all the other user mode drivers and all the other kernel mode drivers as long as we all use this sharing model things are gonna work great ok the Apple class drivers that we are providing with Mac OS 10 is almost the full complement of drivers that we're providing on 9 currently the drivers that we are providing or of course the hub class driver and the HID class driver for hid devices mice keyboards we do have a new API available in Mac OS 10 that we did not have in mac os9 called the hid manager and the hid manager encapsulate a lot of the same functionality that we had within the hid library within Mac OS 9 point 1 so the hid library functionality has sort of rolled into this new hid manager API the hid manager in addition to working with USB HID devices also works with other hid devices that might be attached to the system and actually makes them kind of look like USB HID devices it uses USBs hid reports and hid report descriptors as a mechanism to describe the data that comes from a device so adb mice you know if Mac OS 10 was running on a machine that had ADB and an ADB Mouse would actually show up in the hid manager just like it were kind of a USB device with an actual report descriptor and reports and all of that information the other driver that other drivers were providing include the audio class driver the audio class driver currently supports stereo input output audio classes one of the drivers that was updated with the recent 1002 and 1003 updates included new USB audio class drivers and there's more on the way from the audio team those guys are working really hard trying to get all the the support for all the devices that are out there we have a mass storage class driver this does actually more than our storage class driver in Mac OS 9 did the storage class driver in 10 supports optical media as well because the mass storage team has abstracted the scuzzy architecture model family and was one of the families that we saw in the i/o kid family it can actually support other devices that are attached via USB as its transport mechanism but actually are communicated with scuzzy commands the storage class guys are working on their stuff too we were on a couple of things that worked pretty well on mac OS 9 manual eject and stuff is on its way communication devices this is the exact same support for abstract control MA idle modems you have that available in Mac os10 just like you did in nine and of course we have printing class support what we had on Mac OS 9 was printing class support for any imaging chooser type driver and that included our laser writer postscript driver for PostScript printers we include exactly the same functionality on OS 10 and it's possible to write new Print Center imaging pieces that plug in and still use our printing class transport mechanism you just have to worry about the imaging will help you get the data to the printer okay that about sums up our overview we have a few few slides here with where you might turn for more information in addition to the URLs here you don't need to copy those down they're available on a specific page off of the Apple comm website places that we would point you to include the USB implementers forum USB implementers forum contains the actual specs for USB for the classes of drivers that we've talked about ample supporting it includes information about upcoming classes I'm sure you're all familiar with the getting documentation off of there you can find Mac OS 10 developer information on developer.apple.com slash Mac OS X and USB information is available on developer.android.com type of information all we are really providing is some example code and it automatically installs in slash developer slash examples I believe the other thing that gets installed when you install our SDK is the absolute latest header file that you would need if you're compiling a USB project now other USB drivers one of the things we did in our DDK is we separated out the actual drivers that we used in OS 9 and made them available as sample code well all of the i/o USB family is available as sample code inside the darwin project so it's possible for you to take a look at how any well practically all of our USB drivers are available in darwin and all of the source code to the family is in darwin the USB team operates out of that darwin deposit or repository live so when we check in some new code or new fixes or new changes they're actually available in darwin almost immediately and and you can check those out and see what we're up to we love bug reports that say in this file on that line that line right there is wrong so feel free to send those to us okay other sessions that you might want to know about at WWDC yesterday you have the i/o kit update right after this session we'll have the i/o kit storage drivers there is a session on the image capture framework tomorrow tomorrow morning and of course our USB in-depth is available tomorrow at 3:30 p.m. that seems wrong I thought it was 2 o'clock but anyway it's available tomorrow in the Civic Auditorium which is across the street finally we have our feedback forum on Thursday an always popular event we're looking forward to it okay if you want to gonna contact somebody at Apple Craig Keithley he's the guy he does USB and firewire there's his email address and we have a developer mailing list where developers help each other with questions and answers and the USB team when it as time tries to provide a little guidance there as well so it's a good way to keep track of what's going on with USB you