diff options
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r-- | drivers/usb/core/message.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 217a3d6d0a06..b7434787db5f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -412,10 +412,24 @@ int usb_sg_init ( | |||
412 | io->urbs [i]->status = -EINPROGRESS; | 412 | io->urbs [i]->status = -EINPROGRESS; |
413 | io->urbs [i]->actual_length = 0; | 413 | io->urbs [i]->actual_length = 0; |
414 | 414 | ||
415 | /* | ||
416 | * Some systems need to revert to PIO when DMA is temporarily | ||
417 | * unavailable. For their sakes, both transfer_buffer and | ||
418 | * transfer_dma are set when possible. However this can only | ||
419 | * work on systems without HIGHMEM, since DMA buffers located | ||
420 | * in high memory are not directly addressable by the CPU for | ||
421 | * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL | ||
422 | * to prevent stale pointers and to help spot bugs. | ||
423 | */ | ||
415 | if (dma) { | 424 | if (dma) { |
416 | /* hc may use _only_ transfer_dma */ | ||
417 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); | 425 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); |
418 | len = sg_dma_len (sg + i); | 426 | len = sg_dma_len (sg + i); |
427 | #ifdef CONFIG_HIGHMEM | ||
428 | io->urbs[i]->transfer_buffer = NULL; | ||
429 | #else | ||
430 | io->urbs[i]->transfer_buffer = | ||
431 | page_address(sg[i].page) + sg[i].offset; | ||
432 | #endif | ||
419 | } else { | 433 | } else { |
420 | /* hc may use _only_ transfer_buffer */ | 434 | /* hc may use _only_ transfer_buffer */ |
421 | io->urbs [i]->transfer_buffer = | 435 | io->urbs [i]->transfer_buffer = |
@@ -1305,7 +1319,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1305 | return 0; | 1319 | return 0; |
1306 | } | 1320 | } |
1307 | 1321 | ||
1308 | static void release_interface(struct device *dev) | 1322 | void usb_release_interface(struct device *dev) |
1309 | { | 1323 | { |
1310 | struct usb_interface *intf = to_usb_interface(dev); | 1324 | struct usb_interface *intf = to_usb_interface(dev); |
1311 | struct usb_interface_cache *intfc = | 1325 | struct usb_interface_cache *intfc = |
@@ -1315,6 +1329,67 @@ static void release_interface(struct device *dev) | |||
1315 | kfree(intf); | 1329 | kfree(intf); |
1316 | } | 1330 | } |
1317 | 1331 | ||
1332 | #ifdef CONFIG_HOTPLUG | ||
1333 | static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | ||
1334 | char *buffer, int buffer_size) | ||
1335 | { | ||
1336 | struct usb_device *usb_dev; | ||
1337 | struct usb_interface *intf; | ||
1338 | struct usb_host_interface *alt; | ||
1339 | int i = 0; | ||
1340 | int length = 0; | ||
1341 | |||
1342 | if (!dev) | ||
1343 | return -ENODEV; | ||
1344 | |||
1345 | /* driver is often null here; dev_dbg() would oops */ | ||
1346 | pr_debug ("usb %s: uevent\n", dev->bus_id); | ||
1347 | |||
1348 | intf = to_usb_interface(dev); | ||
1349 | usb_dev = interface_to_usbdev(intf); | ||
1350 | alt = intf->cur_altsetting; | ||
1351 | |||
1352 | if (add_uevent_var(envp, num_envp, &i, | ||
1353 | buffer, buffer_size, &length, | ||
1354 | "INTERFACE=%d/%d/%d", | ||
1355 | alt->desc.bInterfaceClass, | ||
1356 | alt->desc.bInterfaceSubClass, | ||
1357 | alt->desc.bInterfaceProtocol)) | ||
1358 | return -ENOMEM; | ||
1359 | |||
1360 | if (add_uevent_var(envp, num_envp, &i, | ||
1361 | buffer, buffer_size, &length, | ||
1362 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | ||
1363 | le16_to_cpu(usb_dev->descriptor.idVendor), | ||
1364 | le16_to_cpu(usb_dev->descriptor.idProduct), | ||
1365 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | ||
1366 | usb_dev->descriptor.bDeviceClass, | ||
1367 | usb_dev->descriptor.bDeviceSubClass, | ||
1368 | usb_dev->descriptor.bDeviceProtocol, | ||
1369 | alt->desc.bInterfaceClass, | ||
1370 | alt->desc.bInterfaceSubClass, | ||
1371 | alt->desc.bInterfaceProtocol)) | ||
1372 | return -ENOMEM; | ||
1373 | |||
1374 | envp[i] = NULL; | ||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1378 | #else | ||
1379 | |||
1380 | static int usb_if_uevent(struct device *dev, char **envp, | ||
1381 | int num_envp, char *buffer, int buffer_size) | ||
1382 | { | ||
1383 | return -ENODEV; | ||
1384 | } | ||
1385 | #endif /* CONFIG_HOTPLUG */ | ||
1386 | |||
1387 | struct device_type usb_if_device_type = { | ||
1388 | .name = "usb_interface", | ||
1389 | .release = usb_release_interface, | ||
1390 | .uevent = usb_if_uevent, | ||
1391 | }; | ||
1392 | |||
1318 | /* | 1393 | /* |
1319 | * usb_set_configuration - Makes a particular device setting be current | 1394 | * usb_set_configuration - Makes a particular device setting be current |
1320 | * @dev: the device whose configuration is being updated | 1395 | * @dev: the device whose configuration is being updated |
@@ -1349,7 +1424,7 @@ static void release_interface(struct device *dev) | |||
1349 | * | 1424 | * |
1350 | * This call is synchronous. The calling context must be able to sleep, | 1425 | * This call is synchronous. The calling context must be able to sleep, |
1351 | * must own the device lock, and must not hold the driver model's USB | 1426 | * must own the device lock, and must not hold the driver model's USB |
1352 | * bus rwsem; usb device driver probe() methods cannot use this routine. | 1427 | * bus mutex; usb device driver probe() methods cannot use this routine. |
1353 | * | 1428 | * |
1354 | * Returns zero on success, or else the status code returned by the | 1429 | * Returns zero on success, or else the status code returned by the |
1355 | * underlying call that failed. On successful completion, each interface | 1430 | * underlying call that failed. On successful completion, each interface |
@@ -1478,8 +1553,8 @@ free_interfaces: | |||
1478 | intf->dev.parent = &dev->dev; | 1553 | intf->dev.parent = &dev->dev; |
1479 | intf->dev.driver = NULL; | 1554 | intf->dev.driver = NULL; |
1480 | intf->dev.bus = &usb_bus_type; | 1555 | intf->dev.bus = &usb_bus_type; |
1556 | intf->dev.type = &usb_if_device_type; | ||
1481 | intf->dev.dma_mask = dev->dev.dma_mask; | 1557 | intf->dev.dma_mask = dev->dev.dma_mask; |
1482 | intf->dev.release = release_interface; | ||
1483 | device_initialize (&intf->dev); | 1558 | device_initialize (&intf->dev); |
1484 | mark_quiesced(intf); | 1559 | mark_quiesced(intf); |
1485 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", | 1560 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", |