Solaris USB设备驱动-USB Generic Driver

The Solaris USB Driver Development Kit includes the USB Generic Driver (Ugen), which presents USB devices to applications through a standard read/write UNIX interface. Ugen allows for easy access to USB peripherals connected to your SPARC processor-based Solaris system. Currently, Ugen supports USB control, bulk, and interrupt-IN transfers, but not isochronous transfers. We provide an example that uses Ugen to access status information about a USB uninterruptible power supply (UPS). This paper targets application programmers with limited knowledge of USB devices.

Please download the latest Solaris 10 Express releases for the new and ongoing enhancements in USB. Information about the Solaris Express release can be found at http://www.sun.com/software/solaris/solaris-express/sol_index.html.

USB HID PDC

Having been invented by engineers, USB comes with a slew of acronyms. An uninterruptible power supply is classified as a USB HID PDC, for Universal Serial Bus Human Interface Devices Power Device Class. The USB Implementers Forum has defined a number of device class specifications, among them the mass storage class specification, the audio class specification, and the human interface device (HID) class. For a given set of devices, a class specification defines the methods of transferring data, the commands the devices should support, and how they should respond to these commands. The HID class deals with keyboards, mice, and joysticks, but also with devices such as a UPS. The HID specifications for these devices are listed on the USB-IF HID web page. The following paragraphs refer to several sections of these specifications.

Simplified UPS Application

The simple UPS application first will obtain manufacturer and device information about UPS. It will also query additional USB information. The application's goal is to show how to obtain the battery status of the UPS. Is the AC wall power available? Is the battery charging? Does the device need to be replaced? Other information can easily be obtained in a similar fashion. To keep the application simple, a HID parser or GUI has been omitted.

Appendix A provides the demonstration source code for usbups.h, and Appendix B shows the source code for usbups.c.

Binding Ugen Driver to Your Device

The Solaris Ugen driver will interface with the USBA1.0 Framework to issue low-level USB transfers. Before being able to talk to the device, the Ugen driver must be bound to the device. This is accomplished using device-specific information. Upon reboot of the system or hot-plugging of a USB device, the Solaris USBA1.0 Framework reads out the USB device's device-specific information (device descriptor).

Upon plugging the UPS into our system, the prtconf(1M) command shows that the device is initially being recognized as an HID device, using the Solaris hid(7D) driver. Because the current Solaris USB HID implementation does not support UPS devices, the hid binding will be removed and the device will be bound to the Ugen driver.

# prtconf -v
input (driver not attached)
Hardware properties:
name='low-speed' type=boolean
...
name='compatible' type=string items=8
value='usb463,ffff.1' + 'usb463,ffff'
+ 'usbif463,class3.0.0' + 'usbif463,class3.0'
+ 'usbif463,class3' + 'usbif,class3.0.0'
+ 'usbif,class3.0' + 'usbif,class3'
# rem_drv ugen
# add_drv -i '"usb463,ffff.1"' -m '* 0666 root sys' ugen
# grep ugen /etc/driver_aliases
ugen "usb463,ffff.1"
# reboot -- -r // Reconfiguration reboot
# prtconf -D
...
usb, instance #0 (driver name: ohci)
mouse, instance #0 (driver name: hid)
keyboard, instance #1 (driver name: hid)
input, instance #0 (driver name: ugen)
...

# cd /dev/usb/463.ffff/0
# cd 0
# ls -l
cntrl0 // Default Control Pipe
cntrl0stat // Default Control status
devstat // Device Status
if0in1 // Interrupt IN Pipe
if0in1stat // Interrupt IN status

Details on ugen are available as part of the Solaris man pages. You can also access details at http://developers.sun.com/solaris/developer/support/driver/docs/ugen7d.txt.

Obtaining USB Device Status

Before accessing specific device information, the application intends to find out the overall status of the device. Ugen will report four device status levels:

  1. Device is available (USB_DEV_STAT_ONLINE)
  2. Device has been disconnected (USB_DEV_STAT_DISCONNECTED)
  3. Device has been resumed (USB_DEV_STAT_RESUMED)
  4. Device has been reconnected ( USB_DEV_STAT_UNAVAILABLE)

This information can be used throughout the application; for example, it could be used to ask the user to (re)insert the device. To obtain the device status, you need to consult the devstat device node.

/* 
* Obtain Device status
*/

int
get_dev_stat(int fd) {

int error;
int status;

error = read(fd, &status, sizeof(status));
if (error != sizeof(status)) {
fprintf(stderr, "usbups: Could not read device
status: %sn", strerror(error));
status = -1;
}
else {
switch(status) {
case USB_DEV_STAT_ONLINE:
DPRINT("usbups: Device Status - Device
is availablen");
break;
case USB_DEV_STAT_DISCONNECTED:
DPRINT("usbupsS: Device Status - Device
has been disconnectedn");
break;
case USB_DEV_STAT_RESUMED:
DPRINT("usbups: Device Status - Device
has been resumedn");
break;
case USB_DEV_STAT_UNAVAILABLE:
DPRINT("usbups: Device Status - Device
powered downn");
break;
}
}
return status;
} // end get_dev_stat
...


./* Obtain Device Status
* The default device status node is /devstat
* i.e. /dev/usb/463.ffff/0/devstat
*/
strcpy(name_buffer, path);
strcat(name_buffer, "/");
strcat(name_buffer, "devstat");

devstat_fd = open(name_buffer, O_RDONLY | O_EXCL );
if (devstat_fd < 0) {
fprintf(stderr, "usbups: Error opening %s: %sn",
name_buffer, strerror(errno));
exit(errno);
}
if (get_dev_stat(devstat_fd) != USB_DEV_STAT_ONLINE) {
fprintf(stderr, "usbups: Device is not availablen");
exit(1);
}
Reading the USB Device Descriptor

USB devices report their attributes using descriptors. A descriptor is simply a data structure with a defined format. The device descriptor describes general information about a USB device. It includes the manufacturer ID, product ID, class code, and so on (see USB 2.0/ 9.6.1 in References section). The device descriptor information is also requested by the USBA1.0 framework in order to build the device tree; its contents were used when binding Ugen to our device (see the preceding code sample).

USB devices present their device information in response to a GET_DESCRIPTOR SETUP request in a form that is little-endian and, for multibyte integers, unaligned. This SETUP request is sent to the device using a control pipe. In the following code snippet, the SETUP request (setup_data) is prepared in the init_cntrl_req function. (init_cntrl_req fills up an 8-byte data structure, setup_data, and performs a byte swap for SPARC platforms.) Details about init_cntrl_req can be found in the source code listing (see Appendixes A and B).

/* Open default control endpoint, in order to send GET_DESCRIPTOR  
* requests. The default control pipe name is /cntrl0 */

strcpy(name_buffer, path);
strcat(name_buffer, "/");
strcat(name_buffer, "cntrl0");

ctrl_fd = open(name_buffer, O_RDWR|O_EXCL);
if (ctrl_fd < 0) {
// Error Handling
}
...

/*********************************************************
* Obtain device descriptor
* Device Descriptor Setup Packet
* bmRequestType = USB_DEV_REQ_DEV_TO_HOST (0x80)
* bRequest = USB_REQ_GET_DESCR (0x06)
* wValue = USB_DESCR_TYPE_DEV (0x0001)
* wIndex = 0
* wLength = 12
*********************************************************/

init_cntrl_req(&setup_data, USB_DEV_REQ_DEV_TO_HOST,
USB_REQ_GET_DESCR, USB_DESCR_TYPE_DEV, 0, 0x0012);

count = write(ctrl_fd, &setup_data, sizeof(setup_data));
if (count != sizeof(setup_data)) {
error = get_ctrl_stat(ctrlstat_fd);
fprintf(stderr, "usbups: Error issuing
GET_DESCRIPTOR(device): %sn", error);
}
else { /* Read DEVICE_DESCRIPTOR */
count = read(ctrl_fd, &dev_descr, sizeof(dev_descr));
if (count != sizeof(dev_descr)) {
error = get_ctrl_stat(ctrlstat_fd);
fprintf(stderr, "usbups: Error reading device
descriptor: %sn", error);
}
}
print_dev_descr(dev_descr);
Descriptors Galore: the Configuration, Interface, HID, and Report Descriptors

A single USB device might have several configurations; that is, a high-power device might support a low-power mode, which might have different functionality. The configuration descriptors include general information about each configuration. The configurati

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值