Top Banner
1.1.2 USB Developer’s Kit Programmer’s Guide EDITION 2
135
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Usb Developers Kit Programmers Guide 1.1.2 (1)

1.1.2

USB Developer’s Kit

Programmer’s Guide

EDITION 2

Page 2: Usb Developers Kit Programmers Guide 1.1.2 (1)

Copyright 2003 Wind River Systems, Inc.

All rights reserved. No part of this publication may be reproduced or transmitted in anyform or by any means without the prior written permission of Wind River Systems, Inc.

Wind River, the Wind River logo, Tornado, and VxWorks are registered trademarks ofWind River Systems, Inc. Any third-party trademarks referenced are the property of theirrespective owners. For further information regarding Wind River trademarks, please see:

http://www.windriver.com/company/terms/trademark.html

Corporate HeadquartersWind River Systems, Inc.500 Wind River WayAlameda, CA 94501-1153U.S.A.

toll free (U.S.): (800) 545-WINDtelephone: (510) 748-4100facsimile: (510) 749-2010

For additional contact information, please visit the Wind River URL:

http://www.windriver.com

For information on how to contact Customer Support, please visit the following URL:

http://www.windriver.com/support

USB Developer’s Kit Programmer’s Guide, 1.1.2Edition 223 Apr 03Part #: DOC-14516-ZD-02

Page 3: Usb Developers Kit Programmers Guide 1.1.2 (1)

Contents

1 USB Host Stack ........................................................................................................ 1

1.1 Introduction ...................................................................................................... 1

1.1.1 System Requirements ........................................................................ 2

1.1.2 Documentation ................................................................................... 2

Reference Manual Entries ................................................................. 4Related Documentation .................................................................... 5

1.2 Architecture Overview .................................................................................... 5

Host Module Roadmap ..................................................................... 7

1.3 The USB Host Driver (USBD) ......................................................................... 11

1.3.1 Initializing the USBD ......................................................................... 11

Attaching and Detaching HCDs ...................................................... 12Order of Initialization ........................................................................ 14Bus Tasks ............................................................................................. 15Registering Client Modules .............................................................. 16Dynamic Attachment Registration .................................................. 18Device Configuration ........................................................................ 20Data Flow ............................................................................................ 22

1.3.2 USBD Internals ................................................................................... 24

Hub Management .............................................................................. 24New Device Connections .................................................................. 25

iii

Page 4: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.4 The USB Host Controller Driver (HCD) ....................................................... 25

1.4.1 HCD Header File ............................................................................... 25

1.4.2 HCD Entry Point ............................................................................... 26

1.4.3 Host Request Blocks (HRB) .............................................................. 26

HCD_FNC_ATTACH ........................................................................ 27HCD_FNC_DETACH ....................................................................... 28HCD_FNC_BUS_RESET ................................................................... 28HCD_FNC_SET_BUS_STATE .......................................................... 29HCD_FNC_SOF_INTERVAL_GET and

HCD_FNC_SOF_INTERVAL_SET ................................... 29HCD_FNC_PIPE_CREATE .............................................................. 30HCD_FNC_PIPE_DESTROY ........................................................... 32HCD_FNC_PIPE_MODIFY ............................................................. 32HCD_FNC_CURRENT_FRAME_GET ........................................... 33HCD_FNC_IRP_SUBMIT ................................................................. 33HCD_FNC_IRP_CANCEL ............................................................... 39

1.4.4 Management Events .......................................................................... 39

1.4.5 HCD Error Reporting Conventions ................................................ 40

1.4.6 Root Emulation .................................................................................. 41

1.4.7 IRP Timeouts ...................................................................................... 41

1.5 Keyboard Driver .............................................................................................. 42

1.5.1 SIO Driver Model .............................................................................. 42

1.5.2 Dynamic Attachment ........................................................................ 43

1.5.3 Initialization ....................................................................................... 46

1.5.4 ioctl Functions .................................................................................... 46

1.5.5 Data Flow ............................................................................................ 46

1.5.6 Typematic Repeat .............................................................................. 47

1.6 Mouse Driver .................................................................................................... 48

1.6.1 SIO Driver Model .............................................................................. 48

1.6.2 Dynamic Attachment ........................................................................ 48

1.6.3 Initialization ....................................................................................... 49

iv

Page 5: Usb Developers Kit Programmers Guide 1.1.2 (1)

Contents

1.6.4 ioctl Functions .................................................................................... 49

1.6.5 Data Flow ............................................................................................ 50

1.7 Printer Driver .................................................................................................... 50

1.7.1 SIO Driver Model ............................................................................... 51

1.7.2 Dynamic Attachment ........................................................................ 51

1.7.3 Initialization ........................................................................................ 52

1.7.4 ioctl Functions .................................................................................... 53

1.7.5 Data Flow ............................................................................................ 53

1.8 Speaker Driver .................................................................................................. 53

1.8.1 SEQ_DEV Driver Model ................................................................... 54

1.8.2 Dynamic Attachment ........................................................................ 54

1.8.3 Initialization ........................................................................................ 55

1.8.4 Recognizing and Handling USB Speakers ..................................... 56

1.8.5 ioctl Functions .................................................................................... 56

1.8.6 Data Flow ............................................................................................ 57

1.9 Mass Storage Class Driver .............................................................................. 57

1.9.1 Block Device Driver Model .............................................................. 59

1.9.2 Dynamic Attachment ........................................................................ 62

1.9.3 Initialization ........................................................................................ 62

1.9.4 Data Flow ............................................................................................ 63

1.10 Communication Class Drivers ....................................................................... 63

1.10.1 Ethernet Networking Control Model Driver ................................. 63

Enhanced Network Driver Model ................................................... 65Dynamic Attachment ........................................................................ 65Initialization ........................................................................................ 66Interrupt Behavior ............................................................................. 66ioctl Functions .................................................................................... 66Data Flow ............................................................................................ 67

v

Page 6: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.10.2 Abstract Control Model Driver ....................................................... 67

SIO Driver Model .............................................................................. 67Dynamic Attachment ........................................................................ 68Initialization ....................................................................................... 69Interrupt Behavior ............................................................................. 69ioctl Functions .................................................................................... 69Data Flow ............................................................................................ 69Modem Control: Hayes Commands ............................................... 70

1.11 Running the USB Kit ....................................................................................... 70

1.12 Initialization ...................................................................................................... 73

1.12.1 Host Stack and Host Controller Initialization ............................... 73

1.12.2 Device Initialization .......................................................................... 73

Keyboard, Mouse, Printer, and Speaker Initialization ................. 73Mass Storage Class Device Initialization ....................................... 74Communication Class Device Initialization .................................. 74

1.12.3 usbAudio Initialization ..................................................................... 75

1.12.4 usbTool Code Exerciser ..................................................................... 75

Running usbTool from the Shell ...................................................... 76The usbTool Execution Sequence .................................................... 76

1.13 Booting VxWorks Through a Communication Class Driver ..................... 77

1.14 Benchmarking Information ............................................................................ 81

1.15 BSP Porting Issues ........................................................................................... 84

1.15.1 Configuring USB Hardware ............................................................. 85

BSPs with pciAutoConfigLib ........................................................... 85BSPs Without pciAutoConfigLib ..................................................... 86

1.15.2 Configuring Memory Address Windows ...................................... 87

1.15.3 Creating BSP-Specific Stub usbPciLib Files ................................... 88

2 USB Peripheral Stack ............................................................................................... 91

Tested Devices .................................................................................... 91

vi

Page 7: Usb Developers Kit Programmers Guide 1.1.2 (1)

Contents

2.1 Peripheral Stack Architecture ......................................................................... 92

Peripheral Module Roadmap ........................................................... 93

2.2 USB Target Driver (usbTargLib) ..................................................................... 97

2.2.1 Initializing usbTargLib ...................................................................... 97

2.2.2 Attaching and Detaching TCDs ....................................................... 98

2.2.3 Enabling and Disabling TCDs .......................................................... 99

2.2.4 Target Application Callback Table ................................................... 100

mngmtFunc( ) Callback ..................................................................... 101Control Pipe Request Callbacks ....................................................... 102

2.2.5 TCD Endpoints ................................................................................... 107

2.2.6 Data Transfer ...................................................................................... 109

Control Pipe Data Transfers ............................................................. 110General Data Transfers ...................................................................... 111

2.2.7 Setting Endpoint Stall ........................................................................ 111

2.2.8 Bus Frame Number ............................................................................ 112

2.2.9 Resume Signaling ............................................................................... 112

2.3 USB Target Controller Driver ......................................................................... 112

2.3.1 TCD Header File ................................................................................ 113

2.3.2 TCD Entry Point ................................................................................. 113

2.3.3 Target Request Block (TRB) .............................................................. 113

TCD_FNC_ATTACH ......................................................................... 114TCD_FNC_DETACH ......................................................................... 115TCD_FNC_ENABLE ......................................................................... 115TCD_FNC_DISABLE ......................................................................... 116TCD_FNC_ADDRESS_SET .............................................................. 116TCD_FNC_ENDPOINT_ASSIGN ................................................... 116TCD_FNC_ENDPOINT_RELEASE ................................................ 117TCD_FNC_SIGNAL_RESUME ........................................................ 118TCD_FNC_ENDPOINT_STATE_SET ............................................. 118TCD_FNC_CURRENT_FRAME_GET ............................................ 119TCD_FNC_ERP_SUBMIT ................................................................. 119TCD_FNC_ERP_CANCEL ............................................................... 119

vii

Page 8: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

2.3.4 TCD Management Events ................................................................ 120

2.3.5 TCD Error Reporting Conventions ................................................. 120

2.4 Installing the USB Peripheral Stack ............................................................... 121

2.5 Running the USB Peripheral Stack ................................................................ 124

2.5.1 Creating a Downloadable VxWorks Image Including USB ......... 124

2.5.2 Creating a Downloadable USB Application .................................. 125

2.6 Working with usbTool ..................................................................................... 125

The usbTool Execution Sequence .................................................... 125

2.7 BSP-Specific Issues ........................................................................................... 127

viii

Page 9: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

USB Host Stack

1.1 Introduction

The Universal Serial Bus (USB) provides hosts and devices with a versatile channelfor communication at low to moderate speeds. The USB currently offers thefollowing types of service at low (1.5 Mbps) and medium (12 Mbps) data transferrates:

� control transfers� bulk transfers� interrupt transfers� isochronous transfers

The USB also incorporates provisions for power management and for the dynamicattachment and removal of devices.

This flexibility allows the USB to be used—often concurrently—by a number ofdifferent kinds of devices, each requiring its own device driver support. It isdesirable that these device drivers be written independent of each other andindependent of the implementation of the host computer’s underlying USB hostcontroller interface. Wind River’s USB host driver stack meets these requirements,providing a complete set of services to operate the USB and a number of pre-builtUSB class drivers that handle specific kinds of USB devices.

The USB Developer’s Kit, also referred to as the USB Kit, includes the followingsoftware and hardware items:

� Source and object code for the USB host stack and drivers.

� The USB Developer’s Kit Programmer’s Guide (this document).

� The USB Developer’s Kit Release Notes.

1

Page 10: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The USB Kit shows you how to write your own USB host controller driver and USBdevice drivers. It is designed to allow the following:

� Easy portability to RTOSs other than VxWorks.

� Fast development of new host controller drivers.

� Easy portability to many BSPs.

1.1.1 System Requirements

Tornado 2.0 runs on PCs and Sun-4 workstations. Host systems must have thefollowing resources:

� 64 MB RAM.

� 15 MB disk space for typical installation.

� A CD-ROM drive for installation.

� For Solaris, a SPARCstation 5 minimum; Ultra5 is recommended. ForWindows, an Intel 80486 or better; Intel Pentium 90 or better is recommended.

1.1.2 Documentation

The USB Developer’s Kit Programmer’s Guide, 1.1.1 (this manual), describes thearchitecture and implementation of Wind River’s USB host and peripheral stacks.The guide contains the following sections:

� 1.2 Architecture Overview, p.5, provides a high-level look at USB organizationand introduces the various modules.

� 1.3 The USB Host Driver (USBD), p.11, includes important information forwriting host client class drivers and other applications.

� 1.4 The USB Host Controller Driver (HCD), p.25, provides information neededto port the USB host stack to run on different host controllers.

� 1.5 Keyboard Driver, p.42, 1.6 Mouse Driver, p.48, 1.7 Printer Driver, p.50,1.8 Speaker Driver, p.53, 1.9 Mass Storage Class Driver, p.57, 1.10.1 EthernetNetworking Control Model Driver, p.63, and 1.10.2 Abstract Control Model Driver,p.67, offer essential information if you are creating specific verticalapplications using the USB stack.

2

Page 11: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

� 1.11 Running the USB Kit, p.70, describes how to use the USB Kit with VxWorksand the Tornado Integrated Development Environment (IDE).

� 1.12 Initialization, p.73, contains instructions for initializing the host stack, hostcontrollers, external devices, and sample applications, and for USB-UGLconfiguration. This section also includes information on the usbTool codeexerciser.

� 1.13 Booting VxWorks Through a Communication Class Driver, p.77, describeshow to boot VxWorks through a Communication Class driver.

� 1.14 Benchmarking Information, p.81, provides metrics from a sample system forcomparing test results.

� 1.15 BSP Porting Issues, p.84, provides tips on porting the USB to other BSPs.

� 2.1 Peripheral Stack Architecture, p.92, provides a high-level look at USBperipheral stack organization and introduces the various associated modules.

� 2.2 USB Target Driver (usbTargLib), p.97, provides information about the USBtarget driver, usbTargLib.

� 2.3 USB Target Controller Driver, p.112, provides information essential to portthe USB peripheral stack to run on different target controllers.

� 2.4 Installing the USB Peripheral Stack, p.121, describes the installationprocedure and the locations of installed directories and files.

� 2.5 Running the USB Peripheral Stack, p.124, provides information for setting upyour Tornado environment to use the peripheral stack.

This manual assumes that you are already familiar with the USB specification andWind River’s Tornado IDE and VxWorks operating system. The Wind River USBdriver stack has been developed in compliance with the Universal Serial BusSpecification, Revision 1.1, generally referred to in this document as the “USBspecification.” Where possible, this manual uses terminology similar to that usedin the USB specification so that the correspondence between USB concepts andactions is readily apparent in the software interfaces described.

3

Page 12: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Additional Documentation

� PDIUSBD12 Evaluation Board (PC Kit) User’s Manual, Rev. 2.1, which isincluded on the floppy disk distributed with the Philips evaluation kit.

� Firmware Programming Guide for PDIUSBD12, Version 1.0, which is included onthe floppy disk distributed with the Philips evaluation kit.

Reference Manual Entries

Reference pages for the USB Kit libraries and subroutines can be accessed onlinein HTML from the Tornado Help>Manual Index menu command. Search the displaybox for USB-related libraries in the VxWorks Reference Manual, as in Figure 1-1.

Figure 1-1 Tornado Online Manuals Tree

4

Page 13: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

Related Documentation

� USB Developer’s Kit Release Notes, 1.1.1

� Universal Serial Bus Specification, Revision 1.1, September 23, 1998. All USBspecifications are available at www.usb.org/developers/docs.html.

� USB device class specifications. All USB specifications are available atwww.usb.org/developers/docs.html.

� OHCI and UHCI host controller specifications:

– for OHCI:http://www.compaq.com/productinfo/development/openhci.html

– for UHCI:http://developer.intel.com/design/USB/UHCI11D.htm

� Tornado User’s Guide 2.0

� VxWorks Programmer’s Guide 5.4

� VxWorks Reference Manual 5.4

1.2 Architecture Overview

Figure 1-2 presents a simplified overview of the USB host driver stack architecture.

At the bottom of the stack is the USB host controller (USB HC), the piece of hardwarein the host system that controls each USB. Currently, there are two major familiesof USB host controllers on the market, those supporting the Universal HostController Interface (UHCI) originally put forth by Intel, and those supporting theOpen Host Controller Interface (OHCI) designed by Microsoft, Compaq, andNational Semiconductor. A number of hardware manufacturers have built USBHCs around one or the other of these specifications.

For each type of host controller there is a single, hardware-dependent USB hostcontroller driver (HCD). For example, Wind River provides the source for twopre-built drivers:

– usbHcdUhciLib for UHCI HCs

– usbHcdOhciLib for OHCI HCs

5

Page 14: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The interface between the USB host driver (USBD) and the HCD allows for eachHCD to control one or more underlying HCs. Also, Wind River’s USBD is capableof connecting to multiple USB HCDs simultaneously. These design features allowyou to build a range of complex USB systems.

The USBD is the hardware-independent module above the HCD(s). The USBDmanages each USB connected to the host and provides the path through whichhigher layers communicate with the USB. Among its responsibilities, the USBDhandles USB power management and USB bandwidth management automatically.Also, unique to the Wind River architecture, the USBD manages USB hubs. Hubfunctionality is critical to the proper operation of the USB, so the designers of theWind River USBD concluded that hub functionality should be handled

Figure 1-2 USB Host Driver Stack

USB Client Module(for example, USB Class Drivers)

USB Host Driver(USBD)

USB Host Controller Driver(HCD)

USB Host Controller(USB HC)

USBD Interface

USBD/HCD Interface

Software

Hardware

6

Page 15: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

transparently by the USBD. This means that the USBD also handles the dynamicattachment and removal of USB hubs and devices.

Figure 1-2 shows the USB Client Module at the top of the stack. USB class driversare typical examples of client modules. USB class drivers are responsible formanaging individual types of devices that can be connected to the USB; they relyon the USBD to provide the communication path to the individual devices.Applications, diagnostics, and test programs are other examples of client modulesthat rely on the USBD to communicate with USB devices. For example, Wind Riverprovides the test application/module usbTool, which gives you interactive controlover the USB and USB devices.

Host Module Roadmap

The diagram in Figure 1-3 illustrates the functional relationships among themodules that comprise Wind River’s USB host driver stack. Each module is furtherdescribed in this section; for additional information on USB-related libraries andsubroutines, see the associated reference pages in the online VxWorks ReferenceManual: USB Libraries.

usbToolThis module is a test application that gives you interactive control of the USBhost driver stack. The usbTool utility exports a single entry point, usbTool( ),that invokes a command-line-driven interactive environment in which theoperator can initialize components of the USB driver stack, interrogate eachUSB connected to the system, send USB commands to individual USB devices,and test other elements of the USB stack. The usbTool test application is mostuseful during development and testing and does not need to be included in ashipped product.

cmdParserThis module provides generalized command-line parsing functions used byusbTool. The cmdParser module needs to be present only when usbTool isbeing used.

NOTE: The usbTool module relies internally on static data; you should not runmultiple instances of usbTool simultaneously.

NOTE: The usbTool utility resides in target/config/comps/src and is calledusrUsbTool.c.

7

Page 16: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Figure 1-3 Host Module Roadmap

usbToolUSB Exerciser Utility

usbdLib

usbdCoreLib

usbPciLib (usbPciStub.c)

cmdParser

usbHcdLib

usbdHcdOhciLib

usbdHcdUhciLibHCD for UHCI

System Hardware(for example, PCI bus controller)

UHCI or OHCIHost Controller

Software

Hardware

ossLib

usbLib

usbQueueLibusbHandleLib

usbListLib

Class Drivers

usbSpeakerLib

usbMouseLib

. . .

8

Page 17: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

usbKeyboardLibThis module is the USB class driver for USB keyboard devices; for moreinformation, see 1.5 Keyboard Driver, p.42.

usbMouseLibThis module is the USB class driver for USB mouse devices; for moreinformation, see 1.6 Mouse Driver, p.48.

usbPrinterLibThis module is the USB class driver for USB printer devices; for moreinformation, see 1.7 Printer Driver, p.50.

usbSpeakerLibThis module is the USB class driver for USB speaker devices; for moreinformation, see 1.8 Speaker Driver, p.53.

usbBulkDevLiband usbCbiUfiDevLib

These modules are the USB class drivers for USB Mass Storage Class devices;for more information, see 1.9 Mass Storage Class Driver, p.57.

usbPegasusEndLib,usbKlsiEndLib,and usbNC1080EndLib

These modules are the USB class drivers for USB Ethernet Networking ControlModel Communication Class devices; for more information, see 1.10.1 EthernetNetworking Control Model Driver, p.63.

usbAcmLibThis module is the USB class driver for USB Abstract Control ModelCommunication Class devices; for more information, see 1.10.2 AbstractControl Model Driver, p.67.

usbdLiband usbdCoreLib

These modules contain the functionality of the Wind River USBD. TheusbdLib module contains the USBD functions available to USB clientmodules; and usbdCoreLib exports a single entry point, usbdCoreEntry( ),which is used internally by usbdLib and is never called directly by othermodules.

usbHcdLibThis module provides routines to invoke each of the services provided by aUSB HCD. It is used by usbdCoreLib to communicate with underlying HCDs.The routines in usbHcdLib are not called directly by modules other thanusbdCoreLib.

9

Page 18: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

usbHcdUhciLiband usbHcdOhciLib

The usbHcdUhciLib and usbHcdOhciLib modules are the HCDs for UHCIand OHCI host controllers, respectively. All hardware-dependent code for ahost controller is contained in the HCD. Each HCD exports a single entrypoint, generally with a name of the form usbHcdXxxxExec( ), and allcommunication with the HCD is performed through this routine. There is nodirect link between the USBD and any underlying HCDs; that is, the USBD hasno prior knowledge of which HCDs will be loaded in a given system. EachHCD’s entry point is exposed to the USBD during a process called HCDattachment; for more information, see Attaching and Detaching HCDs, p.12.

usbPciLibThe module usbPciLib exists conceptually; however, it is available in the formof BSP-dependent files of the format target/config/BSP/usbPciStub.c. Thismodule provides HCDs with an abstracted view of the underlying PCIhardware and software in a system (both UHCI and OHCI host controllers areimplemented with PCI interfaces). So, while different Wind River BSPs use thestandard Wind River PCI libraries in different ways, the usbPciLib stub filesshield the HCDs from variations among BSPs. This allows HCDs to be writtenindependent of the underlying BSP and promotes portability of HCDs acrossBSP platforms.

ossLibThis module provides an abstracted and simplified view of VxWorksoperating system services to the USB driver stack. It includes routines thatmanage tasks, mutexes, semaphores, memory allocation, and system time.

usbLibThis module provides a mixed collection of USB utility functions shared byvarious modules. The USBD, HCDs, and certain USB class drivers make use ofone or more functions in this module. For example:

� The usbLib module contains routines that the USBD and HCD use todetermine the amount of bandwidth a specified pipe requires.

� Other usbLib routines provide the functionality that allows class driversto issue commands to devices using the device’s control pipe.

usbQueueLibThis module provides an abstracted queue model used by several of themodules in the USB driver stack, principally usbdCoreLib. The usbdCoreLibmodule uses these queuing services to pass messages among internalusbdCoreLib tasks.

10

Page 19: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

usbHandleLibThis module provides an abstracted handle allocation and validation libraryused by several of the modules in the USB driver stack. The USB driver stackuses handles to prevent callers from passing invalid device and pipereferences to the stack. The USB stack also uses the handle mechanisminternally to prevent background usbdCoreLib tasks from performingoperations on stale data structures. The handle validation mechanisms areoptimized and introduce negligible overhead.

usbListLibThis module provides a generalized set of functions to operate ondoubly-linked lists. These functions are used by most of the modules in theUSB driver stack, and most data structures in the USB driver stack belong toone or more lists at any given time.

1.3 The USB Host Driver (USBD)

This section describes typical use of the USBD: activities such as initialization,client registration, dynamic attachment registration, device configuration, anddata transfers. It also discusses key features of the USBD’s internal design.

1.3.1 Initializing the USBD

Initializing the USBD is a two-step process. First, the USBD’s entry point,usbdInitialize( ), must be called at least once. The usbdInitialize( ) routineinitializes internal USBD data structures and, in turn, calls the initialization entrypoints of other modules in the USB driver stack. In a given system, it is acceptableto call usbdInitialize( ) once (perhaps during the boot sequence) or to call it manytimes (as during the initialization of each USBD client). The USBD maintains ausage count that is incremented for each successful call to usbdInitialize( ) anddecremented for each corresponding call to usbdShutdown( ). The USBD onlytruly initializes itself when the usage count goes from zero to one, and it only truly“shuts down” when the usage count returns to zero.

11

Page 20: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The following code fragment illustrates the proper initialization and shutdown ofthe USBD:

.../* Initialize the USBD. */if (usbdInitialize () != OK)

return ERROR;....../* application code. */....../* Shut down the USBD. Note: we only execute this code if the return* code from usbdInitialize() was OK. Note also that there’s really no* reason to check the result of usbdShutdown().*/usbdShutdown ();

The second step of USBD initialization is to attach at least one HCD to the USBD,using the USBD’s usbdHcdAttach( ) routine. Normally, the attachment of HCDs tothe USBD happens during the VxWorks boot sequence. However, the USBD isdesigned to allow HCDs to be attached (and detached) at run-time. This flexibilityallows the USBD to support systems in which USB host controllers can be“hotswapped” without restarting the system.

Attaching and Detaching HCDs

You must decide when to attach HCDs to the USBD and when to detach them (ifever). Typically, USBD clients, such as USB class drivers, are not responsible forattaching HCDs to the USBD.

When an HCD is attached to the USBD, the caller passes the HCD’s execution entrypoint (of the form HCD_EXEC_FUNC) and an HCD-defined parameter (the HCDattachment parameter) to the usbdHcdAttach( ) routine. The USBD in turninvokes the HCD’s execution entry point with an HCD_FNC_ATTACH servicerequest, passing it the same HCD attachment parameter provided by the caller.Use of this HCD-defined parameter can vary; however, both HCDs provided byWind River use the parameter in the same way. For the UHCI and OHCI HCDsprovided by Wind River, the HCD attachment parameter is a pointer to a structureof type PCI_CFG_HEADER (defined in pciConstants.h). The structure has beeninitialized with the PCI configuration header for a UHCI or OCHI host controller.The HCD uses the information in this structure to locate and manage the specifiedhost controller.

Typically, the caller obtains the PCI configuration header for the desired hostcontroller by calling the usbPciClassFind( ) and usbPciConfigHeaderGet( )

12

Page 21: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

routines in usbPciLib (that is, in various stubUsbArchPciLib.c files). If more thanone UHCI or OHCI host controller is to be attached to the USBD, these routinesshould be used repeatedly to obtain the PCI_CFG_HEADER for each host controller,and usbdHcdAttach( ) should be invoked once for each host controller soidentified.

The following code fragment demonstrates how to attach a UHCI host controllerto the USBD:

UINT8 busNo;UINT8 deviceNo;UINT8 funcNo;PCI_CFG_HEADER pciCfgHdr; /* PCI_CFG_HEADER defined in

pciConstants.h */GENERIC_HANDLE uhciAttachToken; /* GENERIC_HANDLE defined in

usbHandleLib.h */

/* Locate the first (0th) UHCI controller. UHCI_CLASS, etc., are defined* in usbUhci.h. The functions usbPciClassFind() and* usbPciConfigHeaderGet() are exported by usbPciLib.*/if (!usbPciClassFind (UHCI_CLASS, UHCI_SUBCLASS, UHCI_PGMIF, 0,

&busNo, &deviceNo, &funcNo)){/* No UHCI controller was found. */return ERROR;}

usbPciConfigHeaderGet (busNo, deviceNo, funcNo, &pciCfgHdr);

/* Attach the UHCI HCD to the USBD. The function usbHcdUhciExec() is* exported by usbHcdUhciLib.*/if (usbdHcdAttach (usbHcdUhciExec, &pciCfgHdr, &uhciAttachToken) != OK)

{/* USBD failed to attach to UHCI HCD. */return ERROR;}

/* Attachment is complete. */

Detaching an HCD from the USBD is even simpler, as demonstrated in thefollowing code fragment:

/* Detach the UHCI HCD from the HCD. */

usbdHcdDetach (uhciAttachToken);

/* Detach is complete! */

13

Page 22: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Order of Initialization

The usbdInitialize( ) routine must be called before all other USBD functions,including usbdHcdAttach( ). However, it is not necessary that all USBD clients callusbdInitialize( ) before one or more HCDs have been attached to the USBD. Thefollowing two scenarios for initialization sequences are both acceptable:

Scenario #1: Traditional “boot time” initialization

(1) Boot code calls usbdInitialize( ).

(2) Boot code calls usbPciClassFind( ) to locate a USB host controller.

(3) Boot code calls usbPciConfigHeaderGet( ) to read the host controller’sconfiguration header.

(4) Boot code calls usbdHcdAttach( ) to attach the HCD for the identified hostcontroller.

(5) Boot code calls the USB class driver initialization entry point.

(6) The USB class driver calls usbdInitialize( ).

Scenario #2: “Hotswap”-driven initialization

(1) Boot code calls the USB class driver initialization entry point.

(2) The USB class driver calls usbdInitialize( ).

(3) Hotswap code identifies the presence or insertion of the USB host controller.

(4) Hotswap code calls usbdInitialize( ).

! CAUTION: While the USBD and Wind River HCDs are designed to support thedynamic attachment and detachment of HCDs, certain Wind River BSPs may notsupport the disconnection of the USB HCD from the underlying PCI interruptvector, which is essential to the detaching process. If the vector is subsequentlyre-enabled, the system may attempt to execute a stale interrupt service routine andwill fault.

14

Page 23: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

(5) Hotswap code calls usbPciConfigHeaderGet( ) to read the host controller’sconfiguration header.

(6) Hotswap code calls usbdHcdAttach( ) to attach the HCD for the identifiedhost controller.

Similarly, calls to usbdHcdDetach( ) can be made at any time to detach HCDs fromthe USBD. Outstanding requests to an HCD that is being detached are canceled,and detachment proceeds.

To understand why these different scenarios work correctly, it is necessary torecognize that hot-plugging of USB devices can occur at any time. So, both theUSBD and its clients must be written (using the “dynamic attachment” functionsdescribed in Dynamic Attachment Registration, p.18) to recognize the appearanceand disappearance of USB devices at run-time. It is for this reason that theappearance and disappearance of host controllers can also be handled flexibly.When a new host controller is attached to the system, the USBD automaticallyidentifies the devices connected to it and notifies interested clients. Likewise, whena host controller is removed from the system, the USBD automatically notifiesinterested clients that the devices attached to that host controller havedisappeared. The key point here is that USBD clients, such as USB class drivers,never assume that a particular device is present when the client is first initialized,and these drivers are always ready to accept devices connected to the system atother times.

Bus Tasks

For each host controller attached to the USBD, the USBD spawns a bus taskresponsible for monitoring bus events, such as the attachment and removal ofdevices. These tasks are normally “dormant”—that is, consuming no CPU time—and they typically wake up only when a USB hub reports a change on one of itsports.

Each USBD bus task has the VxWorks task name tUsbdBus.

It is also possible, though not mandated by the design of the USBD, for the HCDitself to create tasks that monitor host controller events. For example, both theUHCI and OHCI HCDs provided by Wind River create such tasks. In the case ofthe Wind River UHCI module, usbHcdUhciLib, the background task wakes upperiodically to poll the status of the UHCI root hub and to check for timed-out I/Orequest packets (IRPs). In the case of the Wind River OHCI module,

15

Page 24: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

usbHcdOhciLib, the background task wakes up periodically to check fortimed-out IRPs only (OHCI root hub changes are reported by an interrupt).

Registering Client Modules

Client modules that intend to make use of the USBD to communicate with USBdevices must, in addition to calling usbdInitialize( ), register with the USBD bycalling usbdClientRegister( ). When a client registers with the USBD, the USBDallocates per-client data structures that are later used to track all requests made bythat client. During client registration, the USBD also creates a callback task for eachregistered client (see Client Callback Tasks, p.16). After successfully registering anew client, the USBD returns a handle, USBD_CLIENT_HANDLE, that must beused by that client when making subsequent calls to the USBD.

When a client no longer intends to use the USBD, it must callusbdClientUnregister( ) in order to release its per-client data and callback task.Any outstanding USB requests made by the client are canceled at that time.

The following code fragment demonstrates the registration and unregistration ofa USBD client:

USBD_CLIENT_HANDLE usbdClientHandle;

/* Register a client named "USBD_TEST" with the USBD. */if (usbdClientRegister ("USBD_TEST", &usbdClientHandle) != OK)

{/* Attempt to register a new client failed. */return ERROR;}

/* Client is registered...application code follows. */....../* Unregister the client. */usbdClientUnregister (usbdClientHandle);

Client Callback Tasks

USB operations can be time-critical. For example, both USB interrupt andisochronous transfers depend on timely servicing in order to work correctly. In ahost system in which several different USBD clients are present, the possibilityalways exists for one client to interfere with the timely execution of other clientsneeding to service time-sensitive USB traffic. The Wind River USBD introducesper-client callback tasks to manage this problem.

16

Page 25: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

Many USB events can result in callbacks to a USBD client. For example, wheneverthe USBD completes the execution of a USB IRP, the client’s IRP callback routine isinvoked. Similarly, whenever the USBD recognizes a dynamic attachment event,one or more client’s dynamic attachment callback routines are invoked. Instead ofinvoking these callback routines immediately, the USBD schedules the callbacks tobe performed by the callback task for the appropriate USBD client(s). Normally,the callback task for each client is “dormant” (in a blocked state). When the USBDschedules a callback for a specified client, the corresponding client callback task“wakes up” (unblocks) and performs the actual callback. This approach allows theUSBD to process all outstanding USB events before the clients themselves obtaincontrol of the CPU.

The callback task for each client inherits the VxWorks task priority of the task thatoriginally called usbdClientRegister( ). This ensures that callbacks are processedat the task priority level intended by each client and allows you to write clients totake advantage of task priorities as a means of ensuring proper scheduling oftime-sensitive USB traffic.

Because each client has its own callback task, clients have greater flexibility in theamount of work they can do during the callback. For example, during callback, itis acceptable for executing code to block without hurting the performance of theUSBD or other USBD clients.

Client callback tasks have the VxWorks task name tUsbdCln.

USBD Internal Client

When first initialized, the USBD registers an internal “client” that is used to trackUSB requests generated by the USBD itself. Only one such internal client is created,regardless of the number of calls to usbdInitialize( ).

What types of USB requests can the USBD generate? All USBD communicationwith USB devices is made using the same calls available to USBD clients. Forexample, all control pipe requests to a device are made using a control pipe that theUSBD creates automatically when a device is first attached to the system. Just as aUSBD client would use usbdPipeCreate( ) to create a pipe to talk to a USB deviceendpoint, the USBD itself creates a control pipe to talk to endpoint 0 (the defaultcontrol endpoint) on each device. All internal USBD and external USBD client callsto routines like usbdDescriptorGet( ) or usbdFeatureSet( ) are routed through thispipe.

So, the USBD is actually using its own entry points recursively, and the internalclient is the USBD’s mechanism for tracking these requests.

17

Page 26: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Dynamic Attachment Registration

A typical USBD client wants to be notified whenever a device of a particular typeis attached to or removed from the system. By calling theusbdDynamicAttachRegister( ) routine, a client can specify a callback routine torequest such notification.

USB device types are identified by a class, subclass, and protocol. Standard USBclasses are defined in usb.h as USB_CLASS_xxxx. Subclass and protocol definitionsdepend on the class; therefore, these constants are generally defined in the headerfiles associated with a specific class.

Sometimes, a client is interested in a narrow range of devices. In this case, itspecifies values for the class, subclass, and protocol when registering throughusbdDynamicAttachRegister( ). For example, the USB keyboard class driver,usbKeyboardLib, registers for a Human Interface Device (HID) class ofUSB_CLASS_HID, a subclass of USB_SUBCLASS_HID_BOOT, and a protocol ofUSB_PROTOCOL_HID_BOOT_KEYBOARD (both the subclass and protocol aredefined in usbHid.h). In response, by means of the callback mechanism, the USBDnotifies the keyboard class driver whenever a device matching exactly thesecriteria is attached to or removed from the system.

In other cases, a client’s interest is broader. In this case, the constantUSBD_NOTIFY_ALL (defined in usbdLib.h) can be substituted for any or all of theclass, subclass, and protocol match criteria. For example, the USB printer classdriver, usbPrinterLib, registers for a class of USB_CLASS_PRINTER, subclass ofUSB_SUBCLASS_PRINTER (defined in usbPrinter.h), and a protocol ofUSBD_NOTIFY_ALL.

While a typical client makes only a single call to usbdDynamicAttachRegister( ),there is no limit to the number of concurrent notification requests a client can have.A single client can register concurrently for attachment notification of as manydevice types as desired.

The following code fragments demonstrate the correct use of the dynamicattachment registration functions:

/***************************************************************************** attachCallback - called by USBD when a device is attached/removed** The USBD invokes this callback when a USB device is attached to or* removed from the system. <nodeId> is the USBD_NODE_ID of the node being* attached or removed. <attachAction> is USBD_DYNA_ATTACH or* USBD_DYNA_REMOVE.*

18

Page 27: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

* RETURNS: N/A*/

LOCAL VOID attachCallback(USBD_NODE_ID nodeId,UINT16 attachAction,UINT16 configuration,UINT16 interface,UINT16 deviceClass,UINT16 deviceSubClass,UINT16 deviceProtocol){/* Depending on the attachment code, add or remove a device. */switch (attachAction)

{case USBD_DYNA_ATTACH:

/* A device is being attached. */printf (“New device attached to system.\n”);break;

case USBD_DYNA_REMOVE:/* A device is being detached. */printf ("Device removed from system.\n");break;

}}

Somewhere in the initialization of the application, the following code fragmentshould also appear:

/* Register for dynamic notification when a USB device is attached to or* removed from the system. For the sake of demonstration, we’ll request* notification for USB printers, though this same code could be used for* any other type of device.** usbdClientHandle is the USBD_CLIENT_HANDLE for the client.* USB_CLASS_PRINTER is defined in usb.h. USB_SUBCLASS_PRINTER is* defined in usbPrinter.h. USBD_NOTIFY_ALL is a wild-card that* matches anything. In this case we use it to match any USB programming* interface.*/if (usbdDynamicAttachRegister (usbdClientHandle, USB_CLASS_PRINTER,

USB_SUBCLASS_PRINTER, USBD_NOTIFY_ALL, attachCallback) != OK){/* Attempt to register for dynamic attachment notification failed. */return ERROR;}

/* attachCallback() - above - is now called whenever a USB keyboard* is attached or removed from the system.*/......

19

Page 28: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

/* Cancel the dynamic attachment registration. Each parameter must match* exactly those found in an earlier call to usbdDynamicAttachRegister(). */usbdDynamicAttachUnRegister (usbdClientHandle, USB_CLASS_PRINTER,

USB_SUBCLASS_PRINTER, USBD_NOTIFY_ALL, attachCallback);

Node IDs

USB devices are always identified using a USBD_NODE_ID. The USBD_NODE_IDis, in effect, a handle created by the USBD to track a device; it has no relationshipto the device’s actual USB address. This reflects the fact that clients are usually notinterested in knowing to which USB/host controller a device is physicallyattached. Because each device is referred to using the abstract concept of a node ID,the client can remain unconcerned with the details of physical device attachmentand USB address assignment, and the USBD can manage these details internally.

When a client is notified of the attachment or removal of a device, the USBD alwaysidentifies the device in question using the USBD_NODE_ID. Likewise, when theclient wishes to communicate through the USBD with a particular device, it mustpass the USBD_NODE_ID for that device to the USBD.

Bus Enumeration Routines

The usbdLib module exports the routines usbdBusCountGet( ),usbdRootNodeIdGet( ), usbdHubPortCountGet( ), usbdNodeIdGet( ), andusbdNodeInfoGet( ). As a group, these are referred to as bus enumerationroutines, and they allow USBD clients to enumerate the network of devicesattached to each host controller.

These routines are useful in the authoring of diagnostic tools and test programssuch as usbTool. However, when the caller uses these routines, it has no way ofknowing if the USB topology changes after enumeration or evenmid-enumeration. Therefore, authors of traditional clients, such as USB classdrivers, are advised not to use these routines.

Device Configuration

The USB specification defines a set of standard requests, a subset of which must besupported by all USB devices. Typically, a client uses these functions to interrogatea device’s “descriptors”—thus determining the device’s capabilities—and to set aparticular device configuration.

The USBD itself takes care of certain USB configuration issues automatically. Mostcritically, the USBD internally implements the code necessary to manage USB hubs

20

Page 29: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

and to set device addresses when new devices are added to the USB topology.Clients must not attempt to manage these functions themselves, for doing so islikely to cause the USBD to malfunction.

The USBD also monitors so-called configuration events. When a USBD clientinvokes a USBD function that causes a configuration event, the USBDautomatically resets the USB data toggles (DATA0 and DATA1) associated with thedevice’s pipes and endpoints. For example, a call to the USB commandusbdConfigurationSet( ) issues the set configuration command to the device, andin the process resets the data toggle to DATA0. Because the USBD handles USB datatoggles automatically, you do not typically need to concern yourself with resettingdata toggles. For an explanation of pipes and endpoints in the USB environment,see Data Flow, p.22. For more information about USB data toggles, see the USBSpecification.

Device configuration depends heavily on the type of device being configured. Thefollowing code fragment demonstrates how to read and parse a typical devicedescriptor:

UINT8 bfr [USB_MAX_DESCR_LEN]; /* USB_MAX_DESCR_LEN defined in usb.h */UINT16 actLen;pUSB_CONFIG_DESCR pCfgDescr; /* USB_CONFIG_DESCR defined in usb.h */pUSB_INTERFACE_DESCR pIfDescr; /* USB_INTERFACE_DESCR is also in usb.h */

/* Read the configuration descriptor. In the following fragment it is* assumed that nodeId was initialized, probably in response to an* earlier call to the client’s dynamic attachment notification callback* (see above).*/if (usbdDescriptorGet (usbdClientHandle, nodeId,

USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_CONFIGURATION, 0, 0,sizeof (bfr), bfr, &actLen) != OK){/* We failed to read the device’s configuration descriptor. */return FALSE;}

/* Use the function usbDescrParse() - exported by usbLib.h - to extract* the configuration descriptor and the first interface descriptor from* the buffer.*/if ((pCfgDescr = usbDescrParse (bfr, actLen, USB_DESCR_CONFIGURATION)) ==

NULL){/* No configuration descriptor was found in the buffer. */return FALSE;}

21

Page 30: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

if ((pIfDescr = usbDescrParse (bfr, actLen, USB_DESCR_INTERFACE)) ==NULL)

{/* No interface descriptor was found in the buffer. */return FALSE;}

Data Flow

Once a client has completely configured a device, it can begin to exchange datawith that device using the pipe and transfer functions provided by the USBD.Control, bulk, interrupt, and isochronous transfers are described using a singleUSB_IRP data structure (defined in usb.h). For more information about theUSB_IRP mechanism, see HCD_FNC_IRP_SUBMIT, p.33.

USB data transfers are addressed to specific endpoints within each device.1 Thechannel between a USBD client and a specific device endpoint is called a pipe. Eachpipe has a number of characteristics, including:

� the USBD_NODE_ID of the device� the endpoint number on the device� the direction of data transfer� bandwidth requirements� latency requirements

In order to exchange data with a device, a client must first create a pipe. In responseto a client request to create a new pipe, the USBD creates a USBD_PIPE_HANDLE,which the client must use for all subsequent operations on the pipe.

When a client attempts to create a pipe, the USBD checks that sufficient busbandwidth is available. Bandwidth limits are enforced for interrupt andisochronous pipes. The USBD does not allow more than 90% of the available busbandwidth to be allocated to interrupt and isochronous pipes. For control and bulkpipes, there is no bandwidth limit. At the same time, there is no guarantee thatmore than 10% of the bus is available for control transfers, and there is noguarantee that any bus bandwidth is available for bulk transfers.

1. Unlike IEEE-1394, the USB treats an isochronous transfer as an exchange between the USBhost and a specific USB device. In contrast, 1394 treats isochronous transfers as a broadcastto which any number of 1394 devices can listen simultaneously.

22

Page 31: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

The following code fragment demonstrates the creation of a pipe for sending datato the bulk output endpoint on a printer:

USBD_PIPE_HANDLE outPipeHandle;

/* Create a pipe for output to the printer. It is assumed that endpoint,* configValue, interface, and maxPacketSize were determined by reading* the appropriate descriptors from the device.*/if (usbdPipeCreate (usbdClientHandle, nodeId, endpoint, configValue,

interface, USB_XFRTYPE_BULK, USB_DIR_OUT, maxPacketSize, 0, 0,&outPipeHandle) != OK){/* We failed to create the pipe. */return ERROR;}

The following fragment demonstrates sending data to the pipe that has just beencreated:

/***************************************************************************** ourIrpCallback - Invoked upon IRP completion/cancellation** RETURNS: N/A*/

LOCAL VOID ourIrpCallback(pVOID p /* pointer to the completed IRP */)

{pUSB_IRP pIrp = (pUSB_IRP) p;

/* Set status based on whether the IRP completed successfully or not. */if (pIrp->result == OK)

{/* IRP was successful. */}

else/* IRP failed. */}

}

23

Page 32: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Then, elsewhere in the code, the following should appear:

UINT8 bfr [4096]; /* a buffer of arbitrary size. */UINT16 bfrCount; /* amount of data in the buffer. */USB_IRP irp;/* The code here would presumably put data into the buffer and initialize* bfrCount with the amount of data in the buffer.*/

...

.../* Send bfr to the printer. *//* Initialize IRP. */memset (irp, 0, sizeof (irp));irp.userPtr = ourUserPtr; /* some value of use to our callback */irp.irpLen = sizeof (*pIrp); /* the length of the IRP */irp.userCallback = ourIrpCallback; /* our IRP completion callback */irp.timeout = 30000; /* 30 second timeout */irp.transferLen = bfrCount;irp.bfrCount = 1;irp.bfrList [0].pid = USB_PID_OUT;irp.bfrList [0].pBfr = bfr;irp.bfrList [0].bfrLen = count;/* Submit IRP */if (usbdTransfer (usbdClientHandle, outPipeHandle, &irp) != OK)

{/* An error here means that our IRP was malformed. */return ERROR;}

/* The IRP will complete asynchronously. ourIrpCallback() will be invoked* by the USBD when the IRP is complete. */

1.3.2 USBD Internals

Hub Management

The management of USB hubs is integral to the proper functioning of the WindRiver USBD; therefore, USBD clients should not attempt to modify theconfiguration of a USB hub attached to the system. Doing so will likely cause theUSBD to malfunction.

When the USBD detects a hub, it checks to see whether the hub’s powerrequirements can be met—in other words, can the upstream hub to which the hubis connected provide enough power. If so, the USBD automatically configures thehub and creates a pipe to monitor the hub’s status endpoint. If there is insufficient

24

Page 33: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

power for the hub or insufficient bus bandwidth to create the pipe, the USBDrefuses to recognize the hub.

New Device Connections

When a device is connected to one of a hub’s ports, the USBD checks to see whetherthe attachment of the device exceeds the maximum topology depth allowed by theUSB (six levels). Then the USBD tries to read the device’s class information, first byreading the device’s device descriptor or, alternatively, by reading its configurationand interface descriptors, if the device descriptor does not declare the classinformation. If either of these steps fails, the USBD refuses to recognize the device.

If the device is recognized successfully, the USBD automatically notifies any clientsregistered for dynamic attachment notification that the new device has beenattached to the system.

If a device is not recognized for any reason, the USBD disables the port to whichthe device is connected. In this case, the USBD itself is unable to determine the typeof device, and no dynamic attachment notification callbacks are invoked. If aUSBD client calls usbdNodeIdGet( ) to query the hub port of an unrecognizeddevice, the USBD indicates that no device is attached to the port.

1.4 The USB Host Controller Driver (HCD)

This section describes the interface and requirements for HCDs. This informationis essential if you are creating an HCD for a host controller that Wind River doesnot already support.

1.4.1 HCD Header File

All HCDs implement the interface as defined in usbHcd.h.

25

Page 34: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.4.2 HCD Entry Point

Each HCD exports a single entry point, its execution entry point. This function takesthe following form:

typedef STATUS (*HCD_EXEC_FUNC) (pVOID pHrb);

1.4.3 Host Request Blocks (HRB)

All requests to the HCD are made by constructing Host Request Blocks (HRBs) andpassing them to the HCD’s execution entry point for processing. HRBs begin witha common header, followed by parameters unique to the function being executed.The format of the header is as follows:

typedef struct hrb_header{HCD_CLIENT_HANDLE handle; /* I/O: caller's HCD client handle */UINT16 function; /* IN: HCD function code */UINT16 hrbLength; /* IN: Length of the total HRB */} HRB_HEADER, *pHRB_HEADER;

When an HCD is attached, a handle to the host controller is created. That handle,stored in the handle field, is used by all host controller driver functions; however,each time an HCD is attached, a new handle is created.

The function field in HRB_HEADER defines one of the following functions as theHCD function to be executed:

An HCD must implement all of these functions in order to perform properly.

The hrbLength field is set by the caller to be the total length of the HRB, includingthe header and any additional parameters that follow.

Each HCD function, including any associated HRB, is described in the followingsections.

HCD_FNC_ATTACH HCD_FNC_DETACHHCD_FNC_BUS_RESET HCD_FNC_SET_BUS_STATEHCD_FNC_SOF_INTERVAL_GET HCD_FNC_SOF_INTERVAL_SETHCD_FNC_PIPE_CREATE HCD_FNC_PIPE_DESTROYHCD_FNC_PIPE_MODIFY HCD_FNC_CURRENT_FRAME_GETHCD_FNC_IRP_SUBMIT HCD_FNC_IRP_CANCEL

26

Page 35: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

HCD_FNC_ATTACH

This function is contained in the following HRB:

typedef struct hrb_attach{HRB_HEADER header; /* HRB header */pVOID param; /* IN: HCD-specific parameter */USB_HCD_MNGMT_CALLBACK mngmtCallback;

/* IN: USBD's callback for mngmt events */pVOID mngmtCallbackParam; /* IN: USBD-defined parameter to callback */UINT16 busCount; /* OUT: number of buses managed by HCD */} HRB_ATTACH, *pHRB_ATTACH;

In response to an HCD_FNC_ATTACH request, an HCD initializes one or more USBhost controllers, thereby enabling the USB(s) attached to those host controller(s).

The USBD invokes the HCD’s HCD_FNC_ATTACH function whenusbdHcdAttach( ) is called. Unlike other HCD functions, the USBD does not storean existing HCD_CLIENT_HANDLE in the HRB_HEADER.handle field. Instead,upon successful completion of this routine, the HCD is expected to store a newlycreated HCD_CLIENT_HANDLE in the HRB_HEADER.handle field so that the USBDcan retrieve it. The USBD uses the newly created HCD_CLIENT_HANDLE toidentify the indicated USB host controller in subsequent calls to the HCD.Typically, the HCD casts the newly created HCD_CLIENT_HANDLE as a pointer toan internal HCD data structure used to manage a specific host controller.

The HCD-defined parameter passed to the usbdHcdAttach( ) routine is in turnpassed in the param field. The USBD makes no attempt to interpret the meaning ofthis parameter. The HCD can use the param field as needed; for example, the UHCIand OHCI HCDs provided by Wind River cast this parameter to a pointer to aPCI_CFG_HEADER structure (defined in pciConstants.h). The UHCI and OHCIHCDs assume that this structure has already been initialized with the PCIconfiguration header of a USB host controller.

The mngmtCallback parameter is a pointer to a function within the USBD that theHCD should call when it detects certain USB management events. This functiontakes the following form:

typedef VOID (*USB_HCD_MNGMT_CALLBACK)(pVOID mngmtCallbackParam, /* caller-defined parameter */HCD_CLIENT_HANDLE handle, /* handle to host controller */UINT16 busNo, /* bus number */UINT16 mngmtCode /* management code */);

27

Page 36: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Management events are described in 1.4.4 Management Events, p.39. ThemngmtCallbackParam is a USBD-defined parameter that the HCD must pass to theUSBD whenever the HCD calls the mngmtCallback function.

Finally, the HCD must return the number of host controllers initialized in thebusCount field. The UHCI and OCHI HCDs provided by Wind River always return1 in this field. However, other HCDs can initialize multiple host controllers inresponse to a single HCD_FNC_ATTACH request. When a value greater than one isreturned in busCount, the USBD identifies individual host controllers using acombination of the HCD_CLIENT_HANDLE and a host controller index in therange 0..busCount - 1. When busCount is returned as 1, the USBD always passes ahost controller index of 0 to the HCD.

HCD_FNC_DETACH

This function is contained in the following HRB:

typedef struct hrb_detach{HRB_HEADER header; /* HRB header */} HRB_DETACH, *pHRB_DETACH;

The USBD invokes the HCD_FNC_DETACH function when the HCD must shutdown the host controller(s) specified by HCD_CLIENT_HANDLE. Two conditionsprompt the USBD to do this:

� A call to the usbdHcdDetach( ) routine.

� Automatically, when the USBD’s usage count goes to zero as a result of a callto usbdShutdown( ).

In response to this function, the HCD disables the specified host controller(s) andreleases any memory and other resources allocated on behalf of the specified hostcontroller(s).

HCD_FNC_BUS_RESET

This function is contained in the following HRB:

typedef struct hrb_bus_reset{HRB_HEADER header; /* HRB header */

28

Page 37: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

UINT16 busNo; /* IN: bus number to reset */} HRB_BUS_RESET, *pHRB_BUS_RESET;

The USBD invokes the HCD_FNC_BUS_RESET function to reset a USB. TheHCD_CLIENT_HANDLE passed in HRB.HRB_HEADER.handle specifies the USB tobe reset, and the host controller index passed in busNo specifies the host controllerto be reset.

When driving the signaling of a USB reset, the HCD must ensure that USB resettiming requirements are met. That is, the reset width must be at leastUSB_TIME_RESET and the HCD should wait USB_TIME_RESET_RECOVERY afterresetting the bus. Both of these time management constants are defined in usb.h.

HCD_FNC_SET_BUS_STATE

This function is contained in the following HRB:

typedef struct hrb_set_bus_state{HRB_HEADER header; /* HRB header */UINT16 busNo; /* IN: bus number */UINT16 busState; /* IN: new bus state, HCD_BUS_xxxx */} HRB_SET_BUS_STATE, *pHRB_SET_BUS_STATE;

The USBD controls global SUSPEND and global RESUME states with theHCD_FNC_SET_BUS_STATE function. To place a host controller in the globalSUSPEND state, the USBD invokes this function with the field busState set toHCD_BUS_SUSPEND. To bring the host controller out of the SUSPEND state, theUSBD invokes this function with busState set to HCD_BUS_RESUME. The HCDresponds by placing the specified host controller, busNo, in the specified state.

HCD_FNC_SOF_INTERVAL_GET and HCD_FNC_SOF_INTERVAL_SET

These functions share the following HRB:

typedef struct hrb_sof_interval_get_set{HRB_HEADER header; /* HRB header */UINT16 busNo; /* IN: bus index */UINT16 sofInterval; /* I/O: SOF interval */} HRB_SOF_INTERVAL_GET_SET, *pHRB_SOF_INTERVAL_GET_SET;

29

Page 38: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Most USB host controllers can adjust start-of-frame (SOF) timing within a narrowrange (± 1 bit-time). This adjustment allows time-sensitive applications to tune thereal-time behavior of the USB to meet strict isochronous timing requirements. Theentire frame is called an interval.

The HCD responds to these functions by setting or requesting the current SOFinterval for a specified host controller, busNo. It returns the current SOF interval inthe sofInterval field. The value returned is expressed as the current number ofbit-times in each frame. The default value should always be 12,000.

HCD_FNC_PIPE_CREATE

This function is contained in the following HRB:

typedef struct hrb_pipe_create{HRB_HEADER header; /* HRB header */UINT16 busNo; /* IN: bus index: 0, 1, ... */UINT16 busAddress; /* IN: bus address of USB device */UINT16 endpoint; /* IN: endpoint on device */UINT16 transferType; /* IN: transfer type */UINT16 direction; /* IN: transfer/pipe direction */UINT16 speed; /* IN: transfer speed */UINT16 maxPacketSize; /* IN: packet size */UINT16 bytesPerFrame; /* IN: number of bytes per frame */UINT16 interval; /* IN: service interval */UINT32 time; /* OUT: calc’d transfer time in nanosecs */HCD_PIPE_HANDLE pipeHandle; /* OUT: pipe handle */} HRB_PIPE_CREATE, *pHRB_PIPE_CREATE;

The USBD invokes the HCD_FNC_PIPE_CREATE function when creating a pipe.The structure’s elements specify a new pipe’s attributes as follows:

busAddressSpecifies the USB bus address of the device.

endpointSpecifies the endpoint on the device.

transferTypeSpecifies the type of pipe as one of the following:

USB_XFRTYPE_CONTROLUSB_XFRTYPE_BULKUSB_XFRTYPE_INTERRUPTUSB_XFRTYPE_ISOCH

30

Page 39: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

direction (control pipes only)Specifies the direction of the control pipe as one of the following:

speedSpecifies the speed of the device as USB_SPEED_FULL (12 Mbps) orUSB_SPEED_LOW (1.5 Mbps).

maxPacketSizeSpecifies the maximum packet size supported by the endpoint.

bytesPerFrameFor periodic transfers (interrupt and isochronous), specifies the number ofbytes to be transferred on the pipe in each 1 millisecond frame.

intervalSpecifies the service interval for interrupt pipes.

timeBased on the values of transferType, direction, speed, maxPacketSize, andbytesPerFrame, the HCD calculates the worst-case recurring bandwidthrequired for the pipe and returns it in the time field. This value is always 0(zero) for control and bulk pipes because they do not involve recurringtransfers and are not guaranteed bandwidth. The calculation for interrupt andisochronous pipes is greatly simplified by the usbRecurringTime( ) routine inusbLib. It uses the parameters of HCD_FNC_PIPE_CREATE and twohardware-specific parameters provided by the HCD to generate the valuereturned in time. For more information about these HCD parameters, see thereference entry for usbTransferTime( ).

The HCD keeps track of the total amount of bandwidth allocated for each hostcontroller it manages. If the amount of bandwidth requested exceeds themaximum amount of bus bandwidth available for interrupt and isochronoustransfers (90% of total bus bandwidth), the HCD returns the errorS_usbHcdLib_BANDWIDTH_FAULT.

Finally, the HCD must return a non-NULL HCD_PIPE_HANDLE in pipeHandle. TheUSBD records this value and passes it to the HCD_FNC_IRP_SUBMIT functionwhen subsequently submitting IRPs for execution on the pipe.

USB_DIR_INUSB_DIR_OUTUSB_DIR_INOUT

31

Page 40: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

HCD_FNC_PIPE_DESTROY

This function is contained in the following HRB:

typedef struct hrb_pipe_destroy{HRB_HEADER header; /* HRB header */HCD_PIPE_HANDLE pipeHandle; /* IN: pipe to be destroyed */} HRB_PIPE_DESTROY, *pHRB_PIPE_DESTROY;

The USBD invokes the HCD_FNC_PIPE_DESTROY function to notify the HCD thata specified pipe is being torn down and that the bandwidth associated with thatpipe should be released. The HCD responds by releasing the amount of bandwidthoriginally allocated to the pipe and releasing any data structures and otherresources allocated on behalf of the pipe.

Before invoking this function, the USBD cancels any outstanding IRPs on the pipe.

HCD_FNC_PIPE_MODIFY

This function is contained in the following HRB:

typedef struct hrb_pipe_modify{HRB_HEADER header; /* HRB header */HCD_PIPE_HANDLE pipeHandle; /* IN: pipe to modify */UINT16 busAddress; /* IN: new bus address, or 0 if unchanged */UINT16 maxPacketSize; /* IN: new max pkt size, or 0 if unchanged */} HRB_PIPE_MODIFY, *pHRB_PIPE_MODIFY;

The HCD_FNC_PIPE_MODIFY function allows the USBD to modify pipe attributesafter creating the default control pipe.

When the USBD creates the default control pipe for a device, it must read thedevice’s device descriptor before it can know the maximum packet size that thepacket permits. Also, the USBD generally assigns a new USB address to a deviceafter establishing communication with the device’s default control pipe.

By convention, when creating the default control pipe, the USBD specifies a deviceaddress of 0 and a maximum packet size of 8 (the minimum required by the USBSpecification). Typically, after the host obtains the device descriptor, it issues thecommand to set a new, non-zero address for the device specified by pipeHandle.Then, after the device address has been changed, the USBD invokesHCD_FNC_PIPE_MODIFY to change the busAddress and maxPacketSize attributes.

32

Page 41: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

HCD_FNC_CURRENT_FRAME_GET

This function is contained in the following HRB:

typedef struct hrb_current_frame_get{HRB_HEADER header; /* HRB header */UINT16 busNo; /* IN: bus index: 0, 1, ... */UINT16 frameNo; /* OUT: current frame number */UINT16 frameWindow; /* OUT: frame window size */} HRB_CURRENT_FRAME_GET, *pHRB_CURRENT_FRAME_GET;

USBD clients use this function to retrieve the current USB frame number for aspecified host controller, busNo. In response to this function, the HCD stores thecurrent USB frame number in the frameNo field and the maximum number ofunique frame numbers tracked by the host controller in the frameWindow field.

For example, most USB host controllers are capable of counting frame numbersfrom 0 to 1023 or from 0 to 2047. In such cases, frameWindow should be returned as1024 or 2048, respectively.

HCD_FNC_IRP_SUBMIT

This function is contained in the following HRB:

typedef struct hrb_irp_submit{HRB_HEADER header; /* HRB header */HCD_PIPE_HANDLE pipeHandle; /* IN: pipe to which IRP is directed */pUSB_IRP pIrp; /* IN: pointer to IRP */} HRB_IRP_SUBMIT, *pHRB_IRP_SUBMIT;

The USBD uses the HCD_FNC_IRP_SUBMIT function to pass a USB_IRP datastructure to the HCD for execution on a specified pipe. IRPs are a mechanism forscheduling data transfers across the USB. See below for additional informationabout the USB_IRP structure.

Use the pipeHandle parameter to specify the HCD_PIPE_HANDLE for a pipepreviously created through the HCD_FNC_PIPE_CREATE function.

In response, the HCD queues the IRP and returns immediately. The HCD notifiesthe USBD when the IRP is complete by invoking the USBD’s IRP callback function(identified in the usbdCallback field of the IRP). After accepting an IRP forexecution, an HCD must guarantee that it will invoke the USBD’s IRP callback

33

Page 42: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

function when the IRP completes for any reason, including being canceled (seeHCD_FNC_IRP_CANCEL, p.39).

The HCD can omit the call to the USBD’s IRP callback function if it detects amalformed HRB or IRP when the IRP is initially passed to theHCD_FNC_IRP_SUBMIT function. If this is the case, the HCD returns an error,indicating to the USBD that the HCD refused to accept the IRP.

USB_IRP Data Structure.

The structure of a USB_IRP takes the following form:

typedef struct usb_irp{LINK usbdLink; /* link field used internally by USBD */pVOID usbdPtr; /* pointer field for use by USBD */LINK hcdLink; /* link field used internally by USB HCD */pVOID hcdPtr; /* pointer field for use by USB HCD */pVOID userPtr; /* pointer field for use by client */UINT16 irpLen; /* total length of IRP structure */int result; /* IRP completion result: S_usbHcdLib_xxxx */IRP_CALLBACK usbdCallback; /* USBD completion callback routine */IRP_CALLBACK userCallback; /* client's completion callback routine */UINT16 dataToggle; /* IRP should start with DATA0/DATA1. */UINT16 flags; /* defines other IRP processing options */UINT32 timeout; /* IRP timeout in milliseconds */UINT16 startFrame; /* start frame for isochronous transfer */UINT16 dataBlockSize; /* granularity of data for isoch. transfer */UINT32 transferLen; /* total length of data to be transferred */UINT16 bfrCount; /* indicates count of buffers in BfrList */USB_BFR_LIST bfrList [1];} USB_IRP, *pUSB_IRP;

The following fields comprise the IRP data structure:

usbdLinkThis field is used internally by the USBD.

usbdPtrThis field is used internally by the USBD.

hcdLinkThis field is reserved for use only by the HCD, not other modules. Typically,the HCD uses the hcdLink field to bind the USB_IRP to a linked list of USB_IRPsbeing managed by the HCD.

34

Page 43: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

hcdPtrThis field is reserved for use only by the HCD, not other modules. Typically,the HCD uses the hcdPtr field to store a pointer to HCD data related to theUSB_IRP.

userPtrThis field is reserved for use by the USBD client that initially created theUSB_IRP and submitted it for execution.

irpLenThis field is initialized by the USBD client with the total length, in bytes, of theUSB_IRP structure. The last field of the USB_IRP is an array of USB_BFR_LISTentries, so the total length of the IRP is not known in advance; however, thetotal length of the IRP equals the size of the USB_IRP structure plus the size ofall the buffers associated with the IRP, as follows:

irpLen = sizeof (USB_IRP) + (sizeof (USB_BFR_LIST) x (bfrCount -1))

resultThis field is used to pass the completion status of the IRP. For moreinformation about the use of the result field, see 1.4.5 HCD Error ReportingConventions, p.40.

usbdCallbackThis field is a non-NULL pointer to a callback routine within the USBD. TheHCD must call this routine upon IRP completion.

userCallbackThis field, if non-NULL, is the address of a USBD client callback routine. TheUSBD invokes this routine upon IRP completion.

dataToggleThis field is initialized by the USBD as USB_DATA0 or USB_DATA1 andindicates the starting USB data toggle that the HCD uses when transferringdata for the USB_IRP. The USBD automatically calculates the next data togglevalue for each IRP; therefore, the USBD client and the HCD do not need tomaintain this information across IRPs. The HCD can modify the value ofdataToggle while executing the USB_IRP. Neither the USBD nor the USBD clientexamines the dataToggle field upon IRP completion.

flagsThis field contains a bit mask of flags that control IRP execution.USB_FLAG_SHORT_OK (the default if no flag is specified) indicates that a dataunderrun on input buffers is acceptable. USB_FLAG_SHORT_FAIL indicatesthat a data underrun should be treated as a fatal error. USB_FLAG_ISO_ASAP

35

Page 44: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

is used only with USB_IRPs that describe isochronous transfers. IfUSB_FLAG_ISO_ASAP is specified, the HCD ignores the startFrame field in theUSB_IRP and instead schedules the isochronous transfer for the next availableframe. If USB_FLAG_ISO_ASAP is not specified, startFrame must specify thestarting frame number for an isochronous data transfer.

timeoutThis field specifies the USB_IRP timeout in milliseconds. A value ofUSB_TIMEOUT_NONE indicates that the USB_IRP should never time out.Typically, interrupt and isochronous USB_IRPs specify a timeout value ofUSB_TIMEOUT_NONE (no timeout); control and bulk USB_IRPs specify atimeout of USB_TIMEOUT_DEFAULT where USB_TIMEOUT_DEFAULT equals5,000 (that is, five seconds). A timeout value of zero (0) is interpreted as arequest for the default timeout.

startFrameThis field specifies the starting frame number for an isochronous data transfer.(See also the discussion of the flags field above.)

dataBlockSizeThis field can be specified for isochronous transfers. If non-0, dataBlockSizedefines the granularity of isochronous data being sent. When the underlyingHCD breaks up the isochronous transfer into individual frames, it ensures thatthe amount of data transferred in each frame is a multiple of the value ofdataBlockSize.

transferLenThis field provides the total length of the data to be transferred by the USB_IRP.It is equal to the sum of the bfrLen fields in each USB_BFR_LIST entry (seebelow).

bfrCountThis field specifies the number of USB_BFR_LIST entries that follow. EachUSB_BFR_LIST can be thought of as a scatter-gather list entry, each specifyinga different region of memory to be transferred and the type of transfer (SETUP,IN, or OUT). For more information on the USB_BFR_LIST structure, see below.

USB_BFR_LIST Structure and Conventions.

The structure of USB_BFR_LIST is as follows:

typedef struct usb_bfr_list{UINT16 pid; /* specifies packet type as USB_PID_xxxx */pUINT8 pBfr; /* pointer to buffer */UINT32 bfrLen; /* length of buffer */

36

Page 45: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

UINT32 actLen; /* actual length transferred */} USB_BFR_LIST, *pUSB_BFR_LIST;

The following fields comprise the USB buffer list structure:

pidThis field specifies the type of transfers as USB_PID_SETUP, USB_PID_IN, orUSB_PID_OUT.

pBfrThis field specifies the location of the buffer. If pBfr is NULL and bfrLen is 0, theHCD transfers a 0-byte packet.

bfrLenThis field specifies the length of the buffer. If pBfr is NULL and bfrLen is 0, theHCD transfers a 0-byte packet.

actLenUpon completion of each USB_BFR_LIST entry, the HCD must store the actuallength of data transferred in this field.

By convention, there are several additional limitations on the structure ofUSB_IRPs passed to the HCD:

� USB_IRPs that describe control transfers must always have two or three bfrListentries (bfrCount equals 2 or 3), depending on whether the setup transferinvolves a data phase.

The first bfrList entry must have a pid value of USB_PID_SETUP and mustdescribe the SETUP transaction. If the SETUP transfer involves a data phase,the second bfrList entry must have a pid value of USB_PID_IN or USB_PID_OUTand must describe the data phase. If there is a data phase, the third bfrList entrymust have a pid value opposite to that of the data phase and must describe a0-byte packet (pBfr equals NULL and bfrLen equals 0). If there is no data phase,the second bfrList entry must have a pid value of USB_PID_IN and mustdescribe a 0-byte packet. Following these rules, a single USB_IRP alwaysdescribes a complete SETUP transfer.

� USB_IRPs describing interrupt transfers generally have only a single bfrListentry with a pid value of USB_PID_IN or USB_PID_OUT; however, this isessentially a practical consideration because most interrupt transfers aresmaller than the maximum size of the packet for a specified interrupt pipe.This is not a mandatory requirement.

� USB_IRPs describing bulk transfers can have an unlimited number of bfrListentries. Because USB bulk and interrupt pipes are uni-directional (one-way),

37

Page 46: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

the pid value of all bfrList entries must be the same and must correspond to thedirection of the pipe.

� USB_IRPs that describe isochronous transfers must have only oneUSB_BFR_LIST entry. In general, the buffer that the USB_BFR_LIST entrydescribes should be large enough to span n frames, where n is comfortablylarger than the interrupt latency of the target system (measured inmilliseconds). The HCDs provided by Wind River automatically split thebuffer into frames of the appropriate size to maintain the average transfer ratespecified for the corresponding pipe.

USB_IRP Queuing Conventions

The USBD never submits more than one SETUP transfer for a particular device atone time. (The USBD internally serializes any attempts to schedule simultaneouscontrol transfers to a single device.)

By convention, when using the Wind River-provided UHCI and OHCI HCDs,USBD clients should never attempt to queue more than one bulk or interrupttransfer for a particular pipe at the same time. The Wind River HCDs make noattempt to serialize multiple USB_IRPs. Therefore, queuing multiple bulk transfersat the same time likely causes data to be exchanged with the device in anunpredictable order. (The USBD does not enforce this convention, so it is possiblefor third parties to create HCDs and USBD clients that do not adhere to this rule.)

Similarly, Wind River HCDs do not serialize concurrent interrupt USB_IRPsdirected at the same pipe; therefore, USBD clients should avoid queuing more thana single interrupt USB_IRP for a particular interrupt pipe at one time. (Again, theUSBD does not enforce this convention, so third-party HCD/client combinationsmay be coded to behave differently.)

On the contrary, USBD clients should maintain a queue of at least two USB_IRPsfor each active isochronous pipe, if the isochronous data flow is to continueuninterrupted. Because isochronous USB_IRPs generally define the startFrame fieldfor each isochronous transfer, the HCD has enough information to schedule eachUSB_IRP for execution at the correct time. Therefore, “double-buffering” USB_IRPsfor isochronous transfers allows the HCD to eliminate dead-time, ensuring acontinuous flow of time-sensitive data. The Wind River UHCI and OHCI HCDsare implemented to ensure continuous isochronous data transfer, provided theUSBD client uses at least two USB_IRPs to maintain double-buffering.

38

Page 47: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

HCD_FNC_IRP_CANCEL

This function is contained in the following HRB:

typedef struct hrb_irp_cancel{HRB_HEADER header; /* HRB header */pUSB_IRP pIrp; /* IN: pointer to IPR to be canceled */} HRB_IRP_CANCEL, *pHRB_IRP_CANCEL;

The USBD uses the HCD_FNC_IRP_CANCEL function to cancel an outstanding IRPpreviously passed to the HCD through the HCD_FNC_IRP_SUBMIT function. If thespecified IRP is still outstanding (that is, it has not yet completed, eithersuccessfully or with an error), the HCD must cancel the IRP and set theUSB_IRP.result field to S_usbHcdLib_IRP_CANCELED. If the IRP has alreadycompleted, the HCD returns the error S_usbHcdLib_CANNOT_CANCEL inresponse to the HCD_FNC_IRP_CANCEL request.

1.4.4 Management Events

The management callback provided by the USBD to the HCD as part of theHCD_FNC_ATTACH request gives the HCD a way to notify the USBD when itdetects asynchronous management events. The format of the callback is as follows:

typedef VOID (*USB_HCD_MNGMT_CALLBACK)(pVOID mngmtCallbackParam, /* caller-defined parameter */HCD_CLIENT_HANDLE handle, /* handle to host controller */UINT16 busNo, /* bus number */UINT16 mngmtCode /* management code */);

The mngmtCallbackParam parameter passed to the callback is theHRB.mngmtCallbackParam value originally passed to the HCD during theHCD_FNC_ATTACH request. The handle parameter is the HCD-assignedHCD_CLIENT_HANDLE for the corresponding host controller(s), and the busNoparameter is the index of the specific host controller reporting the managementevent.

At the present time, the USBD/HCD interface defines only one type ofmanagement event, HCD_MNGMT_RESUME.

The management code is passed to the USBD’s callback in the mngmtCodeparameter.

39

Page 48: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

HCD_MNGMT_RESUME

Most available host controllers in the SUSPEND state can detect a request by a USBdevice to resume. This feature, called remote wakeup, can be used to bring asuspended bus back to normal operation.

If the HCD detects that a USB device is driving RESUME signaling on the USBwhile the host controller is in the SUSPEND state, the HCD should invoke theUSBD’s management callback, passing the value HCD_MNGMT_RESUME in themngmtCode parameter.

1.4.5 HCD Error Reporting Conventions

A number of standard HCD error codes are defined in usbHcd.h. You areencouraged to use the existing HCD error codes when creating new HCDs. Theseerror codes are returned both in response to HCD function requests through theHCDs execution entry point, as well as in the result field of each USB_IRP processedby the HCD. (For more information about the USB_IRP result field, seeHCD_FNC_IRP_SUBMIT, p.33.) To conform to Wind River conventions, the HCDshould also set the system errno whenever returning an error.

HCDs return the standard VxWorks constant OK when a function or IRPcompletes successfully. HCD error codes are defined as follows:

In particular, HCDs must store the error code S_usbHcdLib_IRP_CANCELED in theresult field of USB_IRPs that have been canceled for any reason. Higher layers relyon this error code to recognize situations in which IRPs should not be retried.

For their own convenience, HCDs can temporarily store other values in theUSB_IRP result field while processing IRPs. For example, the UHCI and OHCI

S_usbHcdLib_BAD_CLIENT S_usbHcdLib_BAD_PARAMS_usbHcdLib_BAD_HANDLE S_usbHcdLib_OUT_OF_MEMORYS_usbHcdLib_OUT_OF_RESOURCES S_usbHcdLib_NOT_IMPLEMENTEDS_usbHcdLib_GENERAL_FAULT S_usbHcdLib_NOT_INITIALIZEDS_usbHcdLib_INT_HOOK_FAILED S_usbHcdLib_STRUCT_SIZE_FAULTS_usbHcdLib_HW_NOT_READY S_usbHcdLib_NOT_SUPPORTEDS_usbHcdLib_SHUTDOWN S_usbHcdLib_IRP_CANCELEDS_usbHcdLib_STALLED S_usbHcdLib_DATA_BFR_FAULTS_usbHcdLib_BABBLE S_usbHcdLib_CRC_TIMEOUTS_usbHcdLib_TIMEOUT S_usbHcdLib_BITSTUFF_FAULTS_usbHcdLib_SHORT_PACKET S_usbHcdLib_CANNOT_CANCELS_usbHcdLib_BANDWIDTH_FAULT S_usbHcdLib_SOF_INTERVAL_FAULTS_usbHcdLib_DATA_TOGGLE_FAULT S_usbHcdLib_PID_FAULTS_usbHcdLib_ISOCH_FAULT

40

Page 49: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

HCDs provided by Wind River use this field temporarily while executing the IRP,to store a value indicating that the IRP is “pending.” However, before invoking anIRP’s completion callback routine, the HCD is required to store either the constantOK or one of the above error codes in the USB_IRP result field.

1.4.6 Root Emulation

HCDs are required to emulate the behavior of the root hub. That is, HCDs mustintercept transfer requests intended for the root hub and must synthesize standardUSB responses to these requests.

For example, when a host controller is first initialized by the HCD_FNC_ATTACHrequest, the root hub must respond at the default USB address 0, and itsdownstream ports must be disabled. The USBD interrogates the root hub, just as itwould other hubs, by issuing USB GET_DESCRIPTOR requests. The USBD thenconfigures the root hub for operation by issuing a series of SET_ADDRESS,SET_CONFIGURATION, SET_FEATURE, and CLEAR_FEATURE requests. The HCDis responsible for recognizing which of these requests are intended for the root huband must respond to them appropriately.

After configuration, the USBD begins polling the root hub’s interrupt status pipe tomonitor changes on the root hub’s downstream ports. The HCD must interceptIRPs directed to the root hub’s interrupt endpoint and synthesize appropriatereplies. Typically, the HCD queues USB_IRPs directed to the root hub separatelyfrom those that actually result in bus operations. For example, the UHCI and OHCIHCDs provided by Wind River queue the USB_IRPs sent to the root hub andspawn a background task to synthesize responses to these IRPs. The backgroundtask typically polls the host controller hardware several times per second todetermine whether there has been a change in state on one of the root hub’sdownstream ports.

The source files for the HCDs provided by Wind River include complete examplesof the root hub emulation required of each. See the following source files:

� for UHCI HCD: usbHcdUhciLib.c

� for OHCI HCD: usbHcdOhciLib.c

1.4.7 IRP Timeouts

Each HCD is responsible for determining whether a particular IRP has timed out,and when. The allowable execution time for each IRP is stored in the

41

Page 50: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

USB_IRP.timeout field. Typically, IRPs have a default timeout of 5 seconds (definedas USB_TIMEOUT_DEFAULT in usb.h). However, certain IRPs, such as those usedto monitor interrupt status input from hubs, can have no timeout (defined asUSB_TIMEOUT_NONE in usb.h).

Typically, a background task spawned by the HCD during HCD_FNC_ATTACHprocessing is the mechanism used to detect when IRPs reach their timeouts. In thecase of the Wind River UHCI HCD, this same background task periodically pollsthe root hub for port status changes (as described in 1.4.6 Root Emulation, p.41).This background task is named tUhciInt, whereas the background task spawnedby the Wind River OHCI HCD is named tOhciInt.

1.5 Keyboard Driver

USB keyboards are described in Human Interface Device (HID) relatedspecifications. The Wind River implementation of the USB keyboard driver,usbKeyboardLib, is concerned only with USB devices claiming to be keyboards asset forth in the USB Specification; the driver ignores other types of human interfacedevices, such as printers.

1.5.1 SIO Driver Model

The USB keyboard class driver, usbKeyboardLib, follows the VxWorks serial I/O(SIO) driver model, with certain exceptions and extensions. As the SIO drivermodel presents a fairly limited, byte-stream-oriented view of a serial device, thekeyboard driver maps USB keyboard scan codes into appropriate ASCII codes.Scan codes and combinations of scan codes that do not map to the ASCII characterset are suppressed.

NOTE: USB keyboards can operate according to either a boot protocol or a reportprotocol; however, the usbKeyboardLib driver enables keyboards for operationusing the boot protocol only.

42

Page 51: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.5.2 Dynamic Attachment

Unlike most SIO drivers, the usbKeyboardLib driver’s number of supportedchannels is not fixed. Rather, USB keyboards can be added or removed from thesystem at any time. Thus, the number of channels is dynamic, and clients ofusbKeyboardLib must be made aware of the appearance and disappearance ofchannels. Therefore, this driver includes a set of routines that allows clients toregister for notification upon the attachment and removal of USB keyboards, andthe corresponding creation and deletion of channels.

In order to be notified of the attachment and removal of USB keyboards, clientsshould register with usbKeyboardLib by callingusbKeyboardDynamicAttachRegister( ). Clients provide a callback function ofthe following form:

typedef VOID (*USB_KBD_ATTACH_CALLBACK)(pVOID arg, /* caller-defined argument */SIO_CHAN *pChan, /* pointer to the affected SIO_CHAN */UINT16 attachCode /* defined as USB_KBD_xxxx */);

When usbKeyboardLib detects a new USB keyboard, each registered callback isinvoked with pChan pointing to a new SIO_CHAN structure and with attachCode setto the value USB_KBD_ATTACH. When keyboards are removed from the system,each registered callback is invoked with attachCode set to USB_KBD_REMOVE andwith pChan pointing to the SIO_CHAN structure of the keyboard that has beenremoved.

The usbKeyboardLib driver maintains a usage count for each SIO_CHANstructure. Callers can increase the usage count by callingusbKeyboardSioChanLock( ), or they can decrease it by callingusbKeyboardSioChanUnlock( ). Normally, if a keyboard is removed from thesystem when the usage count is zero (0), usbKeyboardLib automatically releasesthe SIO_CHAN structure formerly associated with the keyboard. However, clientsthat rely on this structure can use the locking mechanism to force the driver toretain the structure until it is no longer needed.

Example 1-1 SIO_CHAN Locking

Consider an application that periodically polls a keyboard by calling thepollInput( ) callback identified in a particular SIO_CHAN structure. This is anexample where SIO_CHAN locking could be required.

43

Page 52: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The task responsible for polling runs in the background and operatesasynchronously with respect to the code that receives attachment or detachmentnotification from usbKeyboardLib. If usbKeyboardLib frees the memoryassociated with the SIO_CHAN structure as soon as the keyboard is unplugged, itis possible that the pollInput( ) function pointer may be corrupted. If that occurs,the application’s asynchronous polling task would fail upon calling the—nowcorrupt—pollInput( ) function pointer, probably taking down the system.

The application can use the SIO_CHAN locking mechanism to force theusbKeyboardLib to delay the release of the SIO_CHAN structure until after theapplication has canceled the background polling operation.

The following code fragments demonstrate the typical use of the dynamicattachment and SIO_CHAN locking functions:

/* First, initialize the usbKeyboardLib. */if (usbKeyboardDevInit () != OK)

{/* We failed to initialize usbKeyboardLib. */return ERROR;}

/* Register for keyboard attachment/detachment notification. */if (usbKeyboardDynamicAttachRegister (kbdAttachCallback, (pVOID) 1234)

!= OK){/* We failed to register for attachment notification. */return ERROR;}

/* The kbdAttachCallback() function will now be called asynchronously* whenever a keyboard is attached to or detached from the system.*/....../* Unregister for keyboard notification and shut down usbKeyboardLib. */usbKeyboardDynamicAttachUnRegister (kbdAttachCallback, (pVOID) 1234);usbKeyboardDevShutdown ();

The keyboard attachment callback might resemble the following:

/*************************************************************************** kbdAttachCallback - receives callbacks from USB keyboard SIO driver** RETURNS: N/A*/

LOCAL SIO_CHAN *pOurChan = NULL;

LOCAL VOID kbdAttachCallback

44

Page 53: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

(pVOID arg, /* caller-defined argument */SIO_CHAN *pChan, /* pointer to the affected SIO_CHAN */UINT16 attachCode /* defined as USB_KBD_xxxx */)

{UINT32 ourArg = (UINT32) arg;

/* The argument is any arbitrary value that may be of use to this* callback. In this example, we just demonstrate that the value* originally passed to usbKeyboardDynamicAttachRegister() shows up here* as our argument.*/

if (ourArg != 1234){/* The argument never made it. */...}

switch (attachCode){case USB_KBD_ATTACH:

/* Lock the SIO_CHAN structure so it doesn’t disappear on us. */if (usbKeyboardSioChanLock (pChan) != OK)

{/* This really shouldn’t be able to fail. */...}

/* Do other initialization stuff. */pOurChan = pChan;......

break;

case USB_KBD_DETACH:

/* Tear down any data structures we may have created. */......pOurChan = NULL;

/* Allow usbKeyboardLib to release the SIO_CHAN structure. */usbKeyboardSioChanUnlock (pChan);break;

}}

45

Page 54: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.5.3 Initialization

As with standard SIO drivers, usbKeyboardLib must be initialized by callingusbKeyboardDevInit( ), which in turn initializes its connection to the USBD andother internal resources needed for operation. All interaction with the USB hostcontrollers and devices is handled through the USBD.

Unlike some SIO drivers, usbKeyboardLib does not include data structures thatrequire initialization prior to calling usbKeyboardDevInit( ).

However, before a call to usbKeyboardDevInit( ), the caller must ensure that theUSBD has been properly initialized by calling, at a minimum, usbdInitialize( ).The caller must also confirm that at least one USB HCD is attached to the USBD,using usbdHcdAttach( ), before keyboard operation can begin; however, it is notnecessary to call usbdHcdAttach( ) prior to initializing usbKeyboardLib. TheusbKeyboardLib driver uses the USBD dynamic attachment services andrecognizes USB keyboard attachment and removal on the fly. Therefore, it ispossible for USB HCDs to be attached to or detached from the USBD at run-time,as may be required (for example, in systems supporting hardware hotswap).

Unlike traditional SIO drivers, the usbKeyboardLib driver does not export entrypoints for send, receive, and error interrupts. All interrupt-driven behavior ismanaged by the underlying USBD and USB HCD(s), so there is no need for a caller(or BSP) to connect interrupts on behalf of usbKeyboardLib. For the same reason,there is no post-interrupt-connect initialization code, and usbKeyboardLibtherefore omits the devInit2 entry point.

1.5.4 ioctl Functions

The usbKeyboardLib driver supports the SIO ioctl interface. However, attempts toset parameters, such as baud rates and start or stop bits, have no meaning in theUSB environment and return ENOSYS.

1.5.5 Data Flow

For each USB keyboard connected to the system, usbKeyboardLib sets up a USBpipe to monitor keyboard input. Input, in the form of scan codes, is translated toASCII codes and placed in an input queue. If SIO callbacks have been installed andusbKeyboardLib has been placed in the SIO interrupt mode of operation,usbKeyboardLib invokes the character received callback for each character in thequeue. When usbKeyboardLib has been placed in polled mode, callbacks are not

46

Page 55: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

invoked and the caller must fetch keyboard input using the driver's pollInput( )routine.

The usbKeyboardLib driver does not support output to the keyboard; therefore,calls to the txStartup( )) and pollOutput( ) routines return errors. The only outputsupported is the control of the keyboard LEDs, which usbKeyboardLib handlesinternally.

The caller should be aware that usbKeyboardLib is not capable of operating in atrue polled mode, because the underlying USBD and USB HCD always operate ininterrupt mode.

The following code fragment demonstrates using usbKeyboardLib to displaykeystrokes typed by the user:

int i;char inChar;

/* Display the next ten keystrokes typed by the user. This code* assumes that pOurChan was initialized as shown earlier and is* currently not NULL. */for (i = 0; i < 10; i++)

{/* Wait for a keystroke */while ((*pOurChan->pDrvFuncs->pollInput) (pOurChan, &inChar) != OK)

;

/* Display the keystroke. */printf ("The user pressed ‘%c’.\n", inChar);}

1.5.6 Typematic Repeat

USB keyboards do not implement typematic repeat, a feature that causes a key torepeat if it is held down, typically for more than one-fourth or one-half second. Ifyou want this feature, implement it with the host software. For this purpose,usbKeyboardLib creates a task, tUsbKbd, that monitors all open channels andinjects characters into input queues at an appropriate repeat rate.

For example, if a user presses and holds a key on a USB keyboard, a single reportis sent from the keyboard to the host indicating the keypress. If no report isreceived within a pre-set interval indicating that the key has been released, thetUsbKbd thread automatically injects additional copies of the same key into theinput queue at a pre-set rate. In the current implementation, the pre-set interval(delay) is one-half (1/2) second, and the repeat rate is 15 characters per second.

47

Page 56: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.6 Mouse Driver

USB mice are described in Human Interface Device (HID) related specifications.The Wind River implementation of the USB mouse driver, usbMouseLib, concernsitself only with USB devices claiming to be mice as set forth in the USB Specification;the driver ignores other types of human interface devices, such as keyboards.

1.6.1 SIO Driver Model

The USB mouse class driver, usbMouseLib, follows the VxWorks serial I/O (SIO)driver model, with certain exceptions and extensions. For example, ioctl functionshave no effect.

1.6.2 Dynamic Attachment

As with the USB keyboard class driver, the number of channels supported by thisdriver is not fixed. Rather, USB mice can be added or removed from the system atany time. Thus, the number of channels is dynamic, and clients of usbMouseLibmust be made aware of the appearance and disappearance of channels. Therefore,this driver includes a set of routines that allows clients to register for notificationupon the attachment and removal of USB mice, and the corresponding creationand deletion of channels.

In order to be notified of the attachment and removal of USB mice, clients shouldregister with usbMouseLib by calling usbMouseDynamicAttachRegister( ).Clients provide a callback function of the following form:

typedef VOID (*USB_MSE_ATTACH_CALLBACK)(pVOID arg, /* caller-defined argument */SIO_CHAN *pChan, /* pointer to the affected SIO_CHAN */UINT16 attachCode /* defined as USB_MSE_xxxx */);

When usbMouseLib detects a new USB mouse, each registered callback is invokedwith pChan pointing to a new SIO_CHAN structure and with attachCode set to thevalue USB_MSE_ATTACH. When a mouse is removed from the system, each

NOTE: USB mice operate according to either a boot protocol or a report protocol;however, the usbMouseLib driver enables mice for operation using the bootprotocol only.

48

Page 57: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

registered callback is invoked with attachCode set to USB_MSE_REMOVE and withpChan pointing to the SIO_CHAN structure of the mouse that has been removed.

As with usbKeyboardLib, usbMouseLib maintains a usage count for eachSIO_CHAN structure. Callers can increment the usage count by callingusbMouseSioChanLock( ) and can decrement it by callingusbMouseSioChanUnlock( ). For more information on using the SIO_CHANstructure, see Example 1-1.

1.6.3 Initialization

As with standard SIO drivers, usbMouseLib must be initialized by callingusbMouseDevInit( ), which in turn initializes its connection to the USBD andother internal resources needed for operation. All interaction with the USB hostcontrollers and devices is handled through the USBD.

Unlike some SIO drivers, usbMouseLib does not include data structures thatrequire initialization prior to calling usbMouseDevInit( ).

However, before a call to usbMouseDevInit( ), the caller must ensure that theUSBD has been properly initialized by calling, at a minimum, usbdInitialize( ).The caller must also confirm that at least one USB HCD is attached to the USBD,using usbdHcdAttach( ), before mouse operation can begin; however, it is notnecessary to call usbdHcdAttach( ) prior to initializing usbMouseLib. TheusbMouseLib driver uses the USBD dynamic attachment services and recognizesUSB mouse attachment and removal on the fly. Therefore, it is possible for USBHCDs to be attached to or detached from the USBD at run-time, as may be required(for example, in systems supporting hardware hotswap).

Unlike traditional SIO drivers, the usbMouseLib driver does not export entrypoints for send, receive, and error interrupts. All interrupt-driven behavior ismanaged by the underlying USBD and USB HCD(s), so there is no need for a caller(or BSP) to connect interrupts on behalf of usbMouseLib. For the same reason,there is no post-interrupt-connect initialization code, and usbMouseLib thereforeomits the devInit2 entry point.

1.6.4 ioctl Functions

The usbMouseLib driver supports the SIO ioctl interface. However, attempts to setparameters, such as baud rates and start or stop bits, have no meaning in the USBenvironment and return ENOSYS.

49

Page 58: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.6.5 Data Flow

For each USB mouse connected to the system, usbMouseLib sets up a USB pipe tomonitor input from the mouse, in the form of HID boot reports. These mouse bootreports are of the following form (as defined in usbHid.h):

typedef struct hid_mse_boot_report{UINT8 buttonState; /* buttons */char xDisplacement; /* signed x-displacement */char yDisplacement; /* signed y-displacement */} HID_MSE_BOOT_REPORT, *pHID_MSE_BOOT_REPORT;

In order to receive these reports, a client of usbMouseLib must install a specialcallback using the driver’s callbackInstall( ) routine. The callback type isSIO_CALLBACK_PUT_MOUSE_REPORT, and the callback itself takes the followingform:

VOID (*MSE_REPORT_CALLBACK)(void *callbackArg, /* callback parameter specified by caller */pHID_MSE_BOOT_REPORT pReport /* pointer to mouse boot report */);

The client callback should interpret the report according to its needs, saving anydata that might be required from the HID_MSE_BOOT_REPORT structure.

The usbMouseLib driver does not support polled modes of operation; neitherdoes it support the traditional SIO_CALLBACK_PUT_RCV_CHAR callback. Giventhe structured nature of the boot reports received from USB mice,character-by-character input of boot reports would be inefficient and could lead toreport framing problems in the input stream.

1.7 Printer Driver

USB printers are described in Human Interface Device (HID) related specifications.This class driver specification presents two kinds of printer: uni-directionalprinters (output only) and bi-directional printers (capable of both output andinput). The usbPrinterLib driver is capable of handling both kinds of printers. If aprinter is uni-directional, the driver only allows characters to be written to the

50

Page 59: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

printer; if the printer is bi-directional, it allows both output and input streams tobe written and read.

1.7.1 SIO Driver Model

The USB printer class driver, usbPrinterLib, follows the VxWorks serial I/O (SIO)driver model, with certain exceptions and extensions. This driver provides theexternal APIs expected of a standard multi-mode serial (SIO) driver and addsextensions that support the hot-plugging USB environment.

1.7.2 Dynamic Attachment

As with usbKeyboardLib, usbMouseLib maintains a usage count for eachSIO_CHAN structure. Callers can increment the usage count by callingusbMouseSioChanLock( ) and can decrement it by callingusbMouseSioChanUnlock( ). These mechanisms are identical to those describedin 1.5 Keyboard Driver, p.42.

As with the USB keyboard class driver, the number of channels supported by thisdriver is not fixed. Rather, USB printers can be added or removed from the systemat any time. Thus, the number of channels is dynamic, and clients of usbPrinterLibmust be made aware of the appearance and disappearance of channels. Therefore,this driver includes a set of routines that allows clients to register for notificationupon the attachment and removal of USB printers, and the corresponding creationand deletion of channels.

In order to be notified of the attachment and removal of USB printers, clientsshould register with usbPrinterLib through the routineusbPrinterDynamicAttachRegister( ). Clients provide a callback function of thefollowing form:

typedef VOID (*USB_PRN_ATTACH_CALLBACK)(pVOID arg, /* caller-defined argument */SIO_CHAN *pChan, /* pointer to the affected SIO_CHAN */UINT16 attachCode /* defined as USB_PRN_xxxx */);

When usbPrinterLib detects a new USB printer, each registered callback isinvoked with pChan pointing to a new SIO_CHAN structure and with attachCode setto the value USB_PRN_ATTACH. When printers are removed from the system, each

51

Page 60: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

registered callback is invoked with attachCode set to USB_PRN_REMOVE and withpChan pointing to the SIO_CHAN structure of the printer that has been removed.

As with usbKeyboardLib, usbPrinterLib maintains a usage count for eachSIO_CHAN structure. Callers can increment the usage count by callingusbPrinterSioChanLock( ) and can decrement it by callingusbPrinterSioChanUnlock( ). Normally, if a printer is removed from the systemwhen the usage count is zero (0), usbPrinterLib automatically releases theSIO_CHAN structure formerly associated with the printer. However, clients thatrely on this structure can use this locking mechanism to force the driver to retainthe structure until it is no longer needed.

For more information about using the SIO_CHAN structure, see Example 1-1.

1.7.3 Initialization

As with standard SIO drivers, usbPrinterLib must be initialized by callingusbPrinterDevInit( ), which in turn initializes its connection to the USBD andother internal resources needed for operation. All interaction with the USB hostcontrollers and devices is handled through the USBD.

Unlike some SIO drivers, usbPrinterLib does not include data structures thatrequire initialization prior to calling usbPrinterDevInit( ).

However, before a call to usbPrinterDevInit( ), the caller must ensure that theUSBD has been properly initialized by calling, at a minimum, usbdInitialize( ).The caller must also confirm that at least one USB HCD is attached to the USBD,using usbdHcdAttach( ), before printer operation can begin; however, it is notnecessary to call usbdHcdAttach( ) prior to initializing usbPrinterLib. TheusbPrinterLib driver uses the USBD dynamic attachment services and recognizesUSB printer attachment and removal on the fly. Therefore, it is possible for USBHCDs to be attached to or detached from the USBD at run-time, as may be required(for example, in systems supporting hardware hotswap).

Unlike traditional SIO drivers, the usbPrinterLib driver does not export entrypoints for send, receive, and error interrupts. All interrupt-driven behavior ismanaged by the underlying USBD and USB HCD(s), so there is no need for a caller(or BSP) to connect interrupts on behalf of usbPrinterLib. For the same reason,there is no post-interrupt-connect initialization code, and usbPrinterLib thereforeomits the devInit2 entry point.

52

Page 61: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.7.4 ioctl Functions

The usbPrinterLib driver supports the SIO ioctl interface. However, attempts to setparameters, such as baud rates and start or stop bits, have no meaning in the USBenvironment and are treated as no-ops.

Additional ioctl functions have been added to allow the caller to retrieve the USBprinter's device ID string, the type of printer (uni- or bi-directional), and thecurrent printer status. The device ID string is discussed in more detail in the USBSpecification and is based on the IEEE-1284 device ID string used by most1284-compliant printers. The printer status function can be used to determinewhether the printer has been selected, is out of paper, or has an error condition.

1.7.5 Data Flow

For each USB printer connected to the system, usbPrinterLib sets up a USB pipeto output bulk data to the printer. This is the pipe through which printer controland page description data are sent to the printer. Additionally, if the printer isbi-directional, usbPrinterLib sets up a USB pipe to receive bulk input data fromthe printer. The meaning of data received from a bi-directional printer depends onthe particular printer make and model.

The USB printer driver supports only SIO_MODE_INT, the SIO interrupt mode ofoperation. Any attempt to place the driver in polled mode returns an error.

1.8 Speaker Driver

USB speakers are described in the USB Device Class Definition for Audio Devices. TheWind River implementation of the USB speaker driver, usbSpeakerLib, supportsonly USB speakers as defined by this specification and ignores other types of USBaudio devices, such as MPEG and MIDI devices.

53

Page 62: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.8.1 SEQ_DEV Driver Model

The usbSpeakerLib driver provides a modified VxWorks SEQ_DEV interface to itscallers. Among existing VxWorks driver models, the SEQ_DEV interface bestsupports the streaming data transfer model required by isochronous devices suchas USB speakers. As with other VxWorks USB class drivers, the standard driverinterface has been expanded to support features unique to the USB and to speakersin general. Functions have been added to allow callers to recognize the dynamicattachment and removal of speaker devices. ioctl functions have been added toretrieve and control additional settings related to speaker operation.

1.8.2 Dynamic Attachment

Like other USB devices, USB speakers can be attached to or detached from thesystem dynamically. The usbSpeakerLib driver uses the USBD's dynamicattachment services to recognize these events, and callers to usbSpeakerLib canuse the usbSpeakerDynamicAttachRegister( ) routine to register with the driverto be notified when USB speakers are attached or removed. The caller mustprovide usbSpeakerDynamicAttachRegister( ) with a pointer to a callbackroutine of the following form:

typedef VOID (*USB_SPKR_ATTACH_CALLBACK)(pVOID arg, /* caller-defined argument */SEQ_DEV *pSeqDev, /* pointer to the affected SEQ_DEV */UINT16 attachCode /* defined as USB_SPKR_xxxx */);

NOTE: Some models of USB speakers are implemented as compound devices, andthese compound devices often integrate a small number of physical audio controls,such as those for volume, bass, treble, and balance. These physical controls arepresented as separate USB interfaces within the compound device and areimplemented according to the HID specification. The usbSpeakerLib libraryignores these non-audio interfaces. If the target application requires these HIDcontrols to be enabled, you must implement additional logic to recognize the HIDinterface and map the HID functions to appropriate usbSpeakerLib ioctl functions(see 1.8.5 ioctl Functions, p.56).

54

Page 63: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

When a USB speaker is attached or removed, usbSpeakerLib invokes eachregistered notification callback. The callback is passed a pointer to the affectedSEQ_DEV structure, pSeqDev, and an attachment code, attachCode, indicatingwhether the speaker is being attached or removed.

The usbSpeakerLib driver maintains a usage count for each SEQ_DEV structure.Callers can increment the usage count by calling usbSpeakerSeqDevLock( ) orcan decrement the count by calling usbSpeakerSeqDevUnlock( ). If a USBspeaker is removed from the system when its usage count is 0, usbSpeakerLibautomatically removes all data structures, including the SEQ_DEV structure itself,that have been allocated on behalf of the device. Sometimes, however, callers relyon these data structures and must properly recognize the removal of the devicebefore it is safe to destroy the underlying data structures. The lock and unlockroutines provide a mechanism for callers to protect these data structures, asneeded.

1.8.3 Initialization

As with standard SEQ_DEV drivers, this driver must be initialized by callingusbSpeakerDevInit( ). The usbSpeakerDevInit( ) routine, in turn, initializes itsconnection to the USBD and other internal resources needed for operation.

Unlike some SEQ_DEV drivers, there are no usbSpeakerLib data structures thatmust be initialized before usbSpeakerDevInit( ) is called.

Prior to calling usbSpeakerDevInit( ), the caller must ensure that the USBD hasbeen properly initialized by, at a minimum, a call to usbdInitialize( ). It is also thecaller's responsibility to ensure that at least one USB HCD is attached to theUSBD—using the USBD function usbdHcdAttach( )— before speaker operationcan begin. However, it is not necessary to call usbdHcdAttach( ) prior toinitializing usbSpeakerLib. The usbSpeakerLib driver uses USBD’s dynamicattachment services and can recognize USB speaker attachment and removal onthe fly. Therefore, it is possible for USB HCDs to be attached to or detached fromthe USBD at run-time, as may be required (for example, in systems supportinghardware hotswap).

55

Page 64: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.8.4 Recognizing and Handling USB Speakers

Speakers, loosely defined, are USB audio devices that provide an output terminal.For each USB audio device, usbSpeakerLib examines the descriptors that defineboth the units and terminals contained within the device and how they areconnected.

If an output terminal is found, usbSpeakerLib traces the device's internalconnections to determine which input terminal provides the audio stream for thatoutput terminal, and which feature unit, if any, is responsible for controlling audiostream attributes such as volume. After building an internal map of the device,usbSpeakerLib configures the device and waits for a caller to provide a stream ofaudio data. If no output terminal is found, usbSpeakerLib ignores the audiodevice.

After determining that the audio device contains an output terminal,usbSpeakerLib builds a list of the audio formats that the device supports. TheusbSpeakerLib driver supports only AudioStreaming interfaces (noMIDIStreaming is supported).

For each USB speaker attached to the system and properly recognized byusbSpeakerLib, usbSpeakerLib creates a SEQ_DEV structure to control thespeaker. Each speaker is uniquely identified by the pointer to its correspondingSEQ_DEV structure.

1.8.5 ioctl Functions

The usbSpeakerLib driver implements a number of ioctl functions unique to thehandling of audio data and devices. The driver uses ioctl functions to set the mute,volume, bass, mid-range, and treble controls. The driver provides ioctl functionsfor use by callers to interrogate a speaker's audio format capabilities or to specifythe audio format for a subsequent data stream. The driver also provides ioctlfunctions to mark the beginning and end of audio data streams (see 1.8.6 Data Flow,p.57).

56

Page 65: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.8.6 Data Flow

Before sending audio data to a speaker device, the caller must specify the dataformat (for example, PCM or MPEG) using an ioctl function (see 1.8.5 ioctlFunctions, p.56). The USB speaker itself must support the specified data format ora similar one.

USB speakers rely on an uninterrupted, time-critical stream of audio data. The datais sent to the speaker through an isochronous pipe. In order for the data flow tocontinue uninterrupted, usbSpeakerLib uses an internal double-bufferingscheme. When the caller presents data to usbSpeakerLib's sd_seqWrt( ) routine,usbSpeakerLib copies the data into an internal buffer and immediately releasesthe caller's buffer. The caller should immediately try to pass the next buffer tousbSpeakerLib. When usbSpeakerLib's internal buffer is filled, it blocks the calleruntil it can accept new data. In this manner, the caller and usbSpeakerLib worktogether to ensure that an adequate supply of audio data is always available tocontinue isochronous transmission uninterrupted.

Audio play begins after usbSpeakerLib has accepted a half-second of audio dataor when the caller closes the audio stream, whichever happens first. The callermust use ioctl functions to open and close each audio stream. The usbSpeakerLibdriver relies on these open and close ioctl functions to manage its internal bufferscorrectly.

1.9 Mass Storage Class Driver

USB Mass Storage Class devices are described in the Mass Storage Classspecification and can behave according to several different implementations. WindRiver supplies drivers that adhere to the Bulk-Only and Control/Bulk/Interrupt(CBI) implementation methods. Each of these two drivers uses a command setfrom an existing protocol. The Wind River CBI driver wraps USB protocol aroundthe commands documented in SCSI Primary Commands: 2 (SPC-2), Revision 3 orlater.2 The Wind River Bulk-Only driver wraps USB protocol around thecommands documented in Advanced Technology Attachment Packet Interface (ATAPI)for Floppies, SFF-8070i.3

2. Available from Global Engineering, 800-854-7179.3. Also available from Global Engineering.

57

Page 66: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

A device’s Subclass code, presented in its interface descriptor, indicates which ofthese command sets the device understands. Table 1-1, adapted from the UniversalSerial Bus Mass Storage Class Specification Overview, shows the command set thatcorresponds to each Subclass code.

Wind River’s CBI driver responds to devices with Subclass code 05h. Wind River’sBulk-Only driver responds to devices with Subclass code 06h.

All references to the Mass Storage Class driver library take the form usbMSCxxx( ).References to Wind River’s CBI driver take the form usbCbiUfixxx( ); references toWind River’s Bulk-Only driver take the form usbBulkxxx( ).

Table 1-1 Device Subclass Codes and Corresponding Command Sets

Subclass Code Command Block Specification Comments

01h Reduced Block Commands(RBC) T10 Project 1240-D

Typically, a flash device uses RBCs.However, any Mass Storage device canuse RBCs.

02h SFF-8020ior

MMC-2 (ATAPI)

Typically, a CD/DVD device usesSFF-8020i or MMC-2 command blocksfor its Mass Storage interface.

03h QIC-157 Typically, a tape device uses QIC-157command blocks.

04h UFI Typically, a floppy disk drive (FDD)device uses UFI command blocks.

05h SFF-8070i Typically, a floppy disk drive (FDD)device uses SFF-8070i command blocks.However, an FDD device can belong toanother Subclass (for example, RBC);likewise, other types of storage devicecan belong to the SFF-8070i Subclass.

06h SCSI transparent command set

07h-FFh Reserved for future use

58

Page 67: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.9.1 Block Device Driver Model

A Mass Storage Class driver is a type of block device driver that provides genericdirect access to a block device through VxWorks. Mass Storage Class driversinteract with the file system. The file system, in turn, interacts with the I/O system.

A device driver for a block device must provide a means of creating a logical blockdevice structure called BLK_DEV. This structure describes the USB Mass Storagedevice in a generic fashion, specifying only those common characteristics thatmust be known to the file system being used with the device (for example, read,write, and ioctl routines). After the device has been initialized with a particular filesystem, all I/O operations for the device are routed through that file system. Thefile system, in turn, calls the routines in the specified BLK_DEV structure. TheBLK_DEV structure is initialized to point to the read/write routines described inthis section.

When the class driver creates the block device using usbMSCBlkDevCreate( ), theUSB device does not have a name or a file system associated with it. In most cases,a file system is assigned during device initialization in the user code (through aroutine such as dosFsDevInit( ) or rt11FsDevInit( )). File system initializationroutines assign a specified name to the USB device and enter the device into theI/O system device table. The following code fragment shows a typical USB MassStorage driver initialization sequence:

pBlkDev = usbMSCDevInit( );dosFsMkfs("dev1:", pBlkDev)

The hierarchy diagram in Figure 1-4 illustrates where the USB Mass Storage Classdriver fits into a VxWorks system.

59

Page 68: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Figure 1-4 USB Block Driver Hierarchy in a VxWorks System

Application

I/O System

Non-Block File System(dosFs, rawFs)Device Driver

USB Mass StorageClass Driver

USBD Host Driver

USB Host Controller

USB Devices

VxWorks

USB Stack

(Block driver)

60

Page 69: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

The USB Mass Storage Class device driver provides the following API functions tothe file system:

usbMSCDevInit( )This routine is a general initialization routine. It performs all operations thatare to be done one time only. It initializes required data structures and registersthe mass storage class driver with the USBD. It also registers for notificationwhen Mass Storage devices are dynamically attached. Traditionally, thisfunction is called from the VxWorks boot code.

usbMSCDevCreate( )

This routine creates a logical block device structure for a particular USB MassStorage device. At least one mass storage device must exist on the USB whenthis routine is invoked.

usbMSCBlkWrt( )

This routine writes to a specified physical block or blocks from a specified USBdevice.

usbMSCBlkRd( )

This routine reads a specified physical block or blocks from a specified USBdevice.

usbMSCDevIoctl( )

This routine performs any device-specific I/O control functions. For example,it sends commands that are not explicitly used by a typical file system, and itsets device configuration.

usbMSCStatusChk( )

This routine checks for the status of the USB device. This is primarily forremovable media such as USB floppy drives or Zip drives. A change in statusis reported to the file system mounted, if any.

usbMSCDevReset( )

This routine resets a specific Mass Storage device. It first tries to perform ablock reset command. If the block reset is not successful, the routine resorts toa port reset.

61

Page 70: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

1.9.2 Dynamic Attachment

A USB device driver must support the most important feature of a USB device:dynamic insertion and removal of the device. A USB Mass Storage Class device canbe plugged into and out of the system at any time. This “hotswap” feature issupported by a callback mechanism.

The USB Mass Storage Class driver provides the registration functionusbMSCDynamicAttachRegister( ), which registers the client with the driver.When a USB Mass Storage Class device is attached to or removed from the system,all clients are notified through the USBD’s call to a user-provided callbackfunction. The callback function receives the USB_NODE_ID of the attached deviceand a flag that is set to either USB_MSC_ATTACH or USB_MSC_DETACH, indicatingthe attachment or removal of the device. The driver also provides theusbMSCDynamicAttachUnregister( ) function for deregistering a block devicedriver.

The Mass Storage Class driver maintains a usage count of BLK_DEV structures.When a client uses the BLK_DEV structure, it informs the driver by callingusbMSCDevLock( ). For each usbMSCDevLock( ) call, the driver increments theusage count. When a client is finished with the BLK_DEV structure, it must notifythe driver by calling usbMSCDevUnlock( ). The driver then decrements the usagecount. Normally, if a Mass Storage Class device is removed from the system whenthe usage count is zero (0), the driver releases the corresponding BLK_DEVstructure. However, clients that rely on this structure can use this lockingmechanism to force the driver to retain the structure until it is no longer needed.

1.9.3 Initialization

The Mass Storage Class driver is initialized through the usbMSCDevInit( )routine. This API call, in turn, initializes internal resources needed for its operationand registers a callback routine with the USBD. The callback routine is theninvoked whenever a USB Mass Storage Class device is attached to or removedfrom the system.

All interactions between the USB host controller and the Mass Storage Class deviceare handled through the USBD. Therefore, before calling usbMSCDevInit( ), theuser must ensure that the USBD has been properly initialized withusbdInitialize( ). Also, before any operation with a block device driver, the callermust ensure that at least one host controller is attached to the USBD.

62

Page 71: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.9.4 Data Flow

The Mass Storage Class driver’s data read and write mechanism behaves like thatof a standard block device driver. It uses the data read and write function pointersthat are installed through the usbMSCBlkDevCreate( ) routine. Because most USBMass Storage Class devices can implement 64-byte endpoints only, the driver mustmanage the transfer of the larger chunks (that is, 512-byte blocks) of data that areunderstood by the file system. To facilitate the multiple read/write transactionsthat are necessary to complete the block access, the USBD uses its IRP mechanism.This allows the user to specify a function, usbMSCIrpCallback( ), that is calledwhen the block transaction is complete.

1.10 Communication Class Drivers

USB Communication Class devices can behave according to several differentimplementations. Wind River supplies drivers for Ethernet Networking ControlModel devices, and for Abstract Control Model devices.

1.10.1 Ethernet Networking Control Model Driver

This section describes Wind River’s USB Networking Control Model driver. Thedriver supports USB network adapter devices with Subclass code 06h (seeTable 1-1), with certain exceptions and extensions.

The Ethernet device presents two interfaces for transferring information to thedevice: a Communication Class interface and a Data Class interface. TheCommunication Class interface is a management interface and is required of allcommunication devices. The Data Class interface can be used to transport dataacross the USB wire. Ethernet data frames are encapsulated into USB packets andare then transferred using this Data Class interface. These Ethernet packets includean Ethernet destination address (DA), which is appended to the data field.Ethernet packets in either direction over the USB do not include a CRC (cyclicredundancy check); error-checking is instead performed on the surrounding USBpacket.

63

Page 72: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The hierarchy diagram in Figure 1-5 illustrates where the USB CommunicationClass driver fits into a VxWorks system.

Figure 1-5 USB Communication Class Driver Hierarchy in a VxWorks System

Application

I/O System

USB CommunicationClass Driver

USBD Host Driver

USB Host Controller

USB Devices

VxWorks

USB Stack

Socket Library

MUX Library

VxWorks

NetworkStack

64

Page 73: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

Enhanced Network Driver Model

Wind River’s USB Networking Control Model driver conforms to the MUXEnhanced Network Driver (END) model, with certain variations. These differencesare designed to accommodate the following features:

� Hotswap of USB devices.� Attaching multiple identical devices to one host.� USB network devices with vendor-specific initialization requirements. For

example, one of the supported devices, the KSLI adapter, requires newfirmware to be downloaded before normal operation can begin.

� A dynamic insertion and removal callback mechanism.

In order to meet these requirements, Wind River’s drivers include additional APIs,beyond those defined in the standard END specification. For detailed informationon the END model, see the Tornado BSP Developer’s Kit for VxWorks User’s Guide:Implementing a MUX-Based Network Interface Driver.

Dynamic Attachment

Because USB network adapters can be hotswapped to and from the system at anytime, the number of devices is dynamic. Clients of usbXXXEndLib can be madeaware of the attachment and removal of devices. The driver includes a set of APIcalls that allows clients to register for notification upon attachment or removal ofa USB network adapter device. The attachment and removal of USB networkadapters correspond, respectively, to the creation and deletion of USB_XXX_DEVstructures.

In order to be notified of the attachment or removal of USB network adapters,clients should register with usbXXXEndLib by callingusbXXXDynamicAttachRegister( ), providing a callback function.

When usbXXXEndLib detects a new USB network adapter, each registered clientcallback function is invoked with callbackType set to USB_XXX_ATTACH. Similarly,when a USB network adapter is removed from the system, each registered clientcallback function is invoked with callbackType set to USB_XXX_DETACH.

The usbXXXEndLib driver maintains a usage count for each USB_XXX_DEVstructure. When a client uses the USB_XXX_DEV structure, it informs the driver bycalling usbXXXDevLock( ). For each usbXXXDevLock( ) call, the driverincrements the usage count. When a client is finished with the USB_XXX_DEVstructure, it must notify the driver by calling usbXXXDevUnlock( ). The driverthen decrements the usage count. Normally, if an adapter is removed from the

65

Page 74: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

system when the usage count is zero (0), the driver releases the correspondingUSB_XXX_DEV structure. However, clients that rely on this structure can use thislocking mechanism to force the driver to retain the structure until it is no longerneeded.

Initialization

The usbXXXEndLib driver must be initialized through the usbXXXEndInit( )routine, which in turn initializes its connection to the USBD and other internalresources needed for its operation. This API call also registers a callback routinewith the USBD. The callback routine is then invoked whenever a USB networkingdevice is attached to or removed from the system.

All interactions between the USB host controller and the networking device arehandled through the USBD. Therefore, before calling usbXXXEndInit( ), the usermust ensure that the USBD has been properly initialized with usbdInitialize( ).Also, before any operation with a networking device driver, the caller must ensurethat at least one host controller has been attached to the USBD throughhcdAttach( ).

Interrupt Behavior

The usbXXXEndLib driver relies on the underlying USBD and HCD layers tocommunicate with the USB Ethernet Networking Control Model devices (networkadapters). The USBD and HCD layers, in turn, use the host controller interrupt forthis communication. In this way, all interrupt-driven behavior is managed by theunderlying USBD and HCD layers. Therefore, there is no need for the caller (orBSP) to connect interrupts on behalf of usbXXXEndLib. For the same reason, thereis no post-interrupt-connect initialization code and usbXXXEndLib omits thedevInit2 entry point.

The usbXXXEndLib driver inherently depends on the host controller interrupt forits communication with USB network adapters. Therefore, the driver supportsonly the interrupt mode of operation. Any attempt to place the driver in the polledmode returns an error.

ioctl Functions

The usbXXXEndLib driver supports the END ioctl interface. However, anyattempt to place the driver in the polled mode returns an error.

66

Page 75: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

Data Flow

The usbXXXEndLib driver’s data transmission mechanism deviates slightly fromthe END standard in that all data is routed through the USBD. TheXXXEndSend( ) routine fills in the pUSB_IRP structure and exports the structureto the USBD to send or receive the data.

IRPs are a mechanism for scheduling data transfers across the USB. For example,for the host to receive data from a network device, an IRP using the bulk input pipeis formatted and submitted to the USBD by the driver. When data becomesavailable, XXXEndRecv( ) is invoked by the IRP’s callback to process the incomingpacket.

Whenever data is transferred through the USBD using the pUSB_IRP structure,callback functions are passed to the USBD. These callback functions acknowledgethe transmission of each packet of data. The execution of each callback functionindicates that the corresponding data packet has been successfully transmitted.

1.10.2 Abstract Control Model Driver

All USB Abstract Control Model (ACM) devices (serial emulation devices) aremodems. These devices are described in the USB Communication Class devicespecification document. These devices use the common AT commands(“attention” commands; also known as “Hayes-compatible” commands) tocommunicate with the devices that conform to the specification. In this section,Wind River uses the term “USB modem driver” interchangeably with the term“USB ACM class driver.”

SIO Driver Model

The USB ACM class driver follows the VxWorks serial I/O (SIO) driver model,with certain exceptions and extensions. The reason for these differences is that themodems, traditionally, interface with the host by means of an RS232 serial line andare controlled as serial devices. The USB ACM class driver, therefore, provides theexternal APIs expected of a standard multimode serial I/O driver and addsextensions that support USB hotswap. The driver fills in an SIO_CHAN structurewith the additional API routines and extensions, and exports the structure to theupper layers of the USB stack for control of the modem devices.

67

Page 76: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Dynamic Attachment

Because USB modems can be added to or deleted from the system at any time, thenumber of devices is dynamic. Clients of usbAcmLib can be made aware of theattachment and removal of devices. The driver includes a set of API calls thatallows clients to register for notification upon the attachment or removal of USBmodems. The attachment and removal of USB modems correspond, respectively,to the creation and deletion of SIO_CHAN structures.

In order to be notified of the attachment or removal of USB modems, clients shouldregister with usbAcmLib by calling usbAcmCallbackRegister( ), with a callbackcode of USB_ACM_CALLBACK_ATTACH. While registering, clients must provide acallback function of the following type:

typedef STATUS (*USB_ACM_CALLBACK)(pVOID arg, /* caller-defined argument */SIO_CHAN * pChan, /* pointer to the affected SIO_CHAN */UINT16 callbackType, /* defined as USB_ACM_CALLBACK_XXXX */UINT8 * pBuf, /* pointer to data buffer, if any data*/

/* transfer is involved. Otherwise NULL */UINT16 count /* No. of bytes of data transferred if data */

/* transfer is involved. 0 otherwise. */)

When usbAcmLib detects a new USB modem, each registered callback is invokedwith pChan pointing to a new SIO_CHAN structure and with callbackType set toUSB_ACM_CALLBACK_ATTACH. Similarly, when a USB modem is removed fromthe system, each registered callback is invoked with pChan pointing to theSIO_CHAN structure of the removed device, and callbackType set toUSB_ACM_CALLBACK_DETACH.

The usbAcmLib driver maintains a usage count for each SIO_CHAN structure.When a client uses the SIO_CHAN structure, it informs the driver by callingusbAcmLockSioChan( ). For each usbAcmLockSioChan( ) call, the driverincrements the usage count. When a client is finished with the SIO_CHANstructure, it must notify the driver by calling usbAcmUnlockSioChan( ). Thedriver then decrements the usage count. Normally, if a modem is removed fromthe system when the usage count is zero (0), the driver releases the correspondingSIO_CHAN structure. However, clients that rely on this structure can use thislocking mechanism to force the driver to retain the structure until it is no longerneeded.

68

Page 77: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

Initialization

The usbAcmLib driver is initialized through the usbAcmLibInit( ) routine. ThisAPI call, in turn, initializes internal resources needed for its operation andestablishes its connection to the USBD.

All interactions with the USB host controller and devices are handled through theUSBD. Therefore, before calling usbAcmLibInit( ), the user must ensure that theUSBD has been properly initialized with usbdInitialize( ). Also, before modemoperation can begin, the caller must ensure that the host controller has beenattached to the USBD.

Interrupt Behavior

The usbAcmLib driver relies on the underlying USBD and HCD layers tocommunicate with the USB ACM devices (modems). The USBD and HCD layers,in turn, use the host controller interrupt for this communication. In this way, allinterrupt-driven behavior is managed by the underlying USBD and HCD layers.Therefore, there is no need for the caller (or BSP) to connect interrupts on behalf ofusbAcmLib. For the same reason, there is no post-interrupt-connect initializationcode and usbAcmLib omits the devInit2 entry point.

The usbAcmLib driver inherently depends on the host controller interrupt for itscommunication with modems. Therefore, the driver supports onlySIO_MODE_INT, the SIO interrupt mode of operation. Any attempt to place thedriver in the polled mode returns an error.

ioctl Functions

The usbAcmLib driver supports the SIO ioctl interface. However, any attempt toplace the driver in the polled mode returns an error. The driver supports additionalioctl functions in order to provide the ACM behavior detailed by the USBCommunication Class devices specification.

Data Flow

The usbAcmLib exports the callback functions for the sending and receiving ofdata as required by the VxWorks SIO model. These callback functions provide datafor transmission and accept any data received, character by character. This meansthat these callback functions are executed once for each character transmitted.

69

Page 78: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The practice of sending or receiving a single character at a time is typicallyintended for a traditional serial I/O device that has no buffer or very little buffer.For USB ACM devices, data is transmitted over bulk I/O pipes, with a packet sizein multiples of 8. For example, a typical value is 64 bytes per packet. In this case, itmakes sense for the API to allow transmission of data in packets, leaving thepacket size to be determined by the maximum packet size of the bulk I/O pipe.Therefore, the driver exports another set of routines for sending and receiving datain bulk quantities. The following ioctl command retrieves the maximum packetsize of the I/O pipe (that is, the buffer size):

UINT size;usbAcmIoctl (ptr, USB_ACM_SIO_GET_MAX_BUF_SIZE, &size) ;

Modem Control: Hayes Commands

The USB ACM specification indicates that modems must support the common ATcommand set for controlling modem behavior. The usbAcmLib driver exports twofunctions to support this feature:

� a transmit function

� a callback registration function. The user registers this callback function inorder to be notified of the modem’s response to the AT command.

1.11 Running the USB Kit

The Tornado project facility is a key element of the Tornado IntegratedDevelopment Environment (IDE). It provides graphical and automatedmechanisms for creating applications that can be downloaded to VxWorks, forconfiguring VxWorks with selected features, and for creating applications that canbe linked with a VxWorks image and started when the target system boots. Theproject facility provides mechanisms for the following actions:

� Organizing the files that make up a project.

� Grouping related projects into a workspace.

� Customizing and scaling VxWorks.

� Adding application initialization routines to VxWorks.

70

Page 79: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

� Defining varied sets of build options.

� Building applications and VxWorks images.

� Downloading application objects to the target.

For a tutorial introduction to the project facility, see the Tornado Getting StartedGuide.

Creating a Downloadable VxWorks Image Including USB

From the Tornado project facility, start a downloadable VxWorks project based onyour BSP. (For a list of BSPs supported with this release of the USB Kit, see theRelease Notes.) The USB Kit software provides components that support USBfunctionality.

USB components are located in the component tree under the hardware folder. Thefollowing components can be found in hardware>buses>USB Hosts:

� OHCI� OHCI Pci Init� UHCI� USB Host Stack� usbTool

The following components can be found in hardware>peripherals>USB Devices:

� End - Pegasus� Keyboard� Mass Storage - Bulk� Mass Storage - CBI� Mouse� Printer� Speaker

Under each of these folders there is also a sub-folder that contains the initializationcomponents for the USB modules.

For general instructions on using the project facility and creating projects, see theTornado User’s Guide: Projects.

For a basic USB setup, you must include the USB host stack component and at leastone of the two host controller components. If you intend to test a device, you mustinclude one or more of the device components.

71

Page 80: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Step 1: Including the Host Stack

Selecting the USB host stack component includes support for the USBD.

Step 2: Including a Host Controller

Selecting either the UHCI or OHCI components includes modules for those types ofhost controllers, respectively. Either host controller component requires that theUSB host stack component also be selected. Both host controllers can be present onthe image at once.

Step 3: Including Devices

Selecting any of the following USB device components includes the correspondingdriver module. These components require that the USB stack be present on theimage:

� Keyboard� Mouse� Printer� Speaker� Mass Storage - Bulk� Mass Storage - CBI� END - Pegasus

NOTE: When you include the OHCI component, the OHCI Init component isrequired. If your BSP does not have pciAutoConfig( ), use OHCI Pci Init as anexample of how the OHCI controller should be configured on the PCI bus. (Forinformation about configuring the OHCI host controller on the PCI bus, see1.15 BSP Porting Issues, p.84.) The OHCI Init component searches the PCI bus for anOHCI controller. The component searches through the list of supported hostcontrollers. If it finds a match, it configures it and continues looking until it findsno more host controllers. If you are using a different OHCI controller, you mustmodify the configlette for the OHCI Init component. Add your Vendor ID (VID) andProduct ID (PID) to the list of supported host controllers in theusrUsbPciOhciInit.c file. This configlette is located in target/config/comps/src.

72

Page 81: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1.12 Initialization

1.12.1 Host Stack and Host Controller Initialization

The USB Kit includes initialization configlettes for the USBD (host stack) and forboth OHCI- and UHCI-type host controllers. In the initialization process, the USBinitialization component makes a call to usbdInitialize( ). The host controllercomponents then attach any host controllers existing in the system to theinitialized USB stack.

1.12.2 Device Initialization

The USB Kit includes initialization components for all of the USB modules.

Keyboard, Mouse, Printer, and Speaker Initialization

The keyboard, mouse, printer, and speaker drivers contain initialization routinesthat install standard open, close, read, write, and ioctl functions into the I/O systemdriver table. This allows an application to call these drivers using standardVxWorks system calls.

For example, an application might want to monitor a keyboard’s input. First, theapplication opens the keyboard with the system call to open( ):

fileDescr = open ("/usbkb/0", 2, 0);

The application can now call the system’s read( ) routine in a loop:

read (fileDescr, &inChar, 1);

These operations can be used for the mouse, printer, and speaker drivers as well.

! CAUTION: When you use the initialization components, usbTool may not beused. The components were derived from usbTool itself, and cause compile-timeerrors when used concurrently with usbTool.

73

Page 82: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Mass Storage Class Device Initialization

The Bulk-Only and CBI Mass Storage Class driver configlettes install standardfunctions into a file system. As with the mouse, keyboard, speaker, and printerdrivers, these functions allow an application to make standard VxWorks systemcalls such as copy, rm, and format (depending on which file system is attached) toaccess the Mass Storage Class device.

After a USB block device has been created by means of usbMSCBlkDevCreate( )(see 1.9 Mass Storage Class Driver, p.57, for the possible values of MSC in this APIname), a file system can be attached to the device as follows:

/* attach DOS file system to the USB drive */pBulkDosVol = dosFsDevCreate ("/usbDr0", pBulkBlkDev, MAX_NO_FILES, 0);

Now calls such as copy( ) can refer to the device as usbDr0. In the following codefragment, the file readme.txt is copied from a host to the USB drive usbDr0.

copy ("host:/readme.txt", "/usbDr0/readme.txt");

SCSI6 Commands

In internal testing, Wind River has found that one supported drive, the M-SystemsFlashOnKey device, does not support SCSI6 commands. This may also be the casefor some non-supported drives. Therefore, the Bulk-Only driver supports bothSCSI-6 and SCSI-10 read/write commands. The user must configure the driver touse the appropriate command for communicating with the device.

The fourth parameter of usbMSCBlkDevCreate( ) sets the SCSI transfer mode. Itcan take either of the following values:

Communication Class Device Initialization

The USB Kit includes a configlette, called usrUsbPegasusEndInit.c, to initialize thePegasus Communication Class driver. Upon device insertion, these routinesconnect a Pegasus device to the network stack, attaching an IP address to thedevice through a specified gateway address.

The IP address, gateway, host name, and a net mask are all user-definableparameters of the component and must be set before communication with thePegasus device can occur.

USB_SCSI_FLAG_READ_WRITE10 Use SCSI read/write 10.USB_SCSI_FLAG_READ_WRITE6 Use SCSI read/write 6.

74

Page 83: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

When a Communication Class device has been successfully connected, it can beused like any other network device.

Like all USB devices, a Communication Class device can be inserted or removed atany time. If the device is unplugged, any resources devoted to it are freed, and thesystem node that was created for it is removed.

1.12.3 usbAudio Initialization

The USB Kit includes a sample application called usbAudio, which demonstrateshow to use the USB stack and the speaker class driver. This application wasdesigned to run on a pcPentium machine that contains both a host controller(OHCI or UHCI) and an ATA hard drive containing .wav files.

The usbAudio program operates with any of the listed supported speakers.

1.12.4 usbTool Code Exerciser

The USB Kit includes a utility called usbTool which you can use to exercise themodules that comprise the USB stack. For example, if you were implementing adifferent device driver, you can use usbTool to exercise and debug your code.

The usbTool utility provides a basic code skeleton that you can customize to suityour test needs.

NOTE: In most cases, when support for a USB Communication Class device isadded, two network devices exist on the system as a result. To make this possible,you must increase the value of IP_MAX_UNITS to 2. This value is a parameter tothe network buffer initialization component. This component is found undernetwork components>basic network initialization components>network buffer initialization.

NOTE: The usbTool module relies internally on static data; you should not runmultiple instances of usbTool simultaneously.

75

Page 84: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Running usbTool from the Shell

1. To use the tool from the shell, type the entry point of the tool at the shellprompt, as follows:

->usbTool

This produces a new prompt where commands can be entered:

usb>

2. To get a list of all usbTool commands and their definitions, type the following:

usb>?

The usbTool Execution Sequence

The usbTool utility allows the user to see a typical execution sequence needed toget the USB up and running.

When an image that includes USB components boots, it automatically executes asequence of events similar to using the usbTool utility:

(1) To initialize the USB host stack, enter the usbInit command at the usbToolprompt.

(2) To initialize an OHCI or UHCI host controller, enter the attach uhci orattach ohci commands at the usbTool prompt.

(3) If you plan to use a device driver, after initializing the host stack and hostcontroller, enter the initialization command for that driver at the usbToolprompt.

To test any included devices, enter the appropriate test command, for example:

usb>mouseTest

! CAUTION: When running usbTool on a host shell, you may encounter aredirection problem that prevents entered commands from being echoed back tothe shell. You can avoid this issue by running usbTool on a target shell.

NOTE: Selecting any of the device driver components (keyboard, mouse, printer,speaker) includes the device test commands into usbTool. If the components arenot included, the commands are not available.

76

Page 85: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

The following commands are available when their associated device componentsare included in your VxWorks image:

mousemouseTest

keyboard

kbdInit, kbdDown and kbdPoll

printerprnInit, prnDown, print4k and print filename

speakerspkrInit, spkrDown, spkrFmt, volume, and play filename

For descriptions of these commands, invoke the help list from usbTool.

1.13 Booting VxWorks Through a Communication Class Driver

You can use the Pegasus USB Ethernet driver to build a bootable VxWorks image.At the time of this release, only the Pegasus driver supported booting.

In order to make a USB boot ROM, you must modify several BSP files. However, itis not recommended that you alter the original BSP system files. Instead, make acopy of the files so that you can revert to the original BSP configuration if needed.

The following configuration files must be altered in order to build a bootableVxWorks image:

� config.h� configNet.h� sysLib.c� bootConfig.c

The sections below provide details on how to alter these files.

NOTE: Command names do not have to be fully entered to be executed. Forexample, usbInit can be entered as usbi.

77

Page 86: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

In config.h

In this file, you must define the USB parts that are required.

Because this method of booting VxWorks uses a USB networking device forbooting, you must undefine the default boot device. The following line undefinesthe default boot device for a pcPentium system:

#undef INCLUDE_FEI

The native network support component (in this case, FEI) conditionally includesthe network stack type (in this case, END) as well as the network device connectiontype (in this case, PCI). Therefore, in addition to including the USB components,you must also re-include the components for network stack type and networkdevice connection type.

The following code fragment demonstrates how to include in config.h thecomponents necessary for booting:

#define INCLUDE_USB_PEGASUS_END#if defined(INCLUDE_USB_PEGASUS_END)

#ifndef INCLUDE_USB#define INCLUDE_USB#endif

#ifndef INCLUDE_OHCI# define INCLUDE_OHCI_PCI_INIT# define INCLUDE_OHCI#endif

#ifndef INCLUDE_PCI# define INCLUDE_PCI#endif

#ifndef INCLUDE_END# define INCLUDE_END#endif

#endif

#endif

In configNet.h

This file contains the definitions of the network load routine and other parametersthat are to be included in the endDrvTbl[ ]. This table tells muxDevLoad( ) whichnetwork method should be called when the network stack is bringing up thenetwork device.

78

Page 87: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

1. First, define the load routine for the driver. The load routine for the Pegasusdriver is contained in usrUsbPegasusInit.c under config/comps/src. Forexample:

/* Define the Pegasus load routine */#ifdef INCLUDE_USB_PEGASUS_END#define END_PEGASUS_LOAD_FUNC sysUsbPegasusEndLoad#define END_PEGASUS_BUFF_LOAN 1#define END_PEGASUS_LOAD_STRING ""

IMPORT END_OBJ * END_PEGASUS_LOAD_FUNC (char *, void*);

2. Then add these definitions to the endDevTbl[ ] array. For example:

END_TBL_ENTRY endDevTbl [] ={/* Include the Pegasus load routine in the table */#ifdef INCLUDE_USB_PEGASUS_END

{0, END_PEGASUS_LOAD_FUNC, END_PEGASUS_LOAD_STRING, \END_PEGASUS_BUFF_LOAN, NULL},

#endif /* INCLUDE_USB_PEGASUS_END */.........

{ 0, END_TBL_END, NULL, 0, NULL, FALSE},};

In sysLib.c

Add a section to this file to include the configlette files for the initialization of theUSB stack and the network driver. For example, the following code includes theUSB stack, the OHCI driver, and the Pegasus network driver initialization code:

/* Include USB stack initialization */#ifdef INCLUDE_USB#include usrUsbInit.c#endif

/* Include PCI enumeration of OHCI card */#ifdef INCLUDE_OHCI_PCI_INIT#include usrUsbPciOhciInit.c#endif

/* Include the OHCI driver initialization */#ifdef INCLUDE_OHCI#include usrUsbHcdOhciInit.c#endif

/* Include the Pegasus network driver initialization */#ifdef INCLUDE_PEGASUS#include usrUsbPegasusInit.c#endif

79

Page 88: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

For more information on the files named in this example, see 1.12 Initialization,p.73.

In target/config/all/bootConfig.c

This file contains the calls to the USB routines.

The boot ROM you make for booting VxWorks must do the following:

(1) Initialize the USB host stack through a call to usbdInitialize( ).

(2) Attach a host controller to the USBD. In the example below, an OHCI controlleris attached.

(3) Initialize the USB network driver. The example below uses the Pegasus driver,as it is the only device that supports USB booting.

Create a routine like the one below. It should be called from usrRoot( ) aftersysClkEnable( ).

/****************************************************************************** usbOhciInit - initialize the USB stack w/ OHCI controller** RETURNS: Nothing.*/

LOCAL void usbOhciInit(){usbInit ();sysUsbPciOhciInit ();usrUsbHcdOhciAttach ();taskDelay (sysClkRateGet()*3);usbPegasusEndInit ();}

A call to your function should appear as follows:

sysClkEnable (); /* start it */

/* Begin USB initialization */sysUsbPciOhciInit(); /* map OHCI card into PCI space */usbOhciInit(); /* initialize stack, attach HC, initialize */

/* network driver */taskDelay (sysClkRateGet()*5); /* gratuitous delay to allow bus traffic */

/* to settle *//* End USB initialization */

/* initialize I/O and file system */iosInit (NUM_DRIVERS, NUM_FILES, "/null");

80

Page 89: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

With these modifications, you can build a boot ROM in the BSP with the followingcommand:

make bootrom_uncmp

Now USB can be used as a boot parameter:

VxWorks System Boot

Copyright 1984-1998 Wind River Systems, Inc.CPU: PCPENTIUMVersion: 5.4.2BSP version: 1.2/0Creation date: Jun 14 2001, 10:03:12Press any key to stop auto-boot...@2

boot device usbunit number 0processor number 0host name hostfile name path/vxWorksinet on ethernet (e)90.0.0.50host inet (h) 90.0.0.3user (u) targetflags (f) 0x0

1.14 Benchmarking Information

This section provides information to help you benchmark your test results. Themetrics shown in this section are derived using spyLib, a VxWorks library thatdisplays information on task execution and CPU utilization.

The sample test described in this section was performed on a project created withthe following components included:

� USB stack and its associated initialization components� OHCI driver and its associated initialization components� Speaker driver and its associated initialization components� Mass Storage Class driver and its associated initialization components� Speaker demo program� spyLib� Target shell

81

Page 90: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

This test was performed on a 400 MHz Pentium II machine with the followingfeatures:

� 128 MB RAM� Lucent Quadrabus 4-port OHCI card� Philips USB speakers� ORB 2.2 GB removable media USB drive

This test used the usbAudio demo program’s play command to play a .wav filethrough the speakers. The Mass Storage Class driver initialization code wasallowed use of the standard calls to the ORB drive, such as copy, rm, and format.

To perform the test, a VxWorks image was built with all of the components listedabove. Two host shells and a target shell were used for entering commands. Usingone host shell, a large (~8 MB) file was copied from the host machine to the ORBdrive. Immediately following, on the other host shell, a .wav file was played usingthe usbAudio tool’s play command. The .wav file was approximately 2 MB andhad the following format:

While the .wav file was being transferred and sound was playing, spyLib wascalled, to display all tasks’ CPU usage. To invoke spyLib, give the followingcommand through the target shell:

->spy 10, 200

This command to spyLib produces a report every 10 seconds, displaying data thatwas gathered at the rate of 200 times per second. The following 3 sample reports,Example 1-2, Example 1-3, and Example 1-4, were produced during the time thedata transfers were in progress.

Example 1-2 spyLib Results Before USB Transfers

NAME ENTRY TID PRI total % (ticks) delta % (ticks)---------- -------- ------- --- --------------- ----------------tUsbdClnt 3fd0604 0 0% ( 0) 0% ( 0)tOhciInt 3fb9da4 0 0% ( 0) 0% ( 0)tOhciInt 3f9fdb4 0 0% ( 0) 0% ( 0)tOhciInt 3f85da4 0 0% ( 0) 0% ( 0)tOhciInt 3f6bdf0 0 0% ( 0) 0% ( 0)tExcTask excTask 3f632d0 0 0% ( 0) 0% ( 0)tLogTask logTask 3f609cc 0 0% ( 0) 0% ( 0)tUsbdClnt 3f5cb38 0 0% ( 0) 0% ( 0)

Size of Format: 16Format: Pulse Code Modulation (PCM)Channels: 1Sample Rate: 22050Bytes per Second: 44100

82

Page 91: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

tUsbdClnt 3f36e54 0 0% ( 0) 0% ( 0)tUsbdBus 3fb595c 1 0% ( 0) 0% ( 0)tUsbdBus 3f9b9a8 1 0% ( 0) 0% ( 0)tUsbdBus 3f81998 1 0% ( 0) 0% ( 0)tUsbdBus 3f679fc 1 0% ( 0) 0% ( 0)tShel shell 3ea3c80 0% ( 0) 0% ( 0)tWdbTask 3ea4e14 3 0% ( 0) 0% ( 0)tPlay 36f4d88 4 0% ( 0) 0% ( 0)tBulkClnt 3f327fc 5 0% ( 0) 0% ( 0)tSpyTask spyComTask 35a37f4 5 0% ( 0) 0% ( 0)tNetTask netTask 3ef0ed0 50 0% ( 0) 0% ( 0)KERNEL 0% ( 0) 0% ( 0)INTERRUPT 0% ( 0) 0% ( 0)IDLE 0% ( 0) 0% ( 0)TOTAL 0% ( 1) 0% ( 1)

Example 1-3 records when the data transfers begin to be logged.

Example 1-3 spyLib Results During USB Transfers

NAME ENTRY TID PRI total % (ticks) delta % (ticks)---------- -------- ------- --- --------------- ----------------tUsbdClnt 3fd0604 0 0% ( 0) 0% ( 0)tOhciInt 3fb9da4 0 1% ( 24) 1% ( 12)tOhciInt 3f9fdb4 0 0% ( 2) 0% ( 0)tOhciInt 3f85da4 0 0% ( 0) 0% ( 0)tOhciInt 3f6bdf0 0 0% ( 0) 0% ( 0)tExcTask excTask 3f632d0 0 0% ( 0) 0% ( 0)tLogTask logTask 3f609cc 0 0% ( 0) 0% ( 0)tUsbdClnt 3f5cb38 0 0% ( 0) 0% ( 0)tUsbdClnt 3f36e54 0 0% ( 0) 0% ( 0)tUsbdBus 3fb595c 1 0% ( 0) 0% ( 0)tUsbdBus 3f9b9a8 1 0% ( 0) 0% ( 0)tUsbdBus 3f81998 1 0% ( 0) 0% ( 0)tUsbdBus 3f679fc 1 0% ( 0) 0% ( 0)tShell shell 3ea3c80 1 3% ( 52) 3% ( 25)tWdbTask 3ea4e14 3 0% ( 0) 0% ( 0)tPlay 36f4d88 4 0% ( 0) 0% ( 0)tBulkClnt 3f327fc 5 0% ( 0) 0% ( 0)tSpyTask spyComTask 35a37f4 5 0% ( 1) 0% ( 1)tNetTask netTask 3ef0ed0 50 0% ( 6) 0% ( 0)KERNEL 0% ( 3) 0% ( 1)INTERRUPT 0% ( 9) 0% ( 3)IDLE 93%( 1363) 94% ( 687)TOTAL 97%( 1461) 98% ( 729)

Example 1-4 spyLib Results During USB Transfers

NAME ENTRY TID PRI total % (ticks) delta % (ticks)---------- -------- ------- --- --------------- ----------------tUsbdClnt 3fd0604 0 0% ( 0) 0% ( 0)tOhciInt 3fb9da4 0 1% ( 30) 0% ( 6)

83

Page 92: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

tOhciInt 3f9fdb4 0 0% ( 3) 0% ( 1)tOhciInt 3f85da4 0 0% ( 0) 0% ( 0)tOhciInt 3f6bdf0 0 0% ( 0) 0% ( 0)tExcTask excTask 3f632d0 0 0% ( 0) 0% ( 0)tLogTask logTask 3f609cc 0 0% ( 0) 0% ( 0)tUsbdClnt 3f5cb38 0 0% ( 0) 0% ( 0)tUsbdClnt 3f36e54 0 0% ( 0) 0% ( 0)tUsbdBus 3fb595c 1 0% ( 0) 0% ( 0)tUsbdBus 3f9b9a8 1 0% ( 0) 0% ( 0)tUsbdBus 3f81998 1 0% ( 0) 0% ( 0)tUsbdBus 3f679fc 1 0% ( 0) 0% ( 0)tShell shell 3ea3c80 1 3% ( 78) 3% ( 26)tWdbTask 3ea4e14 3 0% ( 0) 0% ( 0)tPlay 36f4d88 4 0% ( 0) 0% ( 0)tBulkClnt 3f327fc 5 0% ( 0) 0% ( 0)tSpyTask spyComTask 35a37f4 5 0% ( 2) 0% ( 1)tNetTask netTask 3ef0ed0 50 0% ( 7) 0% ( 1)KERNEL 0% ( 3) 0% ( 0)INTERRUPT 0% ( 17) 1% ( 8)IDLE 93%( 2048) 94% ( 685)TOTAL 97%( 2189) 98% ( 728)

The OHCI task, which is responsible for handling the traffic, occupies a minimumamount of CPU time. (Four such tasks are shown in the reports above: one for eachport on the Lucent card.)

In addition to using spyLib, data throughput rates were determined using a CATCUSB bus analyzer. The CATC is a bus sniffer that allows USB bus traffic to bemonitored. The traces obtained from this hardware were used to calculate thebandwidth of this VxWorks host. These bandwidth calculations were obtainedfrom the traffic during a file transfer to the ORB drive only.

The ORB drive implements a 64-byte output endpoint for sending data to a host.It sends 512-byte chunks per transfer. The CATC trace showed transfers over a499-millisecond period of time. Using the amount of raw data transferred in thisinterval, a throughput rate of 6 Mbps was calculated.

This number most likely points to the device, not the host, as the bottleneck.Identical rates were also found using a Windows 98 Second Edition host.

1.15 BSP Porting Issues

The Wind River USB driver stack has been designed to ease porting across WindRiver BSP platforms. At the source code level, the stack has been tested

84

Page 93: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

successfully on both big and little-endian platforms and across several Wind RiverBSPs. (See USB Developer’s Kit Release Notes: Tested Devices.)

You must address two key issues when porting the USB stack to a new BSP:

� The BSP startup code must configure the USB hardware prior to theinitialization of the USB stack.

� For UHCI and OHCI host stacks, the usbPciLib module (that is, the varioususbPciStub.c files) must be modified to use the correct PCI functions in theunderlying BSP.

The following sections discuss each of these issues in detail.

1.15.1 Configuring USB Hardware

As shipped, the Wind River USB stack supports both UHCI and OHCI USB hostcontrollers. In all systems tested to date, both the UHCI and OHCI host controllersare implemented as PCI devices. As with any PCI device, the UHCI and OHCI hostcontrollers need to be configured to use specific PCI resources.

A PCI UHCI host controller, for example, uses a single I/O address range and oneinterrupt channel. A PCI OHCI controller, on the other hand, uses a single memoryaddress range and one interrupt channel. Both types of controllers need to beassigned a unique address range and an interrupt channel, as well as enabled forbus master operation on the PCI bus; these activities are referred to in this manualas configuring the USB hardware.

It is important to note that the Wind River USB stack itself makes no attempt toassign such PCI resources. Instead, the stack expects that the USB host controller(s)are already assigned resources and enabled before an attempt is made to attach thespecific host controller to the USBD.

BSPs with pciAutoConfigLib

Certain Wind River BSPs include the module pciAutoConfigLib; in these BSPs, theconfiguration of each PCI device is handled automatically. The only PCI devicesnot configured automatically are those listed in the PCI auto-config exclude listwhich is unique for each BSP. So, in order to configure a UHCI or OHCI hostcontroller in these systems, you should ensure that the USB host controller is notin the exclude list.

For more information about pciAutoConfigLib, see your BSP documentation.

85

Page 94: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

BSPs Without pciAutoConfigLib

In BSPs that do not include pciAutoConfigLib, the assignment of PCI resourcesand enabling of each PCI device is generally handled in sysLib.c. You must writecode that explicitly assigns certain PCI resources to each PCI device to beconfigured. That can be done in a configlette or by modifying sysLib.c directly.

The following example was written for the mtx604 BSP to enable an OPTi FireLink82C861 OHCI host controller. Use this code in a configlette or add it directly tosysLib.c:

/****************************************************************************** sysUsbPciOhciInit - configures OHCI adapter** This routine attempts to locate an OHCI controller. If found, it sets up* the controller's PCI configuration.** RETURNS: N/A*/

void sysUsbPciOhciInit (void){int pciBus;int pciDevice;int pciFunc;

/* Attempt to locate the OHCI controller. */if (pciFindDevice (0x1045 /* OPTi */, 0xc861 /* 82c861 */, 0,

&pciBus, &pciDevice, &pciFunc) != OK)return;

/* Set up the base memory address for the controller. */pciDevConfig (pciBus, pciDevice, pciFunc, NULL, PCI_MEM_ADRS,

PCI_CMD_MASTER_ENABLE | PCI_CMD_MEM_ENABLE);

/* Set up the controller's interrupt assignment. */pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_DEV_INT_LINE,

0xb /* based on PCI "slot" number */);}

The sysUsbPciOhciInit( ) routine is called at the end of sysHwInit( ) in sysLib.c.

In this example, the OHCI controller needs a memory address range throughwhich usbHcdOhciLib reads and writes the controller’s memory-mappedregisters. The choice of the address, PCI_MEM_ADRS— the fifth parameter to

NOTE: For this release, this functionality is provided by a configlette; see thecomponent description file (CDF) in target/config/comps/vxWorks/src.

86

Page 95: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

pciDevConfig( )—was appropriate for temporary testing on the mtx604 BSP. Youshould make a permanent selection for your particular BSP and create constantsthat document this assignment.

Similarly, in this example, the interrupt channel 0xb is assigned to the OHCIcontroller. The mtx604 motherboard routes the physical PCI slot to interruptchannel 0xb. The interrupt channel number in your BSP or hardware environmentis likely to be different, and your code should reflect this.

The choice of a specific address range or interrupt channel depends entirely on theunderlying hardware configuration.

1.15.2 Configuring Memory Address Windows

When using PCI devices that require memory address windows, such as OHCIhost controllers, you must make sure that a memory mapping has been created,allowing the processor to “see” the memory window assigned to the PCI device.In the sysUsbPciOhciInit( ) example in BSPs with pciAutoConfigLib, p.85, thememory window beginning at PCI_MEM_ADRS already has a mapping on themtx604 platform, and no code modifications are required.

However, other BSP platforms might require alterations, for example, thepcPentium platform. The following code fragment creates a CPU memorymapping entry for the pcPentium. Add this code at the end of sysHwInit( ) insysLib.c, either through a configlette or by manually inserting it:

int pciBus;int pciDevice;int pciFunc;UINT32 membaseCsr;

/* Find the OPTi controller. */if (pciFindDevice (0x1045 /* OPTi */, 0xc861 /* 82C861 */, 0,

&pciBus, &pciDevice, &pciFunc) != OK)return;

/* get memory base address. * * NOTE: We’re assuming here that the memory address range was assigned* elsewhere, perhaps by pciAutoConfigLib. */pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0,

&membaseCsr); membaseCsr &= PCI_MEMBASE_MASK;

/* add the entry to sysPhysMemDesc[]. * * Note: This code must be executed before usrMmuInit(). */

87

Page 96: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

sysMmuMapAdd ((void *) membaseCsr, 0x1000 /* 4k window */,0x3f /* memory attribute mask */, 0x5 /* memory attributes */);

The final function call in the above code, sysMmuMapAdd( ), creates a memorymapping on the pcPentium platform. The mechanism for creating such a mappingwill vary from BSP to BSP. For more information, check the relevant BSPdocumentation.

1.15.3 Creating BSP-Specific Stub usbPciLib Files

As noted earlier, the stubUsbArchPciLib.c files shield the UHCI and OHCI HCDsfrom variations among underlying BSPs. These files provide the followingroutines, however the underlying PCI functionality may vary from one BSP to thenext.

8-bit, 16-bit, and 32-bit data I/O:

Address range translation functions:

Interrupt functions:

Internally, the stubUsbArchPciLib.c files implement the above routines bydefining a series of macros. Definitions may vary from BSP to BSP.

The following code excerpt from stubUsbPpcPciLib.c shows how the necessarymacros are defined for the mcp750 and mtx604. Creating your own stub file for anew platform generally involves creating a comparable set of definitionscustomized for that platform.

usbPciByteIn( ) usbPciWordIn( )usbPciDwordIn( ) usbPciByteOut( )usbPciWordOut( ) usbPciDwordOut( )

usbPciMemOffset( )usbMemToPci( )usbPciToMem( )

usbPciIntConnect( )usbPciIntRestore( )

NOTE: Certain Wind River BSPs do not support disconnection from theunderlying PCI interrupt vector. See USB Developer’s Kit Release Notes: BSP-SpecificIssues.

88

Page 97: Usb Developers Kit Programmers Guide 1.1.2 (1)

1

1USB Host Stack

/* Power PC 604 (e.g., mcp750) */

#include "mv2600.h"

/* Mappings for I/O and memory address translation (values from mv2600.h) */#define PCI_IO_OFFSET CPU_PCI_ISA_IO_ADRS#define PCI_MEM_OFFSET PCI2DRAM_BASE_ADRS#define PCI_MEMIO_OFFSET (CPU_PCI_MEM_ADRS - PCI_MEM_ADRS)

/* The mcp750 doesn’t define sysInWord, sysInLong, sysOutWord, and * sysOutLong. It includes the following entry points instead for which * there is no vxWorks function prototype. We include the following * definitions in order to suppress compiler warnings. */extern USHORT sysIn16 (int port);extern ULONG sysIn32 (int port);extern void sysOut16 (int port, short data);extern void sysOut32 (int port, long data);

/* Map the "standard" vxworks I/O functions to the mcp750 equivalents */#define sysInWord(p) sysIn16(p)#define sysInLong(p) sysIn32(p)#define sysOutWord(p,d) sysOut16(p,d)#define sysOutLong(p,d) sysOut32(p,d)

/* Interrupt enable/disable */#ifdef MCP750#define INTERRUPT_BASE ISA_INTERRUPT_BASE#else#define INTERRUPT_BASE EXT_INTERRUPT_BASE#endif

#define IVEC(i) INUM_TO_IVEC ((int) ((i) + INTERRUPT_BASE))

#define INT_CONNECT(intNo, func, param) \intConnect (IVEC (intNo), (VOIDFUNCPTR) func, (int) param)

#define INT_DISCONNECT(intNo, func, param)

#define INT_ENABLE(i) intEnable ((i) + INTERRUPT_BASE)#define INT_DISABLE(i) intDisable ((i) + INTERRUPT_BASE)

/* Map I/O functions to underlying system functions. */#define OUR_PCI_IN_BYTE(a) sysInByte ((a) + PCI_IO_OFFSET)#define OUR_PCI_IN_WORD(a) sysInWord ((a) + PCI_IO_OFFSET)#define OUR_PCI_IN_DWORD(a) sysInLong ((a) + PCI_IO_OFFSET)#define OUR_PCI_OUT_BYTE(a,v) sysOutByte ((a) + PCI_IO_OFFSET, (v))#define OUR_PCI_OUT_WORD(a,v) sysOutWord ((a) + PCI_IO_OFFSET, (v))#define OUR_PCI_OUT_DWORD(a,v) sysOutLong ((a) + PCI_IO_OFFSET, (v))

89

Page 98: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

90

Page 99: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

USB Peripheral Stack

This chapter documents the USB peripheral stack, which is an extension of the USBDeveloper’s Kit, also known as the USB Kit. The USB peripheral stack interpretsUSB commands on USB devices running VxWorks.

The USB peripheral stack includes the source code for the USB peripheral stackand firmware emulators.

This chapter shows you how to write your own USB target controller driver andUSB target firmware. The USB peripheral stack is designed to allow:

� easy portability to RTOSs other than VxWorks

� fast development of new target controller drivers

� fast development of new target firmware

Tested Devices

The following device has been tested with the Wind River USB peripheral stack:

Philips PDIUSBD12 evaluation kit

91

Page 100: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

2.1 Peripheral Stack Architecture

Figure 2-1 presents an overview of the USB peripheral stack.

At the bottom of the stack is the USB target controller (USB TC), the hardware partof the peripheral that connects to the USB. Many manufacturers build USB targetcontrollers, which vary widely in implementation. The sample code provided byWind River supports an evaluation kit from Philips based on the PhilipsPDIUSBD12 target chip. The PDIUSBD12 is a general purpose USB target chip thatsupports each of the four basic USB transfers: control, interrupt, bulk, andisochronous. In the evaluation kit, the PDIUSBD12 sits on a standalone printedcircuit board; a separate ISA bus adapter card is used to connect the board to astandard PC system.

Figure 2-1 Peripheral Stack Overview

USB Target Application

USB Target Driver(usbTargLib)

USB Target Controller Driver(TCD)

USB Target Controller(USB TC)

usbTargLib Interface

usbTargLib/TCD Interface

Software

Hardware

92

Page 101: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

For each type of target controller, there is a corresponding USB target controllerdriver (TCD). The TCD provides a consistent, abstract view of the target controllerto the upper software layers.

The source for the pre-built Wind River driver for the Philips PDIUSBD12 iscontained in the library usbTcdPhilipsPdiusbd12EvalLib. However, given therange of USB target chips available, there is a good chance a customer does not usethe Philips PDIUSBD12, and even less likely a customer uses the Philips evaluationkit as part of an actual product. You should be prepared to customize or replace thesample USB target controller driver provided with the USB peripheral stack.

Above the TCD sits the usbTargLib library, a hardware-independent module thatprovides an abstract set of services for simplifying the job of writing USB targetapplications. This library incorporates automatic handling, where possible, forUSB requests. When automatic processing is not possible, usbTargLib relies on thetarget application to complete USB transactions.

At run-time, one or more TCDs are attached to usbTargLib. For each TCD, a singletarget application is also registered with usbTargLib; and usbTargLib becomesresponsible for routing requests and responses between the TCD and the targetapplication. Architecturally, usbTargLib is capable of handling multiple TCDs andtheir corresponding target applications. As a practical matter, however, fewperipherals have more than one target controller, TCD, and target application.

At the top of the peripheral stack sits the target application. The target applicationis the module that gives the peripheral its personality. In response to USB requestsreceived by the TCD and routed through usbTargLib, it is the target application’sresponsibility to provide appropriate responses. For example, when a request isreceived to get a USB descriptor from the peripheral, it is the target application’sresponsibility to provide the contents of the descriptor.

Peripheral Module Roadmap

Figure 2-2 illustrates the functional relationships between the modules thatcomprise Wind River’s USB peripheral driver stack.

The peripheral stack shares a consistent architectural approach with the USB hostdriver stack, as well as a number of common libraries. (Compare Figure 2-2 in thissupplement with the figures in 1.2 Architecture Overview, p.5.)

93

Page 102: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Figure 2-2 Peripheral Module Roadmap

usbTargPhilipsD12EvalLib

usbTargPrnLib

usbToolUSB Exerciser Utility

usbTargLib

usbIsaLib or usbPciLib

cmdParser

usbTcdLib

usbTcdPdiusbd12EvalLibPhilips PDIUSBD12 Evaluation Kit

System Hardware(for example, ISA bus controller)

Philips PDIUSBD 12Evaluation Kit

Software

Hardware

ossLib

usbDescrCopyLibusbQueueLibusbHandleLib

usbListLib

usbTargKbdLibUSB Keyboard Emulator

94

Page 103: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

Modules that are unique to the USB peripheral stack are described in this section.For information on modules shared with the host stack, see 1.2 ArchitectureOverview, p.5. For additional information on USB-related libraries andsubroutines, see the associated reference pages in the online VxWorks ReferenceManual: USB Libraries.

usbTool

This module is a test application that exercises both the Wind River USB host andperipheral stacks. The usbTool functions that control the peripheral stack areindependent of those that control the host stack. In fact, if a VxWorks target hasboth USB host and peripheral hardware, usbTool can be used to control bothsimultaneously and the two can talk to one another!

usbTargPhilipsD12EvalLib

The Philips PDIUSBD12 evaluation kit includes a reference firmwareimplementation. This firmware is implemented as a DOS application. Whenrunning, the firmware makes the PDIUSBD12 look like a test device recognizableby a Windows-based Philips test program. The Philips test program allows theuser to exercise certain functions on the PDIUSBD12 evaluation board. TheusbTargPhilipsD12EvalLib module is a target application that emulates thebehavior of the Philips reference firmware. Thus, the Philips test programcommunicates with the PDIUSBD12 evaluation board when the PDIUSBD12 isunder the control of the Wind River USB peripheral stack.

usbTargPrnLib

This module is a very simple (and incomplete) example of a target application thatacts like a USB printer. This module was originally developed to test USB bulktransfers through the PDIUSBD12; its emulation of a printer is not completeenough to allow it to talk to a standard Windows host, for example.

usbTargKbdLib

Like usbTargPrnLib, this module is a very simple and incomplete example of atarget application that acts like a USB keyboard. It was originally developed to testUSB interrupt transfers through the PDIUSBD12.

Taken together, the three libraries (usbTargPhilipsD12EvalLib, usbTargPrnLib,and usbTargKbdLib) are useful principally to demonstrate how simple it is tocreate a target application on top of the usbTargLib interface.

95

Page 104: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

usbTargLib

This module is the core of the USB peripheral stack. It is responsible for routingrequests between TCDs and their corresponding target applications. TheusbTargLib module automatically manages the default control pipe for each TCDand provides default handlers, where meaningful, for each USB control request.This module also incorporates the necessary functions to allow target applicationsto transfer data across the USB, either in response to control requests or on otherUSB pipes.

usbTcdLib

This module provides functions to invoke each of the services provided by a USBTCD. It is used by usbTargLib to communicate with underlying HCDs. Thefunctions in usbTcdLib are not called directly by modules other than usbTargLib.

usbTcdPdiusbd12EvalLib

This module is the TCD for the Philips PDIUSBD12 evaluation kit. Allhardware-dependent code for a target controller is contained in the TCD. EachTCD exports a single entry point, generally with a name of the formusbTcdXxxxExec( ), and all communication with the TCD is performed throughthis function. There is no direct link between usbTargLib and any underlyingTCD; that is, usbTargLib has no prior (compile-time) knowledge of which TCDsare to be loaded in a particular system. Each TCD’s entry point is exposed tousbTargLib during a process called TCD attachment, described in 2.2.2 Attachingand Detaching TCDs, p.98.

usbIsaLib or usbPciLib

This module provides the TCD with an abstract set of ISA bus services, allowingthe TCD to be written independent of variations in the underlying BSP. In the caseof the pcPentium BSP, on which the Wind River USB peripheral stack wasdeveloped and tested, each of the usbIsaLib functions is redirected to acorresponding function in usbPciLib. For a description of usbPciLib, see1.2 Architecture Overview, p.5.

There is no requirement that a particular TCD be written to use usbIsaLib or evenusbPciLib. These modules were designed to promote portability across BSPplatforms. In systems where that is not an issue, developers can freely code“directly to the hardware” in the TCD itself.

96

Page 105: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

2.2 USB Target Driver (usbTargLib)

This section describes typical use of the usbTargLib, activities such asinitialization, TCD attachment, and data transfers. It also discusses key features ofmodule’s internal design.

2.2.1 Initializing usbTargLib

Initializing usbTargLib is a two-step process. First, usbTargLib’s entry point,usbTargInitialize( ), must be called at least once. The usbTargInitialize( ) routineinitializes internal usbTargLib data structures and, in turn, calls the initializationentry points of other modules in the USB driver stack. For a given system, it isacceptable to call usbTargInitialize( ) once (perhaps during the boot sequence) orto call it many times (as during the initialization of each TCD or target application).The usbTargLib driver maintains a usage count that is incremented for eachsuccessful call to usbTargInitialize( ) and decremented for each corresponding callto usbTargShutdown( ). The driver only truly initializes itself when the usagecount goes from zero to one, and it only truly “shuts down” when the usage countreturns to zero.

The following code fragment illustrates the proper initialization and shutdown ofusbTargLib:

...

/* Initialize usbTargLib. */

if (usbTargInitialize () != OK)return ERROR;

...

...

/* target application code. */......

/* Shut down usbTargLib. Note: we only execute this code if the return* code from usbTargInitialize() was OK. Note also that there’s really no* reason to check the result of usbTargShutdown().*/

usbTargShutdown ();

The second step of usbTargLib initialization is to attach at least one TCD to thedriver, using usbTargLib’s usbTargTcdAttach( ) routine. Normally, theattachment of TCDs to usbTargLib happens during the VxWorks boot sequence.

97

Page 106: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

However, usbTargLib is designed to allow TCDs to be attached (and detached) atrun-time. This flexibility allows usbTargLib to support systems in which USBtarget controllers can be “hot-swapped” without restarting the system.

2.2.2 Attaching and Detaching TCDs

You decide when to attach TCDs to usbTargLib and when to detach them, if ever.In most peripheral applications, a single TCD and corresponding targetapplication are attached to usbTargLib during the initial boot sequence andremain attached indefinitely.

In order to attach a TCD to usbTargLib, the caller passes the TCD’s execution entrypoint and a TCD-defined parameter (the TCD attachment parameter) to theusbTargTcdAttach( ) routine. The caller must also provide the address of a callbacktable that identifies key entry points in the target application. The targetapplication’s callback table is described more fully in 2.2.4 Target ApplicationCallback Table, p.100. Finally, the caller provides pointers to variables that receiveinformation about the TCD attachment, including a handle to the attached TCDand information about the USB endpoints supported by the TCD.

In response to the usbTargTcdAttach( ) call, usbTargLib invokes the TCD’sexecution entry point with a TCD_FNC_ATTACH service request, passing it thesame TCD attachment parameter provided by the caller. Use of this TCD-definedparameter can vary, however the Philips PDIUSBD12 example interprets thisparameter as a pointer to a structure of the following form:

typedef struct usb_tcd_pdiusbd12_params{UINT32 ioBase; /* Base I/O address range */UINT16 irq; /* IRQ channel (e.g., 5 = IRQ5) */UINT16 dma; /* DMA channel (e.g., 3 = DMA3) */} USB_TCD_PDIUSBD12_PARAMS, *pUSB_TCD_PDIUSBD12_PARAMS;

For the Philips evaluation kit, the caller must initialize this structure with settingscorresponding to the Philips ISA bus board. For other target systems, these valuescan be hard-coded. The TCD uses the information in this structure to locate andmanage the specified target controller.

The following code fragment demonstrates how to attach the Philips evaluation kitto usbTargLib:

/* Attach the Philips PDIUSBD12 evaluation kit TCD to usbTargLib. */

USB_TCD_PDIUSBD12_PARAMS params;

memset (&params, 0, sizeof (params));

98

Page 107: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

params.ioBase = (UINT32) 0x368;params.irq = (UINT16) 5;params.dma = (UINT16) 7;

if (usbTargTcdAttach (usbTcdPdiusbd12EvalExec, /* TCD’s entry point */(pVOID) &params, /* TCD-specific parameter */callbackTable, /* target app’s callback table */

/* is defined elsewhere */callbackParam, /* target app-specific parameter */&targChannel, /* “handle” returned by usbTargLib */&numEndpoints, /* nbr of endpoints supported by TCD */&pEndpoints,) /* an array of info about endpoints */)

== OK){/* TCD & target application were initialized successfully. *//* Do post-attach processing. */....../* Now enable the TCD. */

if (usbTargEnable (targChannel) != OK){/* Failed to enable TCD. */}

}else

{/* Failed to attach the TCD & initialize the target application. */}

2.2.3 Enabling and Disabling TCDs

In some situations, the target application may not be ready to begin handling USBrequests as soon as it calls usbTargTcdAttach( ). For example, the targetapplication may need to store and process the endpoint information returned byusbTargTcdAttach( ) first. For this reason, usbTargLib provides two additionalfunctions to enable and disable the TCD.

! CAUTION: While usbTargLib and the sample Philips TCD are designed to supportthe dynamic attachment and detachment of TCDs, some Wind River BSPs do notsupport the disconnection of the USB TCD from the underlying interrupt vector, afunction essential to the detaching process. If the vector is subsequentlyre-enabled, the system may attempt to execute a stale interrupt service routine andwill fault.

99

Page 108: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The routine usbTargEnable( ) enables the specified TCD. The TCD, in turn,enables the underlying USB target controller. By convention, the target controllershould not turn on its USB drivers until the TCD has been enabled by callingusbTargEnable( ). Thus, until usbTargEnable( ) has been called, the targetcontroller, and thus the peripheral, is not visible on the USB.

The routine usbTargDisable( ) disables the specified TCD and is generally calledjust before detaching a TCD.

The previous code fragment in 2.2.2 Attaching and Detaching TCDs, p.98 illustratesone use of the usbTargEnable( ) function.

2.2.4 Target Application Callback Table

USB peripherals never initiate activity on the USB1. Instead, all USB activity isinitiated by the USB host. The architecture of the USB peripheral stack reflects thisin the way communication is handled between usbTargLib and the targetapplication. Once the TCD and its associated target application have been attachedto usbTargLib, usbTargLib asynchronously calls back into the target applicationby way of the entry points exposed in the target application’s callback table. Thecallback table takes the following form:

typedef struct usb_targ_callback_table{/* device management callbacks */

USB_TARG_MANAGEMENT_FUNC mngmtFunc;

/* Control pipe callbacks */

USB_TARG_FEATURE_CLEAR_FUNC featureClear;USB_TARG_FEATURE_SET_FUNC featureSet;USB_TARG_CONFIGURATION_GET_FUNC configurationGet;USB_TARG_CONFIGURATION_SET_FUNC configurationSet;USB_TARG_DESCRIPTOR_GET_FUNC descriptorGet;USB_TARG_DESCRIPTOR_SET_FUNC descriptorSet;USB_TARG_INTERFACE_GET_FUNC interfaceGet;USB_TARG_INTERFACE_SET_FUNC interfaceSet;USB_TARG_STATUS_GET_FUNC statusGet;USB_TARG_ADDRESS_SET_FUNC addressSet;USB_TARG_SYNCH_FRAME_GET_FUNC synchFrameGet;USB_TARG_VENDOR_SPECIFIC_FUNC vendorSpecific;

} USB_TARG_CALLBACK_TABLE, *pUSB_TARG_CALLBACK_TABLE;

1. There is one exception: When the USB is in the SUSPEND state, a USB peripheral caninitiate RESUME signaling, as described in 2.2.9 Resume Signaling, p.112.

100

Page 109: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

Before calling the usbTargTcdAttach( ) routine, the function pointers in this tableshould be set to point to corresponding entry points in the target application. Assoon as usbTargTcdAttach( ) is called, usbTargLib begins making asynchronouscalls to the entry points in the callback table. (Some callbacks are immediate andoccur during the attach process itself; others happen in response to activity on theUSB.) The target application should provide pointers for each function whoserequests need software processing. The usbTargLib driver provides defaulthandling for any functions whose corresponding entry in the callback table isNULL.

The prototypes for each of these callbacks are defined in usbTargLib.h. Twoparameters are common to each of the callback functions:

pVOID paramUSB_TARG_CHANNEL targChannel

paramThe application-defined parameter originally passed to usbTargLib as part ofthe usbTargTcdAttach( ) function. Its value is not interpreted by usbTargLib,and it can take on any meaning defined by the target application.

targChannelThe handle assigned to the TCD by usbTargLib during attach processing.

The following sections describe each callback in the callback table in more detail.

mngmtFunc( ) Callback

The target driver usbTargLib invokes the target application’s mngmtFunc( )callback to inform the application of changes that broadly affect the USB’soperation. This callback takes the following form:

typedef STATUS (*USB_TARG_MANAGEMENT_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 mngmtCode /* management code */);

101

Page 110: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The mngmtCode parameter tells the target application what management event hashappened. It takes the following values, as defined in usbTcd.h:

TCD_MNGMT_ATTACH initial TCD attachmentTCD_MNGMT_DETACH TCD detachTCD_MNGMT_VBUS_DETECT bus detectedTCD_MNGMT_VBUS_LOST Vbus lostTCD_MNGMT_BUS_RESET bus resetTCD_MNGMT_SUSPEND suspend signaling detectedTCD_MNGMT_RESUME resume signaling detected

The target application can process or ignore these management codes as it sees fit.In most cases, usbTargLib ignores the status returned by the mngmtFunc( )callback. However, usbTargLib does examine the mngmtFunc( ) return code inresponse to the TCD_MNGMT_ATTACH code. In this case, if the mngmtFunc( )returns ERROR, TCD attachment is aborted.

The target driver provides default handling for the mngmtFunc( ) callback. Thedefault handler always returns OK.

Control Pipe Request Callbacks

The target driver usbTargLib provides default processing for all standard requestsreceived on the peripheral’s default control pipe (endpoint #0). For each of thestandard USB control requests, usbTargLib provides some form of defaultprocessing. The following callbacks can be provided by the target application tomodify default processing.

featureClear( ) and featureSet( ) Callbacks

The target driver usbTargLib invokes the target application’s featureClear( ) andfeatureSet( ) callbacks in response to the USB CLEAR_FEATURE and SET_FEATURErequests, respectively. These callbacks take the following form:

typedef STATUS (*USB_TARG_FEATURE_CLEAR_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 requestType,UINT16 feature,UINT16 index);

102

Page 111: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

typedef STATUS (*USB_TARG_FEATURE_SET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 requestType,UINT16 feature,UINT16 index);

If the target application supports these functions, it should clear or set the featureidentified by the requestType, feature, and index parameters.

If the target application does not provide these callbacks, then usbTargLib returnsan error in response to the corresponding requests. Similarly, if the callbacks returnERROR, usbTargLib returns an error in response to the corresponding request.

configurationGet( ) and configurationSet( ) Callbacks

The target driver usbTargLib invokes the target application’s configurationGet( )and configurationSet( ) callbacks in response to the USB GET_CONFIGURATIONand SET_CONFIGURATION requests. These callbacks take the following form:

typedef STATUS (*USB_TARG_CONFIGURATION_GET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,pUINT8 pConfiguration);

typedef STATUS (*USB_TARG_CONFIGURATION_SET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 configuration);

For the configurationGet( ) callback, the target application should fill thepConfiguration buffer with the UINT8 value identifying the current configuration;usbTargLib transmits the response back to the USB host. For configurationSet( ),the target application should set the current configuration to the value indicatedby configuration.

If the target application does not provide these callbacks, then usbTargLib returnsan error in response to the corresponding requests. Similarly, if the callbacks returnERROR, usbTargLib returns an error in response to the corresponding request.

103

Page 112: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

descriptorGet( ) and descriptorSet( ) Callbacks

The target driver usbTargLib invokes the target application’s descriptorGet( ) anddescriptorSet( ) callbacks in response to the USB GET_DESCRIPTOR andSET_DESCRIPTOR requests. These callbacks take the following form:

typedef STATUS (*USB_TARG_DESCRIPTOR_GET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 requestType,UINT8 descriptorType,UINT8 descriptorIndex,UINT16 languageId,UINT16 length,pUINT8 pBfr,pUINT16 pActLen);

typedef STATUS (*USB_TARG_DESCRIPTOR_SET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 requestType,UINT8 descriptorType,UINT8 descriptorIndex,UINT16 languageId,UINT16 length);

The requestType, descriptorType, descriptorIndex, and languageId parameters identifythe descriptor requested by the USB host. For the descriptorGet( ) callback, thetarget application should fill the pBfr buffer with the requested descriptor (not toexceed the buffer size specified by length). The target application should also setthe pActLen variable to the length of the descriptor placed in pBfr. The target drivertransmits the descriptor back to the USB host.

In the case of descriptorSet( ), the target application must use theusbTargControlPayloadRcv( ) routine (see Control Pipe Data Transfers, p.110) toreceive the descriptor being sent by the USB host, then process it appropriately.

If the target application does not provide these callbacks, usbTargLib returns anerror in response to the corresponding requests. Similarly, if the callbacks returnERROR, usbTargLib returns an error in response to the corresponding request.

104

Page 113: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

interfaceGet( ) and interfaceSet( ) Callbacks

The target driver usbTargLib invokes the target application’s interfaceGet( )) andinterfaceSet( )) callbacks in response to the USB GET_DESCRIPTOR andSET_DESCRIPTOR requests. These callbacks take the following form:

typedef STATUS (*USB_TARG_INTERFACE_GET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 interfaceIndex,pUINT8 pAlternateSetting);

typedef STATUS (*USB_TARG_INTERFACE_SET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 interfaceIndex,UINT8 alternateSetting);

For the interfaceGet( ) callback, the target application should store its currentinterface setting in the variable pAlternateSetting, for the interface specified byinterfaceIndex. For interfaceSet( ), the target application should set its interfaceaccording to the interfaceIndex and alternateSetting parameters.

If the target application does not provide these callbacks, then usbTargLib returnsan error in response to the corresponding requests. Similarly, if the callbacks returnERROR, usbTargLib returns an error in response to the corresponding request.

statusGet( ) Callback

The target driver usbTargLib invokes the target application’s statusGet( ) callbackin response to the USB GET_STATUS request. This callback takes the followingform:

typedef STATUS (*USB_TARG_STATUS_GET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 requestType,UINT16 index,UINT16 length,pUINT8 pBfr,pUINT16 pActLen);

If the target application supports this callback, it should store the appropriatestatus in pBfr (not to exceed the length specified by length). It should also store the

105

Page 114: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

length of the status in pActLen. The target driver sends the status back to the USBhost.

If the target application does not provide this callback, usbTargLib returns an errorin response to GET_STATUS requests. Similarly, if the statusGet( ) callback returnsERROR, then usbTargLib returns an error in response to the correspondingrequest.

addressSet( ) Callback

The target driver usbTargLib invokes the target application’s addressSet( )callback in response to the USB SET_ADDRESS request. This callback takes thefollowing form:

typedef STATUS (*USB_TARG_ADDRESS_SET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 deviceAddress);

The target driver handles the SET_ADDRESS request automatically whether or notthe target application supports this callback. The current implementation ofusbTargLib ignores the STATUS returned by this callback.

synchFrameGet( ) Callback

The target driver usbTargLib invokes the target application’s synchFrameGet( )callback in response to the USB GET_SYNCH_FRAME request. This callback takesthe following form:

typedef STATUS (*USB_TARG_SYNCH_FRAME_GET_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT16 endpoint,pUINT16 pFrameNo);

Typically, this function is used to synchronize isochronous data transfers. If theapplication supports it, then the callback should store the synch frame informationin pFrameNo and return OK. The target driver sends the response to the USB host.

If the target application does not provide this callback, usbTargLib returns an errorin response to GET_SYNCH_FRAME requests. Similarly, if the synchFrameGet( )

106

Page 115: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

callback returns ERROR, usbTargLib returns an error in response to thecorresponding request.

vendorSpecific( ) Callback

All requests received on the peripheral’s default control pipe and not recognizedas standard requests are routed to the target application’s vendorSpecific( )callback, if one is provided. This callback takes the following form:

typedef STATUS (*USB_TARG_VENDOR_SPECIFIC_FUNC)(pVOID param,USB_TARG_CHANNEL targChannel,UINT8 requestType,UINT8 request,UINT16 value,UINT16 index,UINT16 length);

The target application’s handling of vendor-specific requests varies widely. Somevendor-specific requests can require additional data transfer, perhaps usingusbTargLib’s usbTargControlPayloadRcv( ) or usbTargControlResponseSend( )for support. If the target application handles the vendor-specific requestsuccessfully, it should return OK.

If the target application does not provide this callback, usbTargLib returns an errorin response to a vendor-specific request. Similarly, if the vendorSpecific( ) callbackreturns ERROR, usbTargLib returns an error in response to the correspondingrequest.

2.2.5 TCD Endpoints

In response to the usbTargTcdAttach( ) routine, usbTargLib returns the number ofendpoints supported by the target and a pointer to an array describing eachendpoint. Each entry in this array takes the following form:

typedef struct usb_targ_endpoint_info{UINT16 endpointId; /* TCD-assigned endpoint ID */UINT16 flags; /* endpoint characteristics */

UINT16 endpointNumMask; /* mask of allowed endpoint numbers */

UINT32 ctlMaxPacketSize; /* max packet size in control mode */UINT32 bulkInMaxPacketSize; /* max packet size in bulk IN mode */UINT32 bulkOutMaxPacketSize; /* max packet size in bulk OUT mode */

107

Page 116: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

UINT32 bulkInOutMaxPacketSize; /* max packet size in bulk I/O mode */

UINT32 intInMaxPacketSize; /* max packet size in intrpt IN mode */UINT32 intOutMaxPacketSize; /* max packet size in intrpt OUT mode */UINT32 intInOutMaxPacketSize; /* max packet size in intrpt I/O mode */UINT32 isochInMaxPacketSize; /* max packet size in isoch IN mode */UINT32 isochOutMaxPacketSize; /* max packet size in isoch OUT mode */UINT32 isochInOutMaxPacketSize; /* max packet size in isoch I/O mode */

UINT16 endpointNum; /* currently assigned endpoint num */UINT16 configuration; /* current configuration */UINT16 interface; /* current interface */UINT16 transferType; /* current transfer type */UINT16 direction; /* current direction */

UINT16 maxPacketSize; /* max packet size as configured */

} USB_TARG_ENDPOINT_INFO, *pUSB_TARG_ENDPOINT_INFO;

The purpose of this structure is to give TCDs, and thus usbTargLib, a way todescribe the endpoint capabilities of a particular TCD and target controller in ahardware-independent manner. The target application should treat this structureas read-only. Its fields are defined as follows:

endpointIdAn arbitrary endpoint ID number assigned by the TCD to a particularendpoint.

flagsA description of the capabilities of the endpoint, as follows:

TCD_ENDPOINT_IN_OK host->device capableTCD_ENDPOINT_OUT_OK device->host capableTCD_ENDPOINT_CTRL_OK capable of control xfrTCD_ENDPOINT_BULK_OK capable of bulk xfrTCD_ENDPOINT_INT_OK capable of interrupt xfrTCD_ENDPOINT_ISOCH_OK capable of isoch xfrTCD_ENDPOINT_IN_USE endpoint has pipe

endpointNumMaskA bit-vector identifying the endpoint numbers that can be supported by theendpoint. For example, if bit 0 is “1”, the endpoint can be endpoint 0. If bit 1 is“1”, the endpoint can be endpoint 1. And so on.

xxxMaxPacketSizeThese fields define the maximum packet size supported by the endpoint whenenabled as a control, bulk, interrupt, or isochronous endpoint.

108

Page 117: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

endpointNumThe endpoint number currently assigned to this endpoint.

configurationinterface

The configuration and interface with which this endpoint is currentlyconfigured.

transferTypedirection

Similar to configuration and interface, the endpoints transfer type and direction,as USB_XFRTYPE_xxxx and USB_DIR_xxxx.

maxPacketSizeThe maximum packet size as currently configured.

While this abstract endpoint structure permits target applications to be writtenwithout prior knowledge of the capabilities of the underlying TCD and targetcontroller, many target application developers are likely to bypass this abstractionand code their target applications to use specific endpoints based on theirknowledge of the underlying hardware’s capability.

2.2.6 Data Transfer

All data transfers on a USB are initiated by the USB host. In general, a host createsa pipe—in other words, a connection—to a specific endpoint on a given peripheral.In addition to the address of the peripheral and the endpoint number, the pipe hasother characteristics, such as the data type (control, bulk, interrupt, orisochronous), direction, and perhaps information describing the bandwidthrequired by the pipe. Having created a pipe, the USB host application requests datatransfers by formatting IRPs (I/O request packets) and submitting them to the USBdriver (called the USBD in the Wind River USB host stack).

The Wind River USB peripheral stack functions similarly. A target applicationcreates pipes and attaches them to specific endpoints supported by the TCD andtarget controller. Pipes are created and destroyed using the routinesusbTargPipeCreate( ) and usbTargPipeDestroy( ). As described further in ControlPipe Data Transfers, p.110, usbTargLib automatically creates the pipe for the defaultcontrol endpoint (endpoint #0); so the target application itself omits the pipecreation step for the default control pipe.

109

Page 118: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

After creating the necessary pipes, the target application formats USB_ERPs (USBendpoint request packets) which describe data to be transferred. When the USBhost requests a transfer to or from a specific target endpoint, the USB peripheralstack responds by transferring data to or from USB_ERPs provided by the targetapplication. USB_ERPs take the following form:

typedef struct usb_erp{LINK targLink; /* link field used internally by usbTargLib */pVOID targPtr; /* ptr field for use by usbTargLib */LINK tcdLink; /* link field used internally by USB TCD */pVOID tcdPtr; /* ptr field for use by USB TCD */pVOID userPtr; /* ptr field for use by client */UINT16 erpLen; /* total length of ERP structure */int result; /* ERP completion result: S_usbTcdLib_xxxx */ERP_CALLBACK targCallback; /* usbTargLib completion callback routine */ERP_CALLBACK userCallback; /* client's completion callback routine */UINT16 endpointId; /* device endpoint */UINT16 transferType; /* type of ERP: control, bulk, etc. */UINT16 dataToggle; /* ERP should start with DATA0/DATA1. */UINT16 bfrCount; /* indicates count of buffers in BfrList */USB_BFR_LIST bfrList [1];} USB_ERP, *pUSB_ERP;

There are numerous similarities between this data structure and the USB_IRP usedby the Wind River USB host stack. The USB_BFR_LIST structure in the USB_ERP isidentical to the one included as part of the USB_IRP.

As with the USB host stack, the USB peripheral stack automatically manages thedataToggle for ERPs; thus, the target application is not required to keep track of thecurrent state of DAT0 and DATA1 for each pipe.

Control Pipe Data Transfers

The usbTargLib driver automatically manages communication on the defaultcontrol pipe (endpoint #0), making it unnecessary for the target application tocreate a pipe for this particular endpoint. However, this also means that the targetapplication has no direct access to the default control pipe. For this reason,

NOTE: By convention, the direction of a particular pipe is always viewed from theUSB host’s perspective; so, a pipe that transfers data from the host to the peripheralhas a direction of USB_DIR_OUT (even though the peripheral sees the data asincoming). Similarly, a pipe that transfers data from the peripheral to the host hasa direction of USB_DIR_IN.

110

Page 119: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

usbTargLib provides two routines that allow the target application to transfer datathrough the default control pipe:

usbTargControlResponseSend( )Send control pipe responses to the USB host.

usbTargControlPayloadRcv( )Receive additional control pipe payloads from the USB host.

Unlike the general data transfer routines (see General Data Transfers, p.111), theseroutines take as parameters only the TCD handle and a pointer to a USB_ERP. TheTCD handle uniquely identifies the default control pipe, because there can only beone default control pipe for each TCD and target controller

Target applications typically use these routines when servicing USB requests likeGET_DESCRIPTOR and SET_DESCRIPTOR, or when servicing vendor-specificrequests.

General Data Transfers

In order to perform data transfers that do not involve the default control pipe, thetarget application must first create pipes as described 2.2.6 Data Transfer, p.109. Inresponse to a request to create a pipe, usbTargLib returns a USB_TARG_PIPEhandle to the target application. The target application must use this handle toidentify the correct pipe in subsequent calls to usbTargTransfer( ) andusbTargTransferAbort( ).

The target application passes a USB_TARG_PIPE handle and a formatted USB_ERPto usbTargTransfer( ) to request a data transfer. The usbTargTransferAbort( )routine allows previously submitted transfers to be aborted.

2.2.7 Setting Endpoint Stall

When the target application detects certain error conditions, it may wish to set aparticular endpoint to the STALLed state. The STALL state is an indication to theUSB host that an error has been detected.

The target driver usbTargLib provides the routine usbTargPipeStatusSet( ) whichallows the target application to set the state of a pipe as STALLed or unSTALLed.In addition, this routine allows the target application to reset the next expecteddata toggle for the endpoint to DATA0, as may happen after the target receivesother commands from the USB host, perhaps on the default control pipe.

111

Page 120: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The target application cannot set the STALL or unSTALL state directly for thedefault control pipe. The usbTargLib driver automatically sets the default controlpipe to the STALL state whenever an error is detected in the processing of a requeston the default control pipe. The target driver automatically unSTALLs the defaultcontrol pipe whenever a new SETUP packet is received, as required by the USBSpecification.

For more information on the STALL state, see the USB Specification.

2.2.8 Bus Frame Number

Certain target applications need to determine the current USB frame number—generally those implementing isochronous data transfers. The usbTargLib driverprovides the routine usbTargCurrentFrameGet( ) for this purpose.

2.2.9 Resume Signaling

Some target applications need to be able to drive USB RESUME signaling on thebus in order to “wake up” the USB host. In some systems, the USB is set to theSUSPEND state when the USB host enters a low-power mode; some devices (forexample, keyboards) will want the ability to “wake up” the host from thelow-power mode.

The usbTargLib driver provides the usbTargSignalResume( ) routine whichallows a peripheral to drive RESUME signaling. This routine has no effect if thebus is not in the SUSPEND state; and there is no guarantee that a particular hostwill respond to USB RESUME signaling.

2.3 USB Target Controller Driver

This section describes the TCD interface and its requirements, informationessential for creating a TCD for a target controller not already supported by WindRiver.

112

Page 121: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

2.3.1 TCD Header File

All TCDs implement the interface as defined in usbTcd.h.

2.3.2 TCD Entry Point

Each TCD exports a single entry point, its execution entry point. This function is ofthe following form:

typedef STATUS (*USB_TCD_EXEC_FUNC) (pVOID pTrb);

2.3.3 Target Request Block (TRB)

All requests to the TCD are made by constructing Target Request Blocks (TRB) andpassing them to the TCD’s execution entry point for processing. TRBs begin witha common header that is followed by parameters unique to the function beingexecuted. The format of the header is:

typedef struct trb_header{TCD_HANDLE handle; /* I/O: caller's TCD client handle */UINT16 function; /* IN: TCD function code */UINT16 trbLength; /* IN: Length of the total TRB */} TRB_HEADER, *pTRB_HEADER;

For the TCD_FNC_ATTACH request (see also TCD_FNC_ATTACH, p.114), thehandle field is returned by the TCD to usbTargLib. For all other TRB requests, thehandle field is passed by usbTargLib to the TCD.

The function field in TRB_HEADER defines one of the following functions as theTCD function to be executed:

A TCD must implement all of the above functions in order to perform properly.

The trbLength field is set by the caller to be the total length of the TRB, includingthe header and any additional parameters that follow. Each of the TCD functions

TCD_FNC_ATTACH TCD_FNC_DETACHTCD_FNC_ENABLE TCD_FNC_DISABLETCD_FNC_ADDRESS_SET TCD_FNC_ENDPOINT_ASSIGNTCD_FNC_ENDPOINT_RELEASE TCD_FNC_SIGNAL_RESUMETCD_FNC_ENDPOINT_STATE_SET TCD_FNC_CURRENT_FRAME_GETTCD_FNC_ERP_SUBMIT TCD_FNC_ERP_CANCEL

113

Page 122: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

listed above, including any associated TRB, is described in the remainder of thissection.

TCD_FNC_ATTACH

This function is contained in the following TRB:

typedef struct trb_attach{TRB_HEADER header; /* TRB header */pVOID tcdParam; /* IN: TCD-specific parameter */USB_TCD_MNGMT_CALLBACK mngmtCallback;

/* IN: caller's management callback */pVOID mngmtCallbackParam; /* IN: param to mngmt callback */UINT16 speed; /* OUT: target speed: USB_SPEED_xxxx */UINT16 numEndpoints; /* OUT: number of endpoints supported */pUSB_TARG_ENDPOINT_INFO pEndpoints;

/* OUT: ptr to array of endpoints */} TRB_ATTACH, *pTRB_ATTACH;

In response to a TCD_FNC_ATTACH request, a TCD initializes a single USB targetcontroller.

The usbTargLib driver invokes the TCD’s TCD_FNC_ATTACH function whenusbTargTcdAttach( ) is called. Unlike other TCD functions, usbTargLib does notstore an existing TCD_HANDLE in the TRB_HEADER.handle field. Instead, uponsuccessful completion of this routine, the TCD is expected to store a newly createdTCD_HANDLE in the TRB_HEADER.handle field so it can be retrieved byusbTargLib. The usbTargLib driver uses the newly created TCD_HANDLE toidentify the indicated target controller in subsequent calls to the TCD. Typically,the TCD casts the newly created TCD_HANDLE as a pointer to an internal TCDdata structure used to manage a specific target controller.

The TCD-defined parameter—originally passed to the usbTargTcdAttach( )routine—is passed to the TCD in the tcdParam field. The usbTargLib driver makesno attempt to interpret the meaning of this parameter. The TCD can use thetcdParam field as needed; for example, the Philips PDIUSBD12 TCD provided byWind River casts this parameter to a pointer to a USB_TCD_PDIUSBD12_PARAMSstructure (defined in usbTcdPdiusbd12EvalLib.h).

The mngmtCallback parameter is a pointer to a routine in usbTargLib that shouldbe called asynchronously by the TCD when it detects certain USB management

NOTE: The TCD should not enable the controller until usbTargLib invokes theTCD’s TCD_FNC_ENABLE request (see TCD_FNC_ENABLE, p.115).

114

Page 123: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

events. Each time the TCD invokes the routine pointed to by usbTargLib’smngmtCallback parameter, the TCD passes the value specified bymngmtCallbackParam.

Upon completion, the TCD returns three values:

speedThe speed of the USB peripheral hardware, defined as USB_SPEED_xxxx.

numEndpointsThe number of endpoints supported by the target controller.

pEndpointsA pointer to an array of USB_TARG_ENDPOINT_INFO structures, as discussedin 2.2.5 TCD Endpoints, p.107.

TCD_FNC_DETACH

This function is contained in the following TRB:

typedef struct trb_detach{TRB_HEADER header; /* TRB header */} TRB_DETACH, *pTRB_DETACH;

In response to a TCD_FNC_DETACH request, the TCD disables the target controllerhardware and release all resources allocated on behalf of the controller.

TCD_FNC_ENABLE

This function is contained in the following TRB:

typedef struct trb_enable_disable{TRB_HEADER header; /* TRB header */} TRB_ENABLE_DISABLE, *pTRB_ENABLE_DISABLE;

As described in 2.2.3 Enabling and Disabling TCDs, p.99, usbTargLib separates theattachment and enabling of a target controller into two steps. In response to theTCD_FNC_ENABLE request, the TCD enables the target controller’s I/O drivers,making the peripheral visible on the USB (assuming it is currently connected to aUSB).

115

Page 124: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

By default, the target controller must respond to bus address 0 immediately afterTCD_FNC_ENABLE.

TCD_FNC_DISABLE

This function shares the TRB used by TCD_FNC_ENABLE (seeTCD_FNC_ENABLE, p.115).

In response to the TCD_FNC_DISABLE, the TCD disables the target controller’sI/O drivers, in effect making the peripheral disappear from the USB to which it isattached. This function is generally requested only if the target application is in theprocess of shutting down.

TCD_FNC_ADDRESS_SET

This function is contained in the following TRB:

typedef struct trb_address_set{TRB_HEADER header; /* TRB header */UINT16 deviceAddress; /* IN: new device address */} TRB_ADDRESS_SET, *pTRB_ADDRESS_SET;

In response to the TCD_FNC_ADDRESS_SET function, the TCD sets the targetcontroller to begin responding to a new USB device address as specified bydeviceAddress. Once the peripheral is enumerated by the USB host, the USB hostassigns it a new address. The usbTargLib driver interprets the USB SET_ADDRESSrequest sent by the USB host and invokes the TCD_FNC_ADDRESS_SET request tochange the target controller’s address.

TCD_FNC_ENDPOINT_ASSIGN

This function is contained in the following TRB:

typedef struct trb_endpoint_assign{TRB_HEADER header; /* TRB header */UINT16 endpointId; /* IN: TCD-assigned endpoint ID */UINT16 endpointNum; /* IN: newly assigned endpoint num */UINT16 configuration; /* IN: new configuration */UINT16 interface; /* IN: new interface */UINT16 transferType; /* IN: new transfer type */

116

Page 125: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

UINT16 direction; /* IN: new direction */} TRB_ENDPOINT_ASSIGN, *pTRB_ENDPOINT_ASSIGN;

In response to the TCD_FNC_ENDPOINT_ASSIGN request, the TCD enables theindicated hardware point as specified:

endpointIdThe TCD-assigned ID for the desired endpoint. This parameter should matchthe endpoint ID of an endpoint described in the TCD’s endpoint array—apointer to which was originally returned during TCD_FNC_ATTACHprocessing.

endpointNumThe USB endpoint number which should be assigned to this endpoint. SomeUSB target controllers have flexibility in assigning endpoint numbers tophysical endpoints, others do not. The number passed in endpointNumcorresponds to one of the bits set in the endpointNumMask field of theendpoint’s corresponding USB_TARG_ENDPOINT_INFO structure.

configurationinterface

The configuration and interface associated with this endpoint. The TCD doesnot need to interpret these values, but they should be stored by the TCD in theUSB_TARG_ENDPOINT_INFO structure corresponding to the endpoint.

transferTypedirection

The type of transfers that are performed on this endpoint and the direction ofthose transfers, as USB_XFRTYPE_xxxx and USB_DIR_xxxx, respectively.

The usbTargLib driver invokes this request when creating new pipes.

TCD_FNC_ENDPOINT_RELEASE

This function is contained in the following TRB:

typedef struct trb_endpoint_release{TRB_HEADER header; /* TRB header */UINT16 endpointId; /* IN: TCD-assigned endpoint Id */} TRB_ENDPOINT_RELEASE, *pTRB_ENDPOINT_RELEASE;

In response to the TCD_FNC_ENDPOINT_RELEASE request, the TCD disables theendpoint specified by endpointId.

117

Page 126: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

The usbTargLib driver invokes this request when destroying pipes.

TCD_FNC_SIGNAL_RESUME

This function is contained in the following TRB:

typedef struct trb_signal_resume{TRB_HEADER header; /* TRB header */} TRB_SIGNAL_RESUME, *pTRB_SIGNAL_RESUME;

In response to the TCD_FNC_SIGNAL_RESUME request, the TCD directs the targetcontroller to begin driving RESUME signaling on the USB. If the USB is notcurrently in the SUSPEND state, this request has no effect.

TCD_FNC_ENDPOINT_STATE_SET

This function is contained in the following TRB:

typedef struct trb_endpoint_state_set{TRB_HEADER header; /* TRB header */UINT16 endpointId; /* IN: endpoint Id */UINT16 state; /* IN: TCD_ENDPOINT_xxxx bitmask */} TRB_ENDPOINT_STATE_SET, *pTRB_ENDPOINT_STATE_SET;

In response to the TCD_FNC_ENDPOINT_STATE_SET function, the TCD sets thestate of the endpoint, specified by endpointId. The state parameter is a bit mask ofthe following values:

TCD_ENDPOINT_STALLSet the STALL state for a specified endpoint.

TCD_ENDPOINT_UNSTALLClear the STALL state for a specified endpoint.

TCD_ENDPOINT_DATA0Direct the TCD to reset the target controller to DATA0 for a specifiedendpoint.

118

Page 127: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

TCD_FNC_CURRENT_FRAME_GET

This function is contained in the following TRB:

typedef struct trb_current_frame_get{TRB_HEADER header; /* TRB header */UINT16 frameNo; /* OUT: current frame number */} TRB_CURRENT_FRAME_GET, *pTRB_CURRENT_FRAME_GET;

In response to the TCD_FNC_CURRENT_FRAME_GET request, the TCD returns thecurrent USB frame number in frameNo.

TCD_FNC_ERP_SUBMIT

This function is contained in the following TRB:

typedef struct trb_erp_submit{TRB_HEADER header; /* TRB header */pUSB_ERP pErp; /* IN: ptr to IRP */} TRB_ERP_SUBMIT, *pTRB_ERP_SUBMIT;

In response to the TCD_FNC_ERP_SUBMIT request, the TCD queues the specifiedUSB_ERP for subsequent transfer on one of the target controller’s endpoints.USB_ERPs are described in 2.2.6 Data Transfer, p.109.

TCD_FNC_ERP_CANCEL

This function is contained in the following TRB:

typedef struct trb_erp_cancel{TRB_HEADER header; /* TRB header */pUSB_ERP pErp; /* IN: ptr to IPR to be canceled */} TRB_ERP_CANCEL, *pTRB_ERP_CANCEL;

In response to the TCD_FNC_ERP_CANCEL request, the TCD attempts to cancel thespecified USB_ERP. If the USB_ERP can be canceled, the TCD must set the ERP’sresult to S_usbTcdLib_ERP_CANCELED.

119

Page 128: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

2.3.4 TCD Management Events

The management callback to the TCD provided by usbTargLib as part of theTCD_FNC_ATTACH request gives the TCD a way to notify usbTargLib when theTCD detects asynchronous management events. The format of the callback is:

typedef VOID (*USB_TCD_MNGMT_CALLBACK)(pVOID mngmtCallbackParam, /* caller-defined param */TCD_HANDLE handle, /* channel */UINT16 mngmtCode /* management code */);

The mngmtCallbackParam parameter passed to the callback is theTRB.mngmtCallbackParam value originally passed to the TCD during theTCD_FNC_ATTACH request. The handle parameter is the TCD-assignedTCD_HANDLE for the corresponding target controller.

The values for mngmtCode are the same as those introduced in the description ofthe mngmtFunc( ) callback in mngmtFunc( ) Callback, p.101. The usbTargLib driverprocesses some of these events internally. Generally, usbTargLib passes allmanagement events up to the target application through the target application’smngmtFunc( ) callback.

2.3.5 TCD Error Reporting Conventions

A number of standard TCD error codes are defined in usbTcd.h. You areencouraged to use the existing TCD error codes when creating new TCDs. Theseerror codes are returned both in response to TCD function requests through theTCD’s execution entry point, as well as in the result field of each USB_ERPprocessed by the TCD. To conform to Wind River conventions, the TCD shouldalso set the system errno whenever returning an error. TCDs return the standardVxWorks constant, OK, when a function or ERP completes successfully. TCD errorcodes are as follows:

S_usbTcdLib_BAD_PARAM S_usbTcdLib_BAD_HANDLES_usbTcdLib_OUT_OF_MEMORY S_usbTcdLib_OUT_OF_RESOURCESS_usbTcdLib_NOT_IMPLEMENTED S_usbTcdLib_GENERAL_FAULTS_usbTcdLib_NOT_INITIALIZED S_usbTcdLib_INT_HOOK_FAILEDS_usbTcdLib_HW_NOT_READY S_usbTcdLib_NOT_SUPPORTEDS_usbTcdLib_ERP_CANCELED S_usbTcdLib_CANNOT_CANCELS_usbTcdLib_SHUTDOWN S_usbTcdLib_DATA_TOGGLE_FAULTS_usbTcdLib_PID_MISMATCH S_usbTcdLib_COMM_FAULTS_usbTcdLib_NEW_SETUP_PACKET

120

Page 129: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

In particular, TCDs must store the error code S_usbTcdLib_ERP_CANCELED in theresult field of USB_ERPs that have been canceled for any reason. Higher layers relyon this error code to recognize situations in which ERPs should not be retried. Fortheir own convenience, TCDs can temporarily store other values in the USB_ERPresult field while processing ERPs (such as a value indicating that the ERP ispending). However, before invoking an ERP’s completion callback routine, theTCD is required to store either the constant OK or one of the above error codes inthe USB_ERP result field.

2.4 Installing the USB Peripheral Stack

See the Tornado Getting Started Guide for general instructions on how to install theUSB Kit, and all other Wind River products.

The peripheral stack supplement to the USB Kit implements an exampleperipheral stack based on the Philips PDIUSBD12 USB controller chip. Included inthe supplement are the firmware templates used to implement a rudimentarykeyboard, a rudimentary printer, and a device called a PDIUSBD12 firmwareemulator. This latter template was developed to utilize the Windows applicationincluded with the Philips PDIUSBD12 evaluation kit. The other two modules aredesigned as skeletons for creating either a printer or keyboard device. Together, thethree modules demonstrate how three types of USB transfers (control, bulk, andinterrupt) should be implemented.

The PDIUSBD12 firmware emulator is tested with a Windows 98 USB host usingthe application included with the Philips evaluation kit. The printer and keyboardemulator are tested on a VxWorks USB host using the test application usbTool.

Install the USB CD-ROM on top of your current Tornado installation. If youalready have the USB Developer’s Kit for the host installed, you only have toinstall the peripheral stack supplement:

– USB Peripheral Library Source

If you are installing both the host stack source and libraries, as well as theperipheral stack supplement, you must install the above module and the followingthree parts:

– USB Library Source

– USB Support Library: i86

– USB Support Library: ppc

121

Page 130: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

For additional information about installation of the USB host stack, see 1. USB HostStack and the USB Developer’s Kit Release Notes. The remainder of this sectioncontains information pertaining to installation of the peripheral stack only.

Source files related to the peripheral stack are created in the Tornado tree asfollows. The header files for both host and peripheral stacks are installed:

target/h/usbHeader files pertaining to the USBD and the OS abstraction module.

target/h/drv/usbHeader files pertaining to the device drivers (printer, mouse, keyboard) andhost controller drivers (OHCI, UHCI).

target/h/usb/targetHeader files pertaining to the target stack

target/h/drv/usb/targetHeader files pertaining to the peripheral stack firmware templates (printer,keyboard, Philips PDIUSBD12 evaluation kit) and target controller drivers(Philips PDIUSBD12 evaluation kit).

target/src/usbSource files pertaining to the OS abstraction module.

target/src/usb/toolsSource files pertaining to usbTool, a test utility that exercises the USB andsupported devices.

target/src/usb/targetSource files pertaining to the target stack.

target/src/drv/usb/targetSource files pertaining to the peripheral stack firmware templates (printer,keyboard, Philips PDIUSBD12 evaluation kit) and target controller drivers(Philips PDIUSBD12 evaluation kit).

target/config/comps/srcSource files (configlettes) for all Tornado components associated with theperipheral stack and requiring initialization, that is, stubs for BSP-specific PCIroutines, and usbTool.

122

Page 131: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

target/config/bspThe BSP-specific component description files (.cdf) are contained in thefollowing directory:

– pcPentium

target/config/comps/vxworksThe component description file (.cdf) is contained here. For more informationabout components, see the Tornado BSP Developer’s Kit for VxWorks User’sGuide, Tornado 2.0: Components.

Because this is a source code product, object files are not created duringinstallation. The CD-ROM image has no binaries on it. To be able to use theperipheral stack components mentioned above to create a bootable VxWorksimage, you must build the .o files from the command line, as follows:

make CPU=PENTIUM release

The following directories must be built:

tornado/target/src/usb/target

tornado/target/src/usb/tools

tornado/target/src/drv/usb/target

tornado/target/src/usb

The makefiles put object modules in the following directories:

target/lib/obj80386gnuvx

target/lib/obj80486gnuvx

target/lib/objPENTIUMgnuvx

The object files are also linked into their corresponding archive (.a) files in thetarget/lib directory.

123

Page 132: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

2.5 Running the USB Peripheral Stack

After installing the USB peripheral stack, you can run it as a peripheral stack aloneor in conjunction with the host stack.

Regardless of whether you are running the peripheral stack independently or withthe host stack, there are two ways to use the Tornado project facility to configureand download projects:

� Create a downloadable VxWorks image with the USB peripheral stack built in.

� Create a downloadable application module for the USB peripheral stack thatruns on top of an already loaded VxWorks image.

2.5.1 Creating a Downloadable VxWorks Image Including USB

From the Tornado project facility, start a downloadable VxWorks project based onyour BSP. The peripheral stack supplement software provides components thatsupport USB peripheral device functionalities.

For general instructions on using the project facility and creating projects, see theTornado User’s Guide: Projects.

The following steps configure a basic USB peripheral stack setup:

Step 1: Configure the Peripheral Stack

Select the USB Peripheral Stack component from the project facility componenthierarchy to provide support for the Philips PDIUSBD12 target controller.

Step 2: Configure usbTool

Select the usbTool component to include the usbTool module, which allows you toexercise the peripheral stack and its features, as well as the USB’s host functions.For information about using usbTool, see 2.6 Working with usbTool, p.125.

Step 3: Configure Peripheral Devices

Select any of the following peripheral stack device components to include theircorresponding firmware modules. These components require the peripheral stackto be present on the image:

– D12 Emulator– Keyboard Emulator– Printer Emulator

124

Page 133: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

2.5.2 Creating a Downloadable USB Application

To create a downloadable USB application module, follow the standard proceduredescribed in the Tornado User’s Guide: Projects. See that document for details.

2.6 Working with usbTool

The peripheral stack supplement includes a utility called usbTool, which you canuse to exercise the modules comprising the USB peripheral stack. For example, ifyou are implementing a different firmware module, you can use usbTool toexercise and debug your code.

The usbTool utility provides a code skeleton which you can customize to suit yourtest needs.

There are two methods for running usbTool:

� from the shell, on both UNIX and Windows hosts

� from the debugger, Windows only

For more information about how to run usbTool, see 1. USB Host Stack.

This section focuses on using usbTool to exercise the USB peripheral stack.

The usbTool Execution Sequence

NOTE: The keyboard firmware emulator requires two hosts for testing: a VxWorkshost running the emulator (with or without the USB host stack configured) and aVxWorks/USB host. Whereas testing a printer can occur on a single machinerunning both a VxWorks/USB host stack and the USB peripheral stack (configuredas a printer.)

NOTE: To test the keyboard and printer, you must use Wind River’simplementation of a USB host with usbTool.

125

Page 134: Usb Developers Kit Programmers Guide 1.1.2 (1)

USB Developer’s Kit 1.1.2Programmer’s Guide

Use the usbTool utility to initialize and test peripheral stack devices:

1. To initialize the USB peripheral stack as a specific type of device, at theusbTool prompt, enter the targInit command followed by the emulator type(prn, kbd, D12).

2. Depending on the type of device you emulate, you must also include theappropriate driver—either a Wind River USB host stack driver for the printerand keyboard, or a Windows 98 driver for the Philips PDIUSBD12 emulator.For more information about using printers and keyboards, see 1. USB HostStack. For information on using the Philips PDIUSBD12 emulator, see thePDIUSBD12 Evaluation Board (PC Kit) User’s Manual, Rev. 2.1.

3. To test the printer and keyboard, use the usbTool commands in Table 2-1.

To test the PDIUSBD12 emulator, you must use a Windows 98 host and theapplication included with the Philips PDIUSBD12 evaluation kit.

Table 2-1 lists the usbTool commands available when their associated devicecomponents are included in your VxWorks image:

Table 2-1 usbTool Commands

Device Type Command Description

Keyboard emulator kbdReport Generate a keyboard report to send to the host.This command simulates a keypress on an actualkeyboard.

Printer emulator prnDump Typically the host uses the usbTool commandprint4k to send 4KB of arbitrary data to theprinter. This command displays those bytes thathave been sent to the printer.

NOTE: Selecting any of the peripheral device components (keyboard, printer, D12)includes the peripheral device test commands into usbTool. If the components arenot included, the commands are not available.

NOTE: Command names do not have to be fully entered to be executed. Forexample, usbInit can be entered as usbi.

126

Page 135: Usb Developers Kit Programmers Guide 1.1.2 (1)

2

2USB Peripheral Stack

2.7 BSP-Specific Issues

The following run-time issue has been encountered with the pcPentium BSP.

pcPentium

When using a serial connection to your target, the PC_CONSOLE component mustbe removed from your image. (Figure 2-3 shows the location of the PC_CONSOLEcomponent.)

Figure 2-3 PC_CONSOLE Component Location

127