本文基于新思的dwc3 usb控制器,介绍usb的gadget驱动,kernel版本为5.15。
probe刚开始和前面介绍的host驱动是一样的,只不过在dwc3_core_init_mode函数中会选择gadget初始化dwc3_gadget_init。
1214 static int dwc3_core_init_mode(struct dwc3 *dwc)
1215 {
1216 struct device *dev = dwc->dev;
1217 int ret;
1218
1219 switch (dwc->dr_mode) {
1220 case USB_DR_MODE_PERIPHERAL:
1221 dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
1222
1223 if (dwc->usb2_phy)
1224 otg_set_vbus(dwc->usb2_phy->otg, false);
1225 phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE);
1226 phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE);
1227
1228 ret = dwc3_gadget_init(dwc);
1229 if (ret)
1230 return dev_err_probe(dev, ret, "failed to initialize gadget\n");
1231 break;
1232 case USB_DR_MODE_HOST:
1233 dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
1234
1235 if (dwc->usb2_phy)
1236 otg_set_vbus(dwc->usb2_phy->otg, true);
1237 phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
1238 phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
1239
1240 ret = dwc3_host_init(dwc);
1241 if (ret)
1242 return dev_err_probe(dev, ret, "failed to initialize host\n");
1243 break;
1244 case USB_DR_MODE_OTG:
1245 INIT_WORK(&dwc->drd_work, __dwc3_set_mode);
1246 ret = dwc3_drd_init(dwc);
1247 if (ret)
1248 return dev_err_probe(dev, ret, "failed to initialize dual-role\n");
1249 break;
1250 default:
1251 dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
1252 return -EINVAL;
1253 }
1254
1255 return 0;
1256 }
在dwc3_gadget_init中主要就是调用dwc3_gadget_init_endpoints初始化ep, 并且申请了usb_gadget数据结构,并初始化里面的usb_gadget_ops回调函数, 然后调用usb_add_gadget。
4303 /**
4304 * dwc3_gadget_init - initializes gadget related registers
4305 * @dwc: pointer to our controller context structure
4306 *
4307 * Returns 0 on success otherwise negative errno.
4308 */
4309 int dwc3_gadget_init(struct dwc3 *dwc)
4310 {
4311 int ret;
4312 int irq;
4313 struct device *dev;
4314
4315 #ifdef CONFIG_USB_DWC3_AXERA
4316 axera_usb_device_init(dwc);
4317 #endif
4318
4319 irq = dwc3_gadget_get_irq(dwc);
4320 if (irq < 0) {
4321 ret = irq;
4322 goto err0;
4323 }
4324
4325 dwc->irq_gadget = irq;
4326
4327 dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev,
4328 sizeof(*dwc->ep0_trb) * 2,
4329 &dwc->ep0_trb_addr, GFP_KERNEL);
4330 if (!dwc->ep0_trb) {
4331 dev_err(dwc->dev, "failed to allocate ep0 trb\n");
4332 ret = -ENOMEM;
4333 goto err0;
4334 }
4335
4336 dwc->setup_buf = kzalloc(DWC3_EP0_SETUP_SIZE, GFP_KERNEL);
4337 if (!dwc->setup_buf) {
4338 ret = -ENOMEM;
4339 goto err1;
4340 }
4341
4342 dwc->bounce = dma_alloc_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE,
4343 &dwc->bounce_addr, GFP_KERNEL);
4344 if (!dwc->bounce) {
4345 ret = -ENOMEM;
4346 goto err2;
4347 }
4348
4349 init_completion(&dwc->ep0_in_setup);
4350 dwc->gadget = kzalloc(sizeof(struct usb_gadget), GFP_KERNEL);
4351 if (!dwc->gadget) {
4352 ret = -ENOMEM;
4353 goto err3;
4354 }
4355
4356
4357 usb_initialize_gadget(dwc->dev, dwc->gadget, dwc_gadget_release);
4358 dev = &dwc->gadget->dev;
4359 dev->platform_data = dwc;
4360 dwc->gadget->ops = &dwc3_gadget_ops;
4361 dwc->gadget->speed = USB_SPEED_UNKNOWN;
4362 dwc->gadget->ssp_rate = USB_SSP_GEN_UNKNOWN;
4363 dwc->gadget->sg_supported = false;
4364 dwc->gadget->name = "dwc3-gadget";
4365 dwc->gadget->lpm_capable = !dwc->usb2_gadget_lpm_disable;
4366
4367 /*
4368 * FIXME We might be setting max_speed to <SUPER, however versions
4369 * <2.20a of dwc3 have an issue with metastability (documented
4370 * elsewhere in this driver) which tells us we can't set max speed to
4371 * anything lower than SUPER.
4372 *
4373 * Because gadget.max_speed is only used by composite.c and function
4374 * drivers (i.e. it won't go into dwc3's registers) we are allowing this
4375 * to happen so we avoid sending SuperSpeed Capability descriptor
4376 * together with our BOS descriptor as that could confuse host into
4377 * thinking we can handle super speed.
4378 *
4379 * Note that, in fact, we won't even support GetBOS requests when speed
4380 * is less than super speed because we don't have means, yet, to tell
4381 * composite.c that we are USB 2.0 + LPM ECN.
4382 */
4383 if (DWC3_VER_IS_PRIOR(DWC3, 220A) &&
4384 !dwc->dis_metastability_quirk)
4385 dev_info(dwc->dev, "changing max_speed on rev %08x\n",
4386 dwc->revision);
4387
4388 dwc->gadget->max_speed = dwc->maximum_speed;
4389 dwc->gadget->max_ssp_rate = dwc->max_ssp_rate;
4390
4391 /*
4392 * REVISIT: Here we should clear all pending IRQs to be
4393 * sure we're starting from a well known location.
4394 */
4395
4396 ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps);
4397 if (ret)
4398 goto err4;
4399
4400 ret = usb_add_gadget(dwc->gadget);
4401 if (ret) {
4402 dev_err(dwc->dev, "failed to add gadget\n");
4403 goto err5;
4404 }
4405
4406 if (DWC3_IP_IS(DWC32) && dwc->maximum_speed == USB_SPEED_SUPER_PLUS)
4407 dwc3_gadget_set_ssp_rate(dwc->gadget, dwc->max_ssp_rate);
4408 else
4409 dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed);
4410
4411 return 0;
4412
4413 err5:
4414 dwc3_gadget_free_endpoints(dwc);
4415 err4:
4416 usb_put_gadget(dwc->gadget);
4417 dwc->gadget = NULL;
4418 err3:
4419 dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
4420 dwc->bounce_addr);
4421
4422 err2:
4423 kfree(dwc->setup_buf);
4424
4425 err1:
4426 dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2,
4427 dwc->ep0_trb, dwc->ep0_trb_addr);
4428
4429 err0:
4430 return ret;
4431 }
dwc3_gadget_init_endpoints会调用dwc3_gadget_init_endpoint依次初始化endpoint。在dwc3_gadget_init_endpoint中会分配dwc3_ep数据结构。然后根据endpint类型调用不同的初始化流程,主要就是初始化dep->endpoint.ops,并将这个ep挂到dwc->gadget->ep_list链表上。
3016 static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
3017 {
3018 struct dwc3_ep *dep;
3019 bool direction = epnum & 1;
3020 int ret;
3021 u8 num = epnum >> 1;
3022
3023 dep = kzalloc(sizeof(*dep), GFP_KERNEL);
3024 if (!dep)
3025 return -ENOMEM;
3026
3027 dep->dwc = dwc;
3028 dep->number = epnum;
3029 dep->direction = direction;
3030 dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
3031 dwc->eps[epnum] = dep;
3032 dep->combo_num = 0;
3033 dep->start_cmd_status = 0;
3034
3035 snprintf(dep->name, sizeof(dep->name), "ep%u%s", num,
3036 direction ? "in" : "out");
3037
3038 dep->endpoint.name = dep->name;
3039
3040 if (!(dep->number > 1)) {
3041 dep->endpoint.desc = &dwc3_gadget_ep0_desc;
3042 dep->endpoint.comp_desc = NULL;
3043 }
3044
3045 if (num == 0)
3046 ret = dwc3_gadget_init_control_endpoint(dep);
3047 else if (direction)
3048 ret = dwc3_gadget_init_in_endpoint(dep);
3049 else
3050 ret = dwc3_gadget_init_out_endpoint(dep);
3051
3052 if (ret)
3053 return ret;
3054
3055 dep->endpoint.caps.dir_in = direction;
3056 dep->endpoint.caps.dir_out = !direction;
3057
3058 INIT_LIST_HEAD(&dep->pending_list);
3059 INIT_LIST_HEAD(&dep->started_list);
3060 INIT_LIST_HEAD(&dep->cancelled_list);
3061
3062 dwc3_debugfs_create_endpoint_dir(dep);
3063
3064 return 0;
3065 }
usb_ep_ops定义如下,为控制器端点的收发数据等函数。
2175 /* -------------------------------------------------------------------------- */
2176
2177 static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = {
2178 .bLength = USB_DT_ENDPOINT_SIZE,
2179 .bDescriptorType = USB_DT_ENDPOINT,
2180 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
2181 };
2182
2183 static const struct usb_ep_ops dwc3_gadget_ep0_ops = {
2184 .enable = dwc3_gadget_ep0_enable,
2185 .disable = dwc3_gadget_ep0_disable,
2186 .alloc_request = dwc3_gadget_ep_alloc_request,
2187 .free_request = dwc3_gadget_ep_free_request,
2188 .queue = dwc3_gadget_ep0_queue,
2189 .dequeue = dwc3_gadget_ep_dequeue,
2190 .set_halt = dwc3_gadget_ep0_set_halt,
2191 .set_wedge = dwc3_gadget_ep_set_wedge,
2192 };
2193
2194 static const struct usb_ep_ops dwc3_gadget_ep_ops = {
2195 .enable = dwc3_gadget_ep_enable,
2196 .disable = dwc3_gadget_ep_disable,
2197 .alloc_request = dwc3_gadget_ep_alloc_request,
2198 .free_request = dwc3_gadget_ep_free_request,
2199 .queue = dwc3_gadget_ep_queue,
2200 .dequeue = dwc3_gadget_ep_dequeue,
2201 .set_halt = dwc3_gadget_ep_set_halt,
2202 .set_wedge = dwc3_gadget_ep_set_wedge,
2203 };
2204
2205 /* -------------------------------------------------------------------------- */
再继续看usb_gadget数据结构如下:
335 /**
336 * struct usb_gadget - represents a usb device
337 * @work: (internal use) Workqueue to be used for sysfs_notify()
338 * @udc: struct usb_udc pointer for this gadget
339 * @ops: Function pointers used to access hardware-specific operations.
340 * @ep0: Endpoint zero, used when reading or writing responses to
341 * driver setup() requests
342 * @ep_list: List of other endpoints supported by the device.
343 * @speed: Speed of current connection to USB host.
344 * @max_speed: Maximal speed the UDC can handle. UDC must support this
345 * and all slower speeds.
346 * @ssp_rate: Current connected SuperSpeed Plus signaling rate and lane count.
347 * @max_ssp_rate: Maximum SuperSpeed Plus signaling rate and lane count the UDC
348 * can handle. The UDC must support this and all slower speeds and lower
349 * number of lanes.
350 * @state: the state we are now (attached, suspended, configured, etc)
351 * @name: Identifies the controller hardware type. Used in diagnostics
352 * and sometimes configuration.
353 * @dev: Driver model state for this abstract device.
354 * @isoch_delay: value from Set Isoch Delay request. Only valid on SS/SSP
355 * @out_epnum: last used out ep number
356 * @in_epnum: last used in ep number
357 * @mA: last set mA value
358 * @otg_caps: OTG capabilities of this gadget.
359 * @sg_supported: true if we can handle scatter-gather
360 * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
361 * gadget driver must provide a USB OTG descriptor.
362 * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
363 * is in the Mini-AB jack, and HNP has been used to switch roles
364 * so that the "A" device currently acts as A-Peripheral, not A-Host.
365 * @a_hnp_support: OTG device feature flag, indicating that the A-Host
366 * supports HNP at this port.
367 * @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host
368 * only supports HNP on a different root port.
369 * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
370 * enabled HNP support.
371 * @hnp_polling_support: OTG device feature flag, indicating if the OTG device
372 * in peripheral mode can support HNP polling.
373 * @host_request_flag: OTG device feature flag, indicating if A-Peripheral
374 * or B-Peripheral wants to take host role.
375 * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to
376 * MaxPacketSize.
377 * @quirk_altset_not_supp: UDC controller doesn't support alt settings.
378 * @quirk_stall_not_supp: UDC controller doesn't support stalling.
379 * @quirk_zlp_not_supp: UDC controller doesn't support ZLP.
380 * @quirk_avoids_skb_reserve: udc/platform wants to avoid skb_reserve() in
381 * u_ether.c to improve performance.
382 * @is_selfpowered: if the gadget is self-powered.
383 * @deactivated: True if gadget is deactivated - in deactivated state it cannot
384 * be connected.
385 * @connected: True if gadget is connected.
386 * @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag
387 * indicates that it supports LPM as per the LPM ECN & errata.
388 * @irq: the interrupt number for device controller.
389 *
390 * Gadgets have a mostly-portable "gadget driver" implementing device
391 * functions, handling all usb configurations and interfaces. Gadget
392 * drivers talk to hardware-specific code indirectly, through ops vectors.
393 * That insulates the gadget driver from hardware details, and packages
394 * the hardware endpoints through generic i/o queues. The "usb_gadget"
395 * and "usb_ep" interfaces provide that insulation from the hardware.
396 *
397 * Except for the driver data, all fields in this structure are
398 * read-only to the gadget driver. That driver data is part of the
399 * "driver model" infrastructure in 2.6 (and later) kernels, and for
400 * earlier systems is grouped in a similar structure that's not known
401 * to the rest of the kernel.
402 *
403 * Values of the three OTG device feature flags are updated before the
404 * setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before
405 * driver suspend() calls. They are valid only when is_otg, and when the
406 * device is acting as a B-Peripheral (so is_a_peripheral is false).
407 */
408 struct usb_gadget {
409 struct work_struct work;
410 struct usb_udc *udc;
411 /* readonly to gadget driver */
412 const struct usb_gadget_ops *ops;
413 struct usb_ep *ep0;
414 struct list_head ep_list; /* of usb_ep */
415 enum usb_device_speed speed;
416 enum usb_device_speed max_speed;
417
418 /* USB SuperSpeed Plus only */
419 enum usb_ssp_rate ssp_rate;
420 enum usb_ssp_rate max_ssp_rate;
421
422 enum usb_device_state state;
423 const char *name;
424 struct device dev;
425 unsigned isoch_delay;
426 unsigned out_epnum;
427 unsigned in_epnum;
428 unsigned mA;
429 struct usb_otg_caps *otg_caps;
430
431 unsigned sg_supported:1;
432 unsigned is_otg:1;
433 unsigned is_a_peripheral:1;
434 unsigned b_hnp_enable:1;
435 unsigned a_hnp_support:1;
436 unsigned a_alt_hnp_support:1;
437 unsigned hnp_polling_support:1;
438 unsigned host_request_flag:1;
439 unsigned quirk_ep_out_aligned_size:1;
440 unsigned quirk_altset_not_supp:1;
441 unsigned quirk_stall_not_supp:1;
442 unsigned quirk_zlp_not_supp:1;
443 unsigned quirk_avoids_skb_reserve:1;
444 unsigned is_selfpowered:1;
445 unsigned deactivated:1;
446 unsigned connected:1;
447 unsigned lpm_capable:1;
448 int irq;
449 };
在usb_add_gadget中会创建usb_udc数据结构,usb_udc对于的就是usb device设备,它被挂载到udc_list全局链表。可以看到在这个函数中会调用device_add将usb_gadget和usb_udc的dev成员添加到系统中,执行完这个添加工作后,只是会在sys系统中显示设备的相关信息, 并不会匹配驱动。
1283 /**
1284 * usb_add_gadget - adds a new gadget to the udc class driver list
1285 * @gadget: the gadget to be added to the list.
1286 *
1287 * Returns zero on success, negative errno otherwise.
1288 * Does not do a final usb_put_gadget() if an error occurs.
1289 */
1290 int usb_add_gadget(struct usb_gadget *gadget)
1291 {
1292 struct usb_udc *udc;
1293 int ret = -ENOMEM;
1294
1295 udc = kzalloc(sizeof(*udc), GFP_KERNEL);
1296 if (!udc)
1297 goto error;
1298
1299 device_initialize(&udc->dev);
1300 udc->dev.release = usb_udc_release;
1301 udc->dev.class = udc_class;
1302 udc->dev.groups = usb_udc_attr_groups;
1303 udc->dev.parent = gadget->dev.parent;
1304 ret = dev_set_name(&udc->dev, "%s",
1305 kobject_name(&gadget->dev.parent->kobj));
1306 if (ret)
1307 goto err_put_udc;
1308
1309 ret = device_add(&gadget->dev);
1310 if (ret)
1311 goto err_put_udc;
1312
1313 udc->gadget = gadget;
1314 gadget->udc = udc;
1315
1316 udc->started = false;
1317
1318 mutex_lock(&udc_lock);
1319 list_add_tail(&udc->list, &udc_list);
1320
1321 ret = device_add(&udc->dev);
1322 if (ret)
1323 goto err_unlist_udc;
1324
1325 usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
1326 udc->vbus = true;
1327
1328 /* pick up one of pending gadget drivers */
1329 ret = check_pending_gadget_drivers(udc);
1330 if (ret)
1331 goto err_del_udc;
1332
1333 mutex_unlock(&udc_lock);
1334
1335 return 0;
1336
1337 err_del_udc:
1338 flush_work(&gadget->work);
1339 device_del(&udc->dev);
1340
1341 err_unlist_udc:
1342 list_del(&udc->list);
1343 mutex_unlock(&udc_lock);
1344
1345 device_del(&gadget->dev);
1346
1347 err_put_udc:
1348 put_device(&udc->dev);
1349
1350 error:
1351 return ret;
1352 }
usb_udc结构如下:
24 /**
25 * struct usb_udc - describes one usb device controller
26 * @driver: the gadget driver pointer. For use by the class code
27 * @dev: the child device to the actual controller
28 * @gadget: the gadget. For use by the class code
29 * @list: for use by the udc class driver
30 * @vbus: for udcs who care about vbus status, this value is real vbus status;
31 * for udcs who do not care about vbus status, this value is always true
32 * @started: the UDC's started state. True if the UDC had started.
33 *
34 * This represents the internal data structure which is used by the UDC-class
35 * to hold information about udc driver and gadget together.
36 */
37 struct usb_udc {
38 struct usb_gadget_driver *driver;
39 struct usb_gadget *gadget;
40 struct device dev;
41 struct list_head list;
42 bool vbus;
43 bool started;
44 };
usb device设备对应的驱动是usb_gadget_driver ,这个驱动是在usb_gadget_probe_driver里面根据控制器名字绑定的,usb_gadget_probe_driver何时调用我们会在随后的文章中介绍。
1524 int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
1525 {
1526 struct usb_udc *udc = NULL;
1527 int ret = -ENODEV;
1528
1529 if (!driver || !driver->bind || !driver->setup)
1530 return -EINVAL;
1531
1532 mutex_lock(&udc_lock);
1533 if (driver->udc_name) {
1534 list_for_each_entry(udc, &udc_list, list) {
1535 ret = strcmp(driver->udc_name, dev_name(&udc->dev));
1536 if (!ret)
1537 break;
1538 }
1539 if (ret)
1540 ret = -ENODEV;
1541 else if (udc->driver)
1542 ret = -EBUSY;
1543 else
1544 goto found;
1545 } else {
1546 list_for_each_entry(udc, &udc_list, list) {
1547 /* For now we take the first one */
1548 if (!udc->driver)
1549 goto found;
1550 }
1551 }
1552
1553 if (!driver->match_existing_only) {
1554 list_add_tail(&driver->pending, &gadget_driver_pending_list);
1555 pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
1556 driver->function);
1557 ret = 0;
1558 }
1559
1560 mutex_unlock(&udc_lock);
1561 if (ret)
1562 pr_warn("udc-core: couldn't find an available UDC or it's busy\n");
1563 return ret;
1564 found:
1565 ret = udc_bind_to_driver(udc, driver);
1566 mutex_unlock(&udc_lock);
1567 return ret;
1568 }
usb devcie控制器驱动大概就是这些内容,我们后面介绍如何利用这个控制器驱动实现各种各样的usb设备。
标签:dwc3,usb,udc,gadget,ret,dwc,Linux From: https://blog.csdn.net/liverdream/article/details/145263130