USB Drivers - PowerPoint PPT Presentation

1 / 87
About This Presentation
Title:

USB Drivers

Description:

allows a single urb to define a number of isochronous transfers at once ... specifies a isochronous OUT endpoint for the specified USB device with the ... – PowerPoint PPT presentation

Number of Views:254
Avg rating:3.0/5.0
Slides: 88
Provided by: csF2
Learn more at: http://www.cs.fsu.edu
Category:

less

Transcript and Presenter's Notes

Title: USB Drivers


1
USB Drivers
  • Ted Baker ? Andy Wang
  • COP 5641 / CIS 4930

2
USB Device Basics
  • Universal Serial Bus (USB) is a connection
    between a host computer and a number of
    peripheral devices
  • Created to replace a wide range of slow buses
    (parallel, serial, and keyboard connections)
  • Can support up to 480MB/s in theory
  • A tree built out of several point-to-point links
  • Links are four-wire cables (ground, power, and
    two signal wires)

3
USB Device Basics
  • A USB device can never start sending data without
    first being asked by the host controller
  • Single-master implementation
  • Host polls various devices
  • A device can request a fixed bandwidth (for audio
    and video I/O)

4
USB Device Basics
  • USB protocol defines a set of standards that any
    device can follow
  • If a device falls into one of the predefined
    classes and follows that standard, no need to
    write a special device driver
  • Predefined classes storage devices, keyboards,
    mice, joysticks, network devices, and modems
  • No defined standard for video devices and
    USB-to-serial devices
  • A driver is needed for every device

5
USB Device Basics
  • Linux supports two types of USB drivers
  • Drivers on a host system
  • Control the USB devices that are plugged into it
  • Drivers on a device (USB gadget drivers)
  • Control how that single device looks to the host
    computer as a USB device

6
USB Device Basics
7
USB Device Basics
USB drivers bind to interfaces, not the device
8
Endpoints
  • The most basic form of USB communication is
    through an endpoint
  • Carries data in one direction
  • From the host to device (OUT endpoint)
  • From the device to the host (IN endpoint)

9
Endpoints
  • Four endpoint types
  • CONTROL
  • Used for configuring the device, retrieving
    information and status about the device, or
    sending commands to the device
  • Every device has a control endpoint called
    endpoint 0
  • Used by USB core to configure the device at
    insertion time
  • Transfers are guaranteed with reserved bandwidth

10
Endpoints
  • INTERRUPT
  • Transfer small amounts of data at a fixed rate
  • For USB keyboards and mice
  • Also used to control the device
  • Not for large transfers
  • Guaranteed reserved bandwidth

11
Endpoints
  • BULK
  • Transfer large amounts of data
  • No data loss
  • Not time guaranteed
  • A BULK packet might be split up across multiple
    transfers
  • Used for printers, storage, and network devices

12
Endpoints
  • ISOCHRONOUS
  • Transfer large amount of data
  • No guarantees (potential data loss)
  • For real-time data collections, audio and video
    devices
  • Control and bulk endpoints are used for
    asynchronous data transfers
  • Interrupt and isochronous endpoints are periodic
    with reserved bandwidth

13
Endpoints
  • Endpoint information is located in struct
    usb_endpoint_descriptor (embedded in struct
    usb_host_endpoint)
  • Some important fields
  • bEndpointAddress (8-bit)
  • Use USB_DIR_OUT and USB_DIR_IN bit masks to
    determine the direction of data flow

14
Endpoints
  • bmAttributes
  • Type of the endpoint
  • USB_ENDPOINT_XFERTYPE_MASK to determine if the
    endpoint is of type USB_ENDPOINT_XFER_ISOC,
    USB_ENDPOINT_XFER_BULK, or USB_ENDPOINT_XFER_INT
  • wMaxPacketSize
  • Maximum bytes that an endpoint can handle
  • Larger transfers will be split into multiple
    transfers

15
Endpoints
  • bInterval
  • For interrupt endpoints, this value specifies the
    milliseconds between interrupt requests for the
    endpoint

16
Interfaces
  • USB endpoints are bundled into interfaces
  • A interface handles only one type of logical
    connection (e.g., a mouse)
  • Some devices have multiple interfaces
  • E.g., a speaker
  • One interface for buttons and one for audio
    stream
  • USB interface may have alternate settings
  • E.g., different settings to reserve different
    amounts of bandwidth for the device

17
Interfaces
  • Described via struct usb_interface
  • Passed from USB core to USB drivers
  • Some important fields
  • struct usb_host_interface altsetting
  • An array of settings for this interface
  • unsigned num_altsetting
  • Number of alternative settings

18
Interfaces
  • struct usb_host_interface cur_altsetting
  • A pointer into the altsetting array, denoting the
    current setting
  • int minor
  • Minor number assigned by the USB core to the
    interface
  • Valid after a successful call to usb_register_dev

19
Configurations
  • USB interfaces are bundled into configurations
  • A USB device can have multiple configurations
  • Might switch between them
  • Described in struct usb_host_config (embedded in
    struct usb_device)

20
Configurations
  • Overall
  • A USB device has one or more configurations
  • A configuration has one or more interfaces
  • An interface has one or more settings
  • Also zero or more endpoints

21
USB and Sysfs
  • Both USB devices and its interfaces are shown in
    sysfs as individual devices
  • A USB mouse device can be represented as
  • /sys/devices/pci000000/00000009.0/usb2/2-1
  • The interface of the USB mouse device driver is
    represented as
  • /sys/devices/pci000000/00000009.0/usb2/2-1/2-1
    1.0

root_hub-hub_portconfiguration.interface
22
USB and Sysfs
  • For a two-level USB connection, the device name
    is in the following format
  • root_hub-hub_port-hub_portconfiguration.interf
    ace
  • In the sysfs directory, all USB information is
    available
  • E.g., idVendor, idProduct, bMaxPower
  • bConfigurationValue can be written to change the
    active configuration

23
USB and Sysfs
  • More information is available in /proc/bus/usb
    directory
  • User-space programs can directly communicate with
    USB devices via the directory

24
USB Urbs (USB Request Block)
  • struct urb
  • Used to send and receive data between endpoints
  • Asynchronous
  • Defined in ltinclude/linux/usb.hgt
  • Dynamically created
  • Contains reference count for garbage collection
  • Designed to achieve high throughput

25
USB Urbs (USB Request Block)
  • A typical lifecycle of a urb
  • A USB device driver creates a urb
  • Assigns it to a specific endpoint of a device
  • Submits it to the USB core
  • The USB core submits the urb to specific USB host
    controller driver
  • The USB host controller driver processes the urb
    and transfers it to the device
  • Notifies the USB device driver when the urb is
    done

26
USB Urbs (USB Request Block)
  • A urb can be cancelled by the driver or the USB
    core if the device is removed from the system

27
struct urb
  • Important fields
  • / destination USB device /
  • / must be initialized by the USB driver before
    the urb can be sent to the USB core /
  • struct usb_device dev
  • / end point type information /
  • / set to the return value from one of the usb
    send and receive pipe functions /
  • / must be initialized by the USB driver before
    the urb can be sent to the USB core /
  • unsigned int pipe

28
struct urb
  • / assigned to one of the transfer flags /
  • unsigned int transfer_flags
  • void transfer_buffer / points to a kmalloced
    buffer /
  • dma_addr_t transfer_dma / buffer for DMA
    transfers /
  • / buffer length for either the transfer_buffer
    or the transfer_dma variable, 0 if neither
    buffers are used /
  • int transfer_buffer_length
  • / pointer to a setup packet for a control urb /
  • / transferred before the data in the transfer
    buffer /
  • unsigned char setup_packet
  • / DMA buffer for the setup packet for a control
    urb /
  • dma_addr_t setup_dma

29
struct urb
  • / pointer to the completion handler called by
    USB core /
  • usb_complete_t complete
  • / pointer to a data blob that can be set by the
    USB driver /
  • void context
  • / actual length of data sent/received by the urb
    /
  • int actual_length
  • / accessed in the completion handler /
  • / see status values /
  • int status
  • / the initial frame number for isochronous
    transfers /
  • int start_frame

30
struct urb
  • / polling interval for the urb /
  • / valid only for interrupt or isochronous urbs
    /
  • / for slow devices, the unit is in frames or
    milliseconds /
  • / for other devices, the unit is in 1/8
    milliseconds /
  • int interval
  • / the number of isochronous transfer buffers
    handled by this urb /
  • / must be set by the USB driver before the urb
    is sent to the USB core /
  • int number_of_packets
  • / number of isochronous transfers with errors /
  • int error_count

31
struct urb
  • / allows a single urb to define a number of
    isochronous transfers at once /
  • struct usb_iso_packet_descriptor
    iso_frame_desc0
  • struct usb_iso_packet_descriptor
  • unsigned int offset / byte into the transfer
    buffer /
  • unsigned int length / length of the transfer
    buffer /
  • / length of data received into the transfer
    buffer /
  • unsigned int actual_length
  • unsigned int status / see status values /

32
USB send and receive pipe functions
  • / specifies a control OUT endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_sndctrlpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)
  • / specifies a control IN endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_rcvctrlpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)
  • / specifies a bulk OUT endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_sndbulkpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)

33
USB send and receive pipe functions
  • / specifies a bulk IN endpoint for the specified
    USB device with the specified endpoint number /
  • unsigned int usb_rcvbulkpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)
  • / specifies a interrupt OUT endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_sndintpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)
  • / specifies a interrupt IN endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_rcvintpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)

34
USB send and receive pipe functions
  • / specifies a isochronous OUT endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_sndisocpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)
  • / specifies a isochronous IN endpoint for the
    specified USB device with the specified endpoint
    number /
  • unsigned int usb_rcvisocpipe(struct usb_device
    dev,
  • unsigned int
    endpoint)

35
Transfer flags
  • URB_SHORT_NOT_OK
  • Partial read should be treated as an error by the
    USB core
  • URB_ISO_ASAP
  • Set this bit if the driver wants the isochronous
    urb to be scheduled as soon as bandwidth allows
  • Set the start_frame variable

36
Transfer flags
  • URB_NO_TRANSFER_DMA_MAP
  • Set when the urb contains a DMA buffer to be
    transferred
  • Tells the USB core to use the buffer pointed by
    the transfer_dma pointer, not the transfer_buffer
    pointer

37
Transfer flags
  • URB_NO_SETUP_DMA_MAP
  • Used for control urbs with DMA buffer already set
    up
  • Tells the USB core to use the buffer pointed by
    the setup_dma pointer instead of the setup_packet
    pointer
  • URB_ASYNC_UNLINK
  • Tells usb_unlink_urb() to return immediate and
    unlink the urb in the background

38
Transfer flags
  • URB_NO_FSBR
  • For UHCI USB host controller
  • Generally not used
  • URB_ZERO_PACKET
  • Tells a bulk out urb finishes by sending an empty
    packet when the data is aligned to an endpoint
    packet boundary

39
Transfer flags
  • URB_NO_INTERRUPT
  • Indicates that the hardware may not generate an
    interrupt when the urb is finished
  • Used when queuing multiple urbs to the same
    endpoint
  • Used by USB core to perform DMA transfers

40
Status Values
  • 0
  • The urb transfer was successful
  • For isochronous urbs, only indicates whether the
    urb has been unlinked
  • Detailed status in iso_frame_desc
  • -ENOENT
  • Urb stopped by usb_kill_urb
  • -ECONNRESET
  • Urb was unlinked by usb_unlink_urb
  • transfer_flags set to URB_ASYNC_UNLINK

41
Status Values
  • -EINPROGRESS
  • Urb still being processed by the USB host
    controller
  • A bug if seen at the driver level
  • -EPROTO (a hardware problem)
  • A bitstuff error happened during the transfer
  • No response packet was received
  • -EILSEQ (a hardware problem)
  • CRC mismatch

42
Status Values
  • -EPIPE
  • The endpoint is now stalled
  • If not a control endpoint, can clear this error
    with usb_clear_halt
  • -ECOMM
  • Data received faster than it could be written to
    system memory
  • -ENOSR
  • Data cannot be retrieved from the system memory
    during the transfer fast enough to keep up with
    the requested USB data rate

43
Status Values
  • -EOVERFLOW (a hardware problem)
  • A babble error, happened when the endpoint
    receives more data than the specified max
  • -EREMOTEIO
  • Full amount of data was not received
  • Occurs when the URB_SHORT_NOT_OK is set
  • -ENODEV
  • The USB device is gone from the system

44
Status Values
  • -EXDEV
  • Only for a isochronous urb
  • Transfer was partially completed
  • -EINVAL
  • ISO madness, if this happens Log off and go
    home
  • Incorrect function parameter

45
Status Values
  • -ESHUTDOWN
  • Host controller driver has been disabled or
    disconnected
  • Urb was submitted after the device was removed
  • Configuration change while the urb was submitted

46
Creating and Destroying Urbs
  • All urbs need to be created dynamically
  • Or the reference count would not work
  • To create a urb, call
  • struct urb usb_alloc_urb(int iso_packets, int
    mem_flags)
  • Returns a pointer to the urb or NULL on failure
  • iso_packets number of isochronous packets this
    urb should contain
  • mem_flags same as kmalloc flags
  • To destroy a urb, call
  • void usb_free_urb(struct urb urb)

47
Interrupt urbs
  • To initialize an interrupt urb, call
  • void
  • usb_fill_int_urb(struct urb urb, struct
    usb_device dev,
  • unsigned int pipe, void
    transfer_buffer,
  • int buffer_length, usb_complete_t
    complete,
  • void context, int interval)
  • urb a pointer to the urb to be initialized
  • dev The destination USB device
  • pipe the destination endpoint of this urb

48
Interrupt urbs
  • transfer_buffer a pointer to a kmalloced buffer
  • buffer_length the length of the transfer buffer
  • complete pointer to the completion handler
  • context pointer to the blob, retrieved by the
    completion handler function
  • interval scheduling interval for this urb

49
Bulk urbs
  • To initialize an bulk urb, call
  • void
  • usb_fill_bulk_urb(struct urb urb, struct
    usb_device dev,
  • unsigned int pipe, void
    transfer_buffer,
  • int buffer_length, usb_complete_t
    complete,
  • void context)
  • Similar to interrupt urb initialization
  • No interval parameter

50
Control urbs
  • To initialize a control urb, call
  • void
  • usb_fill_control_urb(struct urb urb, struct
    usb_device dev,
  • unsigned int pipe,
  • unsigned char setup_packet,
  • void transfer_buffer, int
    buffer_length,
  • usb_complete_t complete,
    void context)
  • Similar to bulk urb initialization
  • setup_packet points to the setup packet data
  • Does not set the transfer_flags

51
Isochronous urbs
New location for 2.6.25
  • Have no initialization functions
  • Need to be initialized by hand
  • / from /drivers/media/video/usbvideo/konicawc.c
    /
  • urb-gtdev dev
  • urb-gtcontext uvd
  • urb-gtpipe usb_rcvisocpipe(dev, uvd-gtvideo_endp
    - 1)
  • urb-gtinterval 1
  • urb-gttransfer_flags URB_ISO_ASAP
  • urb-gttransfer_buffer cam-gtsts_bufi
  • urb-gtcomplete konicawc_isoc_irq
  • urb-gtnumber_of_packets FRAMES_PER_DESC
  • urb-gttransfer_buffer_length FRAMES_PER_DESC
  • for (j0 j lt FRAMES_PER_DESC j)
  • urb-gtiso_frame_descj.offset j
  • urb-gtiso_frame_descj.length 1

52
Submitting Urbs
  • To send a urb to the USB core, call
  • int usb_submit_urb(struct urb urb, gfp_t
    mem_flags)
  • urb a pointer to the urb
  • mem_flags same as kmalloc flags
  • Should not access a submitted urb until the
    complete function is called

53
Completing Urbs The Completion Callback Handler
  • Called exactly once when the urb is completed
  • When this function is called, the USB core is
    finished with the urb, and control is returned to
    the device driver

54
Completing Urbs The Completion Callback Handler
  • The completion handler is called under three
    conditions
  • The urb is successfully sent to the device and
    acknowledged
  • An error has occurred
  • Check the status variable
  • The urb was unlinked (the submission was
    cancelled) when a device is removed from the
    system

55
Canceling Urbs
  • To stop a submitted urb, call
  • int usb_kill_urb(struct urb urb)
  • Used when the device is disconnected from the
    system
  • int usb_unlink_urb(struct urb urb)
  • Tells the USB core to stop an urb
  • Returns before the urb is fully stopped
  • Useful while in an interrupt handler
  • Requires setting the URB_ASYNC_UNLINK

56
Writing a USB Driver
  • Similar to a pci_driver
  • Driver registers its driver object with the USB
    subsystem
  • Later uses vendor and device identifiers to tell
    if its hardware has been installed

57
What Devices Does the Driver Support?
  • struct usb_device_id lists supported types of USB
    devices
  • Important fields
  • __u16 match_flags
  • Determines which fields in the structure the
    device should be matched against
  • Check include/linux/mod_devicetable.h
  • __u16 idVendor
  • __u16 idProduct

58
What Devices Does the Driver Support?
  • __u16 bcdDevice_lo
  • __u16 bcdDevice_hi
  • Define low and high ends of the range of the
    vendor-assigned product version number
  • Expressed in binary-coded decimal (BCD)
  • __u8 bDeviceClass
  • __u8 bDeviceSubClass
  • __u8 bDeviceProtocol
  • Define the class, subclass, and protocol of the
    device

59
What Devices Does the Driver Support?
  • __u8 bInterfaceClass
  • __u8 bInterfaceSubClass
  • __u8 bInterfaceProtocol
  • Class, subclass, and protocol of the individual
    interface
  • kernel_ulong_t driver_info
  • Used to differentiate different devices in the
    probe callback function

60
What Devices Does the Driver Support?
  • To initialize usb_device_id, use the following
    macros
  • USB_DEVICE(vendor, product)
  • Creates a usb_device_id that can be used to match
    only the specified vendor and product IDs
  • USB_DEVICE_VER(vendor, product, lo, hi)
  • Creates a usb_device_id that can be used to match
    only the specified vendor and product IDs within
    a version range
  • USB_DEVICE_INFO(class, subclass, protocol)
  • Creates a usb_device_id that can be used to match
    a specific class of USB devices

61
What Devices Does the Driver Support?
  • USB_INTERFACE_INFO(class, subclass, protocol)
  • Creates a usb_device_id that can be used to match
    a specific class of USB interfaces
  • Example
  • / table of devices that work with this driver /
  • static struct usb_device_id skel_table
  • USB_DEVICE(USB_SKEL_VENDOR_ID,
    USB_SKEL_PRODUCT_ID) ,
  • / Terminating entry /
  • / allow user-space tools to figure out what
    devices this driver can control /
  • MODULE_DEVICE_TABLE(usb, skel_table)

62
Registering a USB Driver
  • The main structure for a USB driver is struct
    usb_driver
  • Important fields
  • struct module owner
  • Set to THIS_MODULE to track the reference count
    of the module owning this driver
  • const char name
  • Points to a unique driver name

63
Registering a USB Driver
  • const struct usb_device_id id_table
  • Pointer to the list of supported USB devices
  • If you want your driver always be called for
    every USB device, create an entry that sets only
    the driver_info field
  • static struct usb_device_id usb_ids
  • .driver_info 42,

64
Registering a USB Driver
  • int (probe) (struct usb_interface intf,
  • const struct usb_device_id id)
  • Called when the USB core thinks it has a struct
    usb_interface that this driver can handle
  • The USB driver should initialize the usb
    interface and return 0, or return a negative
    error number on failure
  • void (disconnect) (struct usb_interface intf)
  • Called when the usb_interface has been removed
    from the system, or when the driver is being
    unloaded

65
Registering a USB Driver
  • To create a struct usb_driver, only five fields
    need to be initialized
  • static struct usb_driver skel_driver
  • .owner THIS_MODULE,
  • .name "skeleton",
  • .id_table skel_table,
  • .probe skel_probe,
  • .disconnect skel_disconnect,

66
Registering a USB Driver
  • To register a USB driver call usb_register_driver
  • Example
  • static int __init usb_skel_init(void)
  • int result
  • / register this driver with the USB subsystem
    /
  • result usb_register(skel_driver)
  • if (result)
  • err("usb_register failed. Error number d",
    result)
  • return result

67
Registering a USB Driver
  • To unload a USB driver call usb_deregister
  • Example
  • static void __exit usb_skel_exit(void)
  • / deregister this driver with the USB
    subsystem /
  • / invokes disconnect() within usb_deregister()
    /
  • usb_deregister(skel_driver)

68
Probe and Disconnect in Detail
  • Called in the context of the USB hub kernel
    thread
  • Sleep is allowed
  • However, should do most of the work when the
    device is opened by a user
  • USB core handles addition and removal of USB
    devices in a single thread
  • A slow device driver can slow down USB device
    detection

69
Probe and Disconnect in Detail
  • Probe function should
  • Initialize local structures that it might use to
    manage the USB device
  • Save any information that it needs to the local
    structure
  • Detect endpoint address and buffer sizes
  • Example usb/usb-skeleton.c

70
Probe and Disconnect in Detail
  • static int skel_prob(struct usb_interface
    interface,
  • const struct usb_device_id
    id)
  • struct usb_skel dev NULL
  • struct usb_host_interface iface_desc
  • struct usb_endpoint_descriptor endpoint
  • size_t buffer_size
  • int i
  • int retval -ENOMEM
  • dev kmalloc(sizeof(struct usb_skel),
    GFP_KERNEL)
  • if (dev NULL)
  • err(Out of memory)
  • goto error
  • memset(dev, 0x00, sizeof(dev))
  • kref_init(dev-gtkref)

71
Probe and Disconnect in Detail
  • dev-gtudev usb_get_dev(interface_to_usbdev(inte
    rface))
  • dev-gtinterface interface
  • / set up the endpoint information /
  • / use only the first bulk-in and bulk-out
    endpoints /
  • iface_desc interface-gtcur_altsetting
  • for (i 0 i lt iface_desc-gtdesc.bNumEndpoints
    i)
  • endpoint iface_desc-gtendpointi.desc
  • if (!dev-gtbulk_in_endpointAddr
  • (endpoint-gtbEndpointAddress USB_DIR_IN)
  • ((endpoint-gtbmAttributes
    USB_ENDPOINT_XFERTYPE_MASK)
  • USB_ENDPOINT_XFER_BULK))
  • / we found a bulk in endpoint /

72
Probe and Disconnect in Detail
  • / we found a bulk in endpoint /
  • buffer_size endpoint-gtwMaxPacketSize
  • dev-gtbulk_in_size buffer_size
  • dev-gtbulk_in_endpointAddr
    endpoint-gtbEndpointAddress
  • dev-gtbulk_in_buffer kmalloc(buffer_size,
    GFP_KERNEL)
  • if (!dev-gtbulk_in_buffer)
  • err("Could not allocate bulk_in_buffer")
  • goto error
  • if (!dev-gtbulk_out_endpointAddr
  • !(endpoint-gtbEndpointAddress
    USB_DIR_IN)
  • ((endpoint-gtbmAttributes
    USB_ENDPOINT_XFERTYPE_MASK)
  • USB_ENDPOINT_XFER_BULK))
  • / we found a bulk out endpoint /

73
Probe and Disconnect in Detail
  • / we found a bulk out endpoint /
  • dev-gtbulk_out_endpointAddr
    endpoint-gtbEndpointAddress
  • if (!(dev-gtbulk_in_endpointAddr
  • dev-gtbulk_out_endpointAddr))
  • err("Could not find both bulk-in and bulk-out
    endpoints")
  • goto error
  • / save our data pointer in this interface
    device /
  • usb_set_intfdata(interface, dev)

Use usb_get_intfdata(interface) to retrieve dev
74
Probe and Disconnect in Detail
  • / we can register the device now, as it is
    ready /
  • retval usb_register_dev(interface,
    skel_class)
  • if (retval)
  • err(Not able to get a minor for this
    device.)
  • usb_set_intfdata(interface, NULL)
  • goto error
  • return 0
  • error
  • if (dev)
  • kref_put(dev-gtkref, skel_delete)
  • return retval

Need to call usb_register_dev() instead of
usb_register() for input, tty, video USB devices
that are not associated with predefined types
Call usb_put_dev(), free bulk_in_buffer and dev
75
Probe and Disconnect in Detail
  • The definition of skel_class
  • static struct usb_class_driver skel_class
  • .name "usb/skeld",
  • .fops skel_fops,
  • .mode S_IFCHRS_IRUSRS_IWUSRS_IRGRPS_IWGRP
    S_IROTH,
  • .minor_base USB_SKEL_MINOR_BASE,
  • The definition of skel_fops
  • static struct file_operations skel_fops
  • .owner THIS_MODULE,
  • .read skel_read,
  • .write skel_write,
  • .open skel_open,
  • .release skel_release,

The start of the assigned minor range for this
driver
76
Probe and Disconnect in Detail
  • The disconnect function
  • static void skel_disconnect(struct usb_interface
    interface)
  • struct usb_skel dev
  • int minor interface-gtminor
  • / prevent skel_open() from racing
    skel_disconnect() /
  • lock_kernel()
  • dev usb_get_intfdata(interface)
  • usb_set_intfdata(interface, NULL)
  • / give back our minor /
  • usb_deregister_dev(interface, skel_class)
  • unlock_kernel()
  • / decrement our usage count /
  • kref_put(dev-gtkref, skel_delete)

The big kernel lock
All in-transit urbs are canceled by the USB core
before disconnect() is called no need to call
usb_kill_urb()
77
Submitting and Controlling a Urb
  • static ssize_t skel_write(struct file file,
  • const char __user
    user_buffer,
  • size_t count, loff_t
    ppos)
  • struct usb_skel dev
  • int retval 0
  • struct urb urb NULL
  • char buf NULL
  • if (count 0) goto exit
  • dev (struct usb_skel )file-gtprivate_data
  • / create a urb and its buffer copy the data
    to the urb /
  • urb usb_alloc_urb(0, GFP_KERNEL)
  • if (!urb)
  • retval -ENOMEM
  • goto error

Initialized in skel_open()
78
Submitting and Controlling a Urb
  • buf usb_buffer_alloc(dev-gtudev, count,
    GFP_KERNEL,
  • urb-gttransfer_dma)
  • if (!buf)
  • retval -ENOMEM
  • goto error
  • if (copy_from_user(buf, user_buffer, count))
  • retval -EFAULT
  • goto error
  • / initialize the urb properly /
  • usb_fill_bulk_urb(urb, dev-gtudev,
  • usb_sndbulkpipe(dev-gtudev,
    dev-gtbulk_out_endpointAddr),
  • buf, count, skel_write_bulk_callback,
    dev)
  • urb-gttransfer_flags URB_NO_TRANSFER_DMA_MAP

79
Submitting and Controlling a Urb
  • / send the data out the bulk port /
  • retval usb_submit_urb(urb, GFP_KERNEL)
  • if (retval)
  • err("s - failed submitting write urb, error
    d",
  • __FUNCTION__, retval)
  • goto error
  • / release our reference to this urb, the USB
    core will
  • eventually free it entirely /
  • usb_free_urb(urb)
  • exit
  • return count

80
Submitting and Controlling a Urb
  • error
  • usb_buffer_free(dev-gtudev, count, buf,
    urb-gttransfer_dma)
  • usb_free_urb(urb)
  • kfree(buf)
  • return retval

81
Probe and Disconnect in Detail
  • The callback (complete) function
  • static void skel_write_bulk_callback(struct urb
    urb,
  • struct
    pt_regs regs)
  • / in interrupt context /
  • / sync/async unlink faults aren't errors /
  • if (urb-gtstatus !(urb-gtstatus -ENOENT
  • urb-gtstatus -ECONNRESET
  • urb-gtstatus
    -ESHUTDOWN))
  • dbg("s - nonzero write bulk status received
    d",
  • __FUNCTION__, urb-gtstatus)
  • / free up our allocated buffer /
  • usb_buffer_free(urb-gtdev, urb-gttransfer_buffer_l
    ength,
  • urb-gttransfer_buffer,
    urb-gttransfer_dma)

82
USB Transfers Without Urbs
  • usb_bulk_msg
  • Creates a USB bulk urb and sends it to the
    specified device
  • Waits for it to complete before returning to the
    caller
  • int usb_bulk_msg(struct usb_device usb_dev,
  • unsigned int pipe, void data,
    int len,
  • int actual_length, int
    timeout)
  • timeout
  • in jiffies
  • Set to 0 to wait until the message to complete

83
USB Transfers Without Urbs
  • Cannot be called from within interrupt context
  • Cannot be called with a spinlock held
  • Cannot be cancelled by any other function
  • The disconnect call needs to wait for
    usb_bulk_msg to complete before allowing itself
    to be unloaded

84
USB Transfers Without Urbs
  • Example
  • static ssize_t skel_read(struct file file,
  • char __user buffer,
    size_t count,
  • loff_t ppos)
  • struct usb_skel dev
  • int retval 0
  • dev (struct usb_skel )file-gtprivate_data
  • / do a blocking bulk read to get data from the
    device /
  • retval usb_bulk_msg(dev-gtudev,
  • usb_rcvbulkpipe(dev-gtudev, dev-gtbulk_in_endpoi
    ntAddr),
  • dev-gtbulk_in_buffer, min(dev-gtbulk_in_size,
    count),
  • count, HZ10)

85
USB Transfers Without Urbs
  • / if successful read, copy the data to user
    space /
  • if (!retval)
  • if (copy_to_user(buffer, dev-gtbulk_in_buffer,
    count))
  • retval -EFAULT
  • else
  • retval count
  • return retval

86
usb_control_msg
  • Works just like the usb_bulk_msg
  • Allows a driver to send and receive USB control
    messages
  • int usb_control_msg(struct usb_device dev,
  • unsigned int pipe, __u8
    request,
  • __u8 requesttype, __u16
    value,
  • __u16 index, void data,
    __u16 size,
  • int timeout)
  • Returns the number of bytes transferred on
    success, or a negative error number
  • Same restrictions as usb_bulk_msg

87
Other USB Data Functions
  • Cannot be called from within interrupt context or
    with a spinlock held
  • int usb_get_descriptor(struct usb_device dev,
  • unsigned char type,
  • unsigned char index,
  • void buf, int size)
  • int usb_get_string(struct usb_device dev,
  • unsigned short langid,
    unsigned char index,
  • void buf, int size)
Write a Comment
User Comments (0)
About PowerShow.com