我们这里只是讨论usb 驱动的原理 不会涉及到usb的协议
UHCI: intel, 低速(1.5Mbps)/全速(12Mbps)
OHCI:Microsoft 低速/全速
EHCI:高速(480Mbps)
调用的形式为:
hub_irq->kick_khubd -> hub_thread -> hub_events -> hub_port_connect_change->hub_port_init 里面会打印出发现一个新的usb设备
hub_port_init 函数:
1 static int 2 hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, 3 int retry_counter) 4 { 5 struct usb_device *hdev = hub->hdev; 6 struct usb_hcd *hcd = bus_to_hcd(hdev->bus); 7 struct usb_port *port_dev = hub->ports[port1 - 1]; 8 int retries, operations, retval, i; 9 unsigned delay = HUB_SHORT_RESET_TIME; 10 enum usb_device_speed oldspeed = udev->speed; 11 const char *speed; 12 int devnum = udev->devnum; 13 const char *driver_name; 14 bool do_new_scheme; 15 16 /* root hub ports have a slightly longer reset period 17 * (from USB 2.0 spec, section 7.1.7.5) 18 */ 19 if (!hdev->parent) { 20 delay = HUB_ROOT_RESET_TIME; 21 if (port1 == hdev->bus->otg_port) 22 hdev->bus->b_hnp_enable = 0; 23 } 24 25 /* Some low speed devices have problems with the quick delay, so */ 26 /* be a bit pessimistic with those devices. RHbug #23670 */ 27 if (oldspeed == USB_SPEED_LOW) 28 delay = HUB_LONG_RESET_TIME; 29 30 mutex_lock(hcd->address0_mutex); 31 32 /* Reset the device; full speed may morph to high speed */ 33 /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ 34 retval = hub_port_reset(hub, port1, udev, delay, false); 35 if (retval < 0) /* error or disconnect */ 36 goto fail; 37 /* success, speed is known */ 38 39 retval = -ENODEV; 40 41 /* Don't allow speed changes at reset, except usb 3.0 to faster */ 42 if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed && 43 !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) { 44 dev_dbg(&udev->dev, "device reset changed speed!\n"); 45 goto fail; 46 } 47 oldspeed = udev->speed; 48 49 /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... 50 * it's fixed size except for full speed devices. 51 * For Wireless USB devices, ep0 max packet is always 512 (tho 52 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. 53 */ 54 switch (udev->speed) { 55 case USB_SPEED_SUPER_PLUS: 56 case USB_SPEED_SUPER: 57 case USB_SPEED_WIRELESS: /* fixed at 512 */ 58 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); 59 break; 60 case USB_SPEED_HIGH: /* fixed at 64 */ 61 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); 62 break; 63 case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ 64 /* to determine the ep0 maxpacket size, try to read 65 * the device descriptor to get bMaxPacketSize0 and 66 * then correct our initial guess. 67 */ 68 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); 69 break; 70 case USB_SPEED_LOW: /* fixed at 8 */ 71 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); 72 break; 73 default: 74 goto fail; 75 } 76 77 if (udev->speed == USB_SPEED_WIRELESS) 78 speed = "variable speed Wireless"; 79 else 80 speed = usb_speed_string(udev->speed); 81 82 /* 83 * The controller driver may be NULL if the controller device 84 * is the middle device between platform device and roothub. 85 * This middle device may not need a device driver due to 86 * all hardware control can be at platform device driver, this 87 * platform device is usually a dual-role USB controller device. 88 */ 89 if (udev->bus->controller->driver) 90 driver_name = udev->bus->controller->driver->name; 91 else 92 driver_name = udev->bus->sysdev->driver->name; 93 94 if (udev->speed < USB_SPEED_SUPER) 95 dev_info(&udev->dev, 96 "%s %s USB device number %d using %s\n", 97 (udev->config) ? "reset" : "new", speed, 98 devnum, driver_name); 99 100 /* Set up TT records, if needed */ 101 if (hdev->tt) { 102 udev->tt = hdev->tt; 103 udev->ttport = hdev->ttport; 104 } else if (udev->speed != USB_SPEED_HIGH 105 && hdev->speed == USB_SPEED_HIGH) { 106 if (!hub->tt.hub) { 107 dev_err(&udev->dev, "parent hub has no TT\n"); 108 retval = -EINVAL; 109 goto fail; 110 } 111 udev->tt = &hub->tt; 112 udev->ttport = port1; 113 } 114 115 /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way? 116 * Because device hardware and firmware is sometimes buggy in 117 * this area, and this is how Linux has done it for ages. 118 * Change it cautiously. 119 * 120 * NOTE: If use_new_scheme() is true we will start by issuing 121 * a 64-byte GET_DESCRIPTOR request. This is what Windows does, 122 * so it may help with some non-standards-compliant devices. 123 * Otherwise we start with SET_ADDRESS and then try to read the 124 * first 8 bytes of the device descriptor to get the ep0 maxpacket 125 * value. 126 */ 127 do_new_scheme = use_new_scheme(udev, retry_counter, port_dev); 128 129 for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) { 130 if (do_new_scheme) { 131 struct usb_device_descriptor *buf; 132 int r = 0; 133 134 retval = hub_enable_device(udev); 135 if (retval < 0) { 136 dev_err(&udev->dev, 137 "hub failed to enable device, error %d\n", 138 retval); 139 goto fail; 140 } 141 142 #define GET_DESCRIPTOR_BUFSIZE 64 143 buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); 144 if (!buf) { 145 retval = -ENOMEM; 146 continue; 147 } 148 149 /* Retry on all errors; some devices are flakey. 150 * 255 is for WUSB devices, we actually need to use 151 * 512 (WUSB1.0[4.8.1]). 152 */ 153 for (operations = 0; operations < GET_MAXPACKET0_TRIES; 154 ++operations) { 155 buf->bMaxPacketSize0 = 0; 156 r = usb_control_msg(udev, usb_rcvaddr0pipe(), 157 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 158 USB_DT_DEVICE << 8, 0, 159 buf, GET_DESCRIPTOR_BUFSIZE, 160 initial_descriptor_timeout); 161 switch (buf->bMaxPacketSize0) { 162 case 8: case 16: case 32: case 64: case 255: 163 if (buf->bDescriptorType == 164 USB_DT_DEVICE) { 165 r = 0; 166 break; 167 } 168 fallthrough; 169 default: 170 if (r == 0) 171 r = -EPROTO; 172 break; 173 } 174 /* 175 * Some devices time out if they are powered on 176 * when already connected. They need a second 177 * reset. But only on the first attempt, 178 * lest we get into a time out/reset loop 179 */ 180 if (r == 0 || (r == -ETIMEDOUT && 181 retries == 0 && 182 udev->speed > USB_SPEED_FULL)) 183 break; 184 } 185 udev->descriptor.bMaxPacketSize0 = 186 buf->bMaxPacketSize0; 187 kfree(buf); 188 189 retval = hub_port_reset(hub, port1, udev, delay, false); 190 if (retval < 0) /* error or disconnect */ 191 goto fail; 192 if (oldspeed != udev->speed) { 193 dev_dbg(&udev->dev, 194 "device reset changed speed!\n"); 195 retval = -ENODEV; 196 goto fail; 197 } 198 if (r) { 199 if (r != -ENODEV) 200 dev_err(&udev->dev, "device descriptor read/64, error %d\n", 201 r); 202 retval = -EMSGSIZE; 203 continue; 204 } 205 #undef GET_DESCRIPTOR_BUFSIZE 206 } 207 208 /* 209 * If device is WUSB, we already assigned an 210 * unauthorized address in the Connect Ack sequence; 211 * authorization will assign the final address. 212 */ 213 if (udev->wusb == 0) { 214 for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) { 215 retval = hub_set_address(udev, devnum); 216 if (retval >= 0) 217 break; 218 msleep(200); 219 } 220 if (retval < 0) { 221 if (retval != -ENODEV) 222 dev_err(&udev->dev, "device not accepting address %d, error %d\n", 223 devnum, retval); 224 goto fail; 225 } 226 if (udev->speed >= USB_SPEED_SUPER) { 227 devnum = udev->devnum; 228 dev_info(&udev->dev, 229 "%s SuperSpeed%s%s USB device number %d using %s\n", 230 (udev->config) ? "reset" : "new", 231 (udev->speed == USB_SPEED_SUPER_PLUS) ? 232 " Plus" : "", 233 (udev->ssp_rate == USB_SSP_GEN_2x2) ? 234 " Gen 2x2" : 235 (udev->ssp_rate == USB_SSP_GEN_2x1) ? 236 " Gen 2x1" : 237 (udev->ssp_rate == USB_SSP_GEN_1x2) ? 238 " Gen 1x2" : "", 239 devnum, driver_name); 240 } 241 242 /* cope with hardware quirkiness: 243 * - let SET_ADDRESS settle, some device hardware wants it 244 * - read ep0 maxpacket even for high and low speed, 245 */ 246 msleep(10); 247 if (do_new_scheme) 248 break; 249 } 250 251 retval = usb_get_device_descriptor(udev, 8); 252 if (retval < 8) { 253 if (retval != -ENODEV) 254 dev_err(&udev->dev, 255 "device descriptor read/8, error %d\n", 256 retval); 257 if (retval >= 0) 258 retval = -EMSGSIZE; 259 } else { 260 u32 delay; 261 262 retval = 0; 263 264 delay = udev->parent->hub_delay; 265 udev->hub_delay = min_t(u32, delay, 266 USB_TP_TRANSMISSION_DELAY_MAX); 267 retval = usb_set_isoch_delay(udev); 268 if (retval) { 269 dev_dbg(&udev->dev, 270 "Failed set isoch delay, error %d\n", 271 retval); 272 retval = 0; 273 } 274 break; 275 } 276 } 277 if (retval) 278 goto fail; 279 280 /* 281 * Some superspeed devices have finished the link training process 282 * and attached to a superspeed hub port, but the device descriptor 283 * got from those devices show they aren't superspeed devices. Warm 284 * reset the port attached by the devices can fix them. 285 */ 286 if ((udev->speed >= USB_SPEED_SUPER) && 287 (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { 288 dev_err(&udev->dev, "got a wrong device descriptor, " 289 "warm reset device\n"); 290 hub_port_reset(hub, port1, udev, 291 HUB_BH_RESET_TIME, true); 292 retval = -EINVAL; 293 goto fail; 294 } 295 296 if (udev->descriptor.bMaxPacketSize0 == 0xff || 297 udev->speed >= USB_SPEED_SUPER) 298 i = 512; 299 else 300 i = udev->descriptor.bMaxPacketSize0; 301 if (usb_endpoint_maxp(&udev->ep0.desc) != i) { 302 if (udev->speed == USB_SPEED_LOW || 303 !(i == 8 || i == 16 || i == 32 || i == 64)) { 304 dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); 305 retval = -EMSGSIZE; 306 goto fail; 307 } 308 if (udev->speed == USB_SPEED_FULL) 309 dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); 310 else 311 dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); 312 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); 313 usb_ep0_reinit(udev); 314 } 315 316 retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); 317 if (retval < (signed)sizeof(udev->descriptor)) { 318 if (retval != -ENODEV) 319 dev_err(&udev->dev, "device descriptor read/all, error %d\n", 320 retval); 321 if (retval >= 0) 322 retval = -ENOMSG; 323 goto fail; 324 } 325 326 usb_detect_quirks(udev); 327 328 if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { 329 retval = usb_get_bos_descriptor(udev); 330 if (!retval) { 331 udev->lpm_capable = usb_device_supports_lpm(udev); 332 usb_set_lpm_parameters(udev); 333 } 334 } 335 336 retval = 0; 337 /* notify HCD that we have a device connected and addressed */ 338 if (hcd->driver->update_device) 339 hcd->driver->update_device(hcd, udev); 340 hub_set_initial_usb2_lpm_policy(udev); 341 fail: 342 if (retval) { 343 hub_port_disable(hub, port1, 0); 344 update_devnum(udev, devnum); /* for disconnect processing */ 345 } 346 mutex_unlock(hcd->address0_mutex); 347 return retval; 348 }
在这个函数中首先重新连接了一次usb口
line34 行:retval = hub_port_reset(hub, port1, udev, delay, false);
line42行:
 if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed &&
	    !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) {
		dev_dbg(&udev->dev, "device reset changed speed!\n");
这里 查看usb的速度是不是变化了 如果变化了则报错
后面从P54行到P75行表示的是速度和msg的packetsize的对应关系
line 127:
use_new_scheme 在usb3.0 中此enumeration scheme会造成USB3 在默认的状态下接收到数据。所以usb3 需要禁止这个枚举。
line 251:retval = usb_get_device_descriptor(udev, 8);
获得usb的描述符

如果得到描述符 那么我们就分配一个地址
usb_control_msg(udev, usb_rcvaddr0pipe) 这个函数是建立一个控制的urb
USB 总线驱动程序的作用
1. 识别USB设备
1.1 分配地址 并告诉USB设备(set address)
1.2 发出命令获取描述符
2.查找并安装对应的设备驱动程序
3. 提供USB读写的函数
由于最新的linux版本usb的源码和之前的相差比较大所以我们直接参考官方文档给出的方法去做:
1.首先完成usb_driver 这个结构体

其中,supports_autosuspend 表示的是是否支持usb自动悬挂。
USB 初始化

ubs_register函数会把skel_driver 结构体注册到总线设备中。

usb_deregister 会把注册的driver注销掉。
为了支持usb热插拔 我们需要MODULE_DEVICE_TABLE

上面的表只是一个例子 下面给一个真的table
static const struct usb_device_id usb_kbd_id_table[] = { { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_KEYBOARD) }, { } /* Terminating entry */ };
这个就是真的keyboard的table
最后就是当usb的deviceID和driver注册的一样的时候就会call probe函数。
请注意 这里面driver的名字可以随便写因为usb设备貌似不看名字。
probe函数中经常用的知识点:
static int usb_kbd_probe(struct usb_interface *iface,
			 const struct usb_device_id *id)
1.struct usb_device *dev = interface_to_usbdev(iface) //这句说是把usb_interface 结构体转化为usb_device.
2. USB endpoint: endpoints指的是usb硬件的一个buffer 主设备都是从这个buffer中读或者写数据。usb设备中至少有一个endpoint 在地址0的位置可读可写这个endpoint是为了hotplug上去之后识别用的。
3.usb_host_interface 这是一个usb主的结构体。
4. bNumEndpoints 表示双向的Endpoints 必须只有一个 且在address0
5. usb_endpoint_is_int_in 是否endpoint是输入 方向(一边的device都是输入 从机)
6.pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 创建一个和end point相连接的pipe 注意pipe是一个软件的概念 通道
7. URB:usb传输的数据块,包含usb信息的所有元素 可以用usb_submit_urb()去发送 如果发送出去返回成功信号。
8. usb_buff = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys) 这个函数分配usb的buffer 表示最后存到哪里
9. usb_make_path(dev, mouse->phys, sizeof(mouse->phys)); 找到mouse->phy 的绝对路径
10. usb_fill_bulk_urb: 把数据写入urb
11.usb_submit_urb 此函数会把数据发送出去
12 usb_bulk_msg 函数是作为读usb里面的数据
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号