diff options
Diffstat (limited to 'drivers')
446 files changed, 4834 insertions, 7879 deletions
diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 2da8660262e5..81dc75033f15 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c | |||
| @@ -33,7 +33,7 @@ acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address, | |||
| 33 | void *handler_context, void *region_context) | 33 | void *handler_context, void *region_context) |
| 34 | { | 34 | { |
| 35 | int i; | 35 | int i; |
| 36 | u8 *value = (u8 *)&value64; | 36 | u8 *value = (u8 *)value64; |
| 37 | 37 | ||
| 38 | if (address > 0xff || !value64) | 38 | if (address > 0xff || !value64) |
| 39 | return AE_BAD_PARAMETER; | 39 | return AE_BAD_PARAMETER; |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index ce06149088c5..fddc1e86f9d0 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
| @@ -196,6 +196,17 @@ static struct lpss_device_desc byt_i2c_dev_desc = { | |||
| 196 | .setup = lpss_i2c_setup, | 196 | .setup = lpss_i2c_setup, |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static struct lpss_shared_clock bsw_pwm_clock = { | ||
| 200 | .name = "pwm_clk", | ||
| 201 | .rate = 19200000, | ||
| 202 | }; | ||
| 203 | |||
| 204 | static struct lpss_device_desc bsw_pwm_dev_desc = { | ||
| 205 | .clk_required = true, | ||
| 206 | .save_ctx = true, | ||
| 207 | .shared_clock = &bsw_pwm_clock, | ||
| 208 | }; | ||
| 209 | |||
| 199 | #else | 210 | #else |
| 200 | 211 | ||
| 201 | #define LPSS_ADDR(desc) (0UL) | 212 | #define LPSS_ADDR(desc) (0UL) |
| @@ -225,6 +236,12 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { | |||
| 225 | { "INT33B2", }, | 236 | { "INT33B2", }, |
| 226 | { "INT33FC", }, | 237 | { "INT33FC", }, |
| 227 | 238 | ||
| 239 | /* Braswell LPSS devices */ | ||
| 240 | { "80862288", LPSS_ADDR(bsw_pwm_dev_desc) }, | ||
| 241 | { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, | ||
| 242 | { "8086228E", LPSS_ADDR(byt_spi_dev_desc) }, | ||
| 243 | { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, | ||
| 244 | |||
| 228 | { "INT3430", LPSS_ADDR(lpt_dev_desc) }, | 245 | { "INT3430", LPSS_ADDR(lpt_dev_desc) }, |
| 229 | { "INT3431", LPSS_ADDR(lpt_dev_desc) }, | 246 | { "INT3431", LPSS_ADDR(lpt_dev_desc) }, |
| 230 | { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, | 247 | { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, |
| @@ -593,7 +610,7 @@ static int acpi_lpss_suspend_late(struct device *dev) | |||
| 593 | return acpi_dev_suspend_late(dev); | 610 | return acpi_dev_suspend_late(dev); |
| 594 | } | 611 | } |
| 595 | 612 | ||
| 596 | static int acpi_lpss_restore_early(struct device *dev) | 613 | static int acpi_lpss_resume_early(struct device *dev) |
| 597 | { | 614 | { |
| 598 | int ret = acpi_dev_resume_early(dev); | 615 | int ret = acpi_dev_resume_early(dev); |
| 599 | 616 | ||
| @@ -633,15 +650,15 @@ static int acpi_lpss_runtime_resume(struct device *dev) | |||
| 633 | static struct dev_pm_domain acpi_lpss_pm_domain = { | 650 | static struct dev_pm_domain acpi_lpss_pm_domain = { |
| 634 | .ops = { | 651 | .ops = { |
| 635 | #ifdef CONFIG_PM_SLEEP | 652 | #ifdef CONFIG_PM_SLEEP |
| 636 | .suspend_late = acpi_lpss_suspend_late, | ||
| 637 | .restore_early = acpi_lpss_restore_early, | ||
| 638 | .prepare = acpi_subsys_prepare, | 653 | .prepare = acpi_subsys_prepare, |
| 639 | .complete = acpi_subsys_complete, | 654 | .complete = acpi_subsys_complete, |
| 640 | .suspend = acpi_subsys_suspend, | 655 | .suspend = acpi_subsys_suspend, |
| 641 | .resume_early = acpi_subsys_resume_early, | 656 | .suspend_late = acpi_lpss_suspend_late, |
| 657 | .resume_early = acpi_lpss_resume_early, | ||
| 642 | .freeze = acpi_subsys_freeze, | 658 | .freeze = acpi_subsys_freeze, |
| 643 | .poweroff = acpi_subsys_suspend, | 659 | .poweroff = acpi_subsys_suspend, |
| 644 | .poweroff_late = acpi_subsys_suspend_late, | 660 | .poweroff_late = acpi_lpss_suspend_late, |
| 661 | .restore_early = acpi_lpss_resume_early, | ||
| 645 | #endif | 662 | #endif |
| 646 | #ifdef CONFIG_PM_RUNTIME | 663 | #ifdef CONFIG_PM_RUNTIME |
| 647 | .runtime_suspend = acpi_lpss_runtime_suspend, | 664 | .runtime_suspend = acpi_lpss_runtime_suspend, |
diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 68f725839eb6..1b13b921dda9 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c | |||
| @@ -316,6 +316,45 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, | |||
| 316 | acpi_ns_check_package_list(info, package, elements, count); | 316 | acpi_ns_check_package_list(info, package, elements, count); |
| 317 | break; | 317 | break; |
| 318 | 318 | ||
| 319 | case ACPI_PTYPE2_UUID_PAIR: | ||
| 320 | |||
| 321 | /* The package must contain pairs of (UUID + type) */ | ||
| 322 | |||
| 323 | if (count & 1) { | ||
| 324 | expected_count = count + 1; | ||
| 325 | goto package_too_small; | ||
| 326 | } | ||
| 327 | |||
| 328 | while (count > 0) { | ||
| 329 | status = acpi_ns_check_object_type(info, elements, | ||
| 330 | package->ret_info. | ||
| 331 | object_type1, 0); | ||
| 332 | if (ACPI_FAILURE(status)) { | ||
| 333 | return (status); | ||
| 334 | } | ||
| 335 | |||
| 336 | /* Validate length of the UUID buffer */ | ||
| 337 | |||
| 338 | if ((*elements)->buffer.length != 16) { | ||
| 339 | ACPI_WARN_PREDEFINED((AE_INFO, | ||
| 340 | info->full_pathname, | ||
| 341 | info->node_flags, | ||
| 342 | "Invalid length for UUID Buffer")); | ||
| 343 | return (AE_AML_OPERAND_VALUE); | ||
| 344 | } | ||
| 345 | |||
| 346 | status = acpi_ns_check_object_type(info, elements + 1, | ||
| 347 | package->ret_info. | ||
| 348 | object_type2, 0); | ||
| 349 | if (ACPI_FAILURE(status)) { | ||
| 350 | return (status); | ||
| 351 | } | ||
| 352 | |||
| 353 | elements += 2; | ||
| 354 | count -= 2; | ||
| 355 | } | ||
| 356 | break; | ||
| 357 | |||
| 319 | default: | 358 | default: |
| 320 | 359 | ||
| 321 | /* Should not get here if predefined info table is correct */ | 360 | /* Should not get here if predefined info table is correct */ |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 1c162e7be045..5fdfe65fe165 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -534,20 +534,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
| 534 | " invalid.\n"); | 534 | " invalid.\n"); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | /* | ||
| 538 | * When fully charged, some batteries wrongly report | ||
| 539 | * capacity_now = design_capacity instead of = full_charge_capacity | ||
| 540 | */ | ||
| 541 | if (battery->capacity_now > battery->full_charge_capacity | ||
| 542 | && battery->full_charge_capacity != ACPI_BATTERY_VALUE_UNKNOWN) { | ||
| 543 | if (battery->capacity_now != battery->design_capacity) | ||
| 544 | printk_once(KERN_WARNING FW_BUG | ||
| 545 | "battery: reported current charge level (%d) " | ||
| 546 | "is higher than reported maximum charge level (%d).\n", | ||
| 547 | battery->capacity_now, battery->full_charge_capacity); | ||
| 548 | battery->capacity_now = battery->full_charge_capacity; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) | 537 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) |
| 552 | && battery->capacity_now >= 0 && battery->capacity_now <= 100) | 538 | && battery->capacity_now >= 0 && battery->capacity_now <= 100) |
| 553 | battery->capacity_now = (battery->capacity_now * | 539 | battery->capacity_now = (battery->capacity_now * |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a66ab658abbc..cb6066c809ea 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -197,6 +197,8 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
| 197 | t->rdata[t->ri++] = acpi_ec_read_data(ec); | 197 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
| 198 | if (t->rlen == t->ri) { | 198 | if (t->rlen == t->ri) { |
| 199 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 199 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
| 200 | if (t->command == ACPI_EC_COMMAND_QUERY) | ||
| 201 | pr_debug("hardware QR_EC completion\n"); | ||
| 200 | wakeup = true; | 202 | wakeup = true; |
| 201 | } | 203 | } |
| 202 | } else | 204 | } else |
| @@ -208,7 +210,20 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
| 208 | } | 210 | } |
| 209 | return wakeup; | 211 | return wakeup; |
| 210 | } else { | 212 | } else { |
| 211 | if ((status & ACPI_EC_FLAG_IBF) == 0) { | 213 | /* |
| 214 | * There is firmware refusing to respond QR_EC when SCI_EVT | ||
| 215 | * is not set, for which case, we complete the QR_EC | ||
| 216 | * without issuing it to the firmware. | ||
| 217 | * https://bugzilla.kernel.org/show_bug.cgi?id=86211 | ||
| 218 | */ | ||
| 219 | if (!(status & ACPI_EC_FLAG_SCI) && | ||
| 220 | (t->command == ACPI_EC_COMMAND_QUERY)) { | ||
| 221 | t->flags |= ACPI_EC_COMMAND_POLL; | ||
| 222 | t->rdata[t->ri++] = 0x00; | ||
| 223 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | ||
| 224 | pr_debug("software QR_EC completion\n"); | ||
| 225 | wakeup = true; | ||
| 226 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | ||
| 212 | acpi_ec_write_cmd(ec, t->command); | 227 | acpi_ec_write_cmd(ec, t->command); |
| 213 | t->flags |= ACPI_EC_COMMAND_POLL; | 228 | t->flags |= ACPI_EC_COMMAND_POLL; |
| 214 | } else | 229 | } else |
| @@ -288,11 +303,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
| 288 | /* following two actions should be kept atomic */ | 303 | /* following two actions should be kept atomic */ |
| 289 | ec->curr = t; | 304 | ec->curr = t; |
| 290 | start_transaction(ec); | 305 | start_transaction(ec); |
| 291 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | ||
| 292 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
| 293 | spin_unlock_irqrestore(&ec->lock, tmp); | 306 | spin_unlock_irqrestore(&ec->lock, tmp); |
| 294 | ret = ec_poll(ec); | 307 | ret = ec_poll(ec); |
| 295 | spin_lock_irqsave(&ec->lock, tmp); | 308 | spin_lock_irqsave(&ec->lock, tmp); |
| 309 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | ||
| 310 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
| 296 | ec->curr = NULL; | 311 | ec->curr = NULL; |
| 297 | spin_unlock_irqrestore(&ec->lock, tmp); | 312 | spin_unlock_irqrestore(&ec->lock, tmp); |
| 298 | return ret; | 313 | return ret; |
| @@ -1015,6 +1030,10 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { | |||
| 1015 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | 1030 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), |
| 1016 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, | 1031 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, |
| 1017 | { | 1032 | { |
| 1033 | ec_flag_msi, "Clevo W350etq", { | ||
| 1034 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO CO."), | ||
| 1035 | DMI_MATCH(DMI_PRODUCT_NAME, "W35_37ET"),}, NULL}, | ||
| 1036 | { | ||
| 1018 | ec_validate_ecdt, "ASUS hardware", { | 1037 | ec_validate_ecdt, "ASUS hardware", { |
| 1019 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 1038 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
| 1020 | { | 1039 | { |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index c96887d5289e..6e6b80eb0bba 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
| @@ -484,6 +484,10 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
| 484 | /* Keep IOAPIC pin configuration when suspending */ | 484 | /* Keep IOAPIC pin configuration when suspending */ |
| 485 | if (dev->dev.power.is_prepared) | 485 | if (dev->dev.power.is_prepared) |
| 486 | return; | 486 | return; |
| 487 | #ifdef CONFIG_PM_RUNTIME | ||
| 488 | if (dev->dev.power.runtime_status == RPM_SUSPENDING) | ||
| 489 | return; | ||
| 490 | #endif | ||
| 487 | 491 | ||
| 488 | entry = acpi_pci_irq_lookup(dev, pin); | 492 | entry = acpi_pci_irq_lookup(dev, pin); |
| 489 | if (!entry) | 493 | if (!entry) |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 3dca36d4ad26..17f9ec501972 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -1071,9 +1071,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1071 | 1071 | ||
| 1072 | if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) { | 1072 | if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) { |
| 1073 | 1073 | ||
| 1074 | cpuidle_pause_and_lock(); | ||
| 1075 | /* Protect against cpu-hotplug */ | 1074 | /* Protect against cpu-hotplug */ |
| 1076 | get_online_cpus(); | 1075 | get_online_cpus(); |
| 1076 | cpuidle_pause_and_lock(); | ||
| 1077 | 1077 | ||
| 1078 | /* Disable all cpuidle devices */ | 1078 | /* Disable all cpuidle devices */ |
| 1079 | for_each_online_cpu(cpu) { | 1079 | for_each_online_cpu(cpu) { |
| @@ -1100,8 +1100,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1100 | cpuidle_enable_device(dev); | 1100 | cpuidle_enable_device(dev); |
| 1101 | } | 1101 | } |
| 1102 | } | 1102 | } |
| 1103 | put_online_cpus(); | ||
| 1104 | cpuidle_resume_and_unlock(); | 1103 | cpuidle_resume_and_unlock(); |
| 1104 | put_online_cpus(); | ||
| 1105 | } | 1105 | } |
| 1106 | 1106 | ||
| 1107 | return 0; | 1107 | return 0; |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0a817ad24f16..3bf7764659a4 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -667,8 +667,14 @@ static ssize_t | |||
| 667 | acpi_device_sun_show(struct device *dev, struct device_attribute *attr, | 667 | acpi_device_sun_show(struct device *dev, struct device_attribute *attr, |
| 668 | char *buf) { | 668 | char *buf) { |
| 669 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 669 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
| 670 | acpi_status status; | ||
| 671 | unsigned long long sun; | ||
| 672 | |||
| 673 | status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); | ||
| 674 | if (ACPI_FAILURE(status)) | ||
| 675 | return -ENODEV; | ||
| 670 | 676 | ||
| 671 | return sprintf(buf, "%lu\n", acpi_dev->pnp.sun); | 677 | return sprintf(buf, "%llu\n", sun); |
| 672 | } | 678 | } |
| 673 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); | 679 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); |
| 674 | 680 | ||
| @@ -690,7 +696,6 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
| 690 | { | 696 | { |
| 691 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 697 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
| 692 | acpi_status status; | 698 | acpi_status status; |
| 693 | unsigned long long sun; | ||
| 694 | int result = 0; | 699 | int result = 0; |
| 695 | 700 | ||
| 696 | /* | 701 | /* |
| @@ -731,14 +736,10 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
| 731 | if (dev->pnp.unique_id) | 736 | if (dev->pnp.unique_id) |
| 732 | result = device_create_file(&dev->dev, &dev_attr_uid); | 737 | result = device_create_file(&dev->dev, &dev_attr_uid); |
| 733 | 738 | ||
| 734 | status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun); | 739 | if (acpi_has_method(dev->handle, "_SUN")) { |
| 735 | if (ACPI_SUCCESS(status)) { | ||
| 736 | dev->pnp.sun = (unsigned long)sun; | ||
| 737 | result = device_create_file(&dev->dev, &dev_attr_sun); | 740 | result = device_create_file(&dev->dev, &dev_attr_sun); |
| 738 | if (result) | 741 | if (result) |
| 739 | goto end; | 742 | goto end; |
| 740 | } else { | ||
| 741 | dev->pnp.sun = (unsigned long)-1; | ||
| 742 | } | 743 | } |
| 743 | 744 | ||
| 744 | if (acpi_has_method(dev->handle, "_STA")) { | 745 | if (acpi_has_method(dev->handle, "_STA")) { |
| @@ -922,12 +923,17 @@ static void acpi_device_notify(acpi_handle handle, u32 event, void *data) | |||
| 922 | device->driver->ops.notify(device, event); | 923 | device->driver->ops.notify(device, event); |
| 923 | } | 924 | } |
| 924 | 925 | ||
| 925 | static acpi_status acpi_device_notify_fixed(void *data) | 926 | static void acpi_device_notify_fixed(void *data) |
| 926 | { | 927 | { |
| 927 | struct acpi_device *device = data; | 928 | struct acpi_device *device = data; |
| 928 | 929 | ||
| 929 | /* Fixed hardware devices have no handles */ | 930 | /* Fixed hardware devices have no handles */ |
| 930 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); | 931 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); |
| 932 | } | ||
| 933 | |||
| 934 | static acpi_status acpi_device_fixed_event(void *data) | ||
| 935 | { | ||
| 936 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); | ||
| 931 | return AE_OK; | 937 | return AE_OK; |
| 932 | } | 938 | } |
| 933 | 939 | ||
| @@ -938,12 +944,12 @@ static int acpi_device_install_notify_handler(struct acpi_device *device) | |||
| 938 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) | 944 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
| 939 | status = | 945 | status = |
| 940 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | 946 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, |
| 941 | acpi_device_notify_fixed, | 947 | acpi_device_fixed_event, |
| 942 | device); | 948 | device); |
| 943 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) | 949 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
| 944 | status = | 950 | status = |
| 945 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | 951 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, |
| 946 | acpi_device_notify_fixed, | 952 | acpi_device_fixed_event, |
| 947 | device); | 953 | device); |
| 948 | else | 954 | else |
| 949 | status = acpi_install_notify_handler(device->handle, | 955 | status = acpi_install_notify_handler(device->handle, |
| @@ -960,10 +966,10 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) | |||
| 960 | { | 966 | { |
| 961 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) | 967 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
| 962 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | 968 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, |
| 963 | acpi_device_notify_fixed); | 969 | acpi_device_fixed_event); |
| 964 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) | 970 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
| 965 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | 971 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, |
| 966 | acpi_device_notify_fixed); | 972 | acpi_device_fixed_event); |
| 967 | else | 973 | else |
| 968 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | 974 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, |
| 969 | acpi_device_notify); | 975 | acpi_device_notify); |
| @@ -975,7 +981,7 @@ static int acpi_device_probe(struct device *dev) | |||
| 975 | struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); | 981 | struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); |
| 976 | int ret; | 982 | int ret; |
| 977 | 983 | ||
| 978 | if (acpi_dev->handler) | 984 | if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) |
| 979 | return -EINVAL; | 985 | return -EINVAL; |
| 980 | 986 | ||
| 981 | if (!acpi_drv->ops.add) | 987 | if (!acpi_drv->ops.add) |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 826884392e6b..fcbda105616e 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -82,9 +82,9 @@ module_param(allow_duplicates, bool, 0644); | |||
| 82 | * For Windows 8 systems: used to decide if video module | 82 | * For Windows 8 systems: used to decide if video module |
| 83 | * should skip registering backlight interface of its own. | 83 | * should skip registering backlight interface of its own. |
| 84 | */ | 84 | */ |
| 85 | static int use_native_backlight_param = 1; | 85 | static int use_native_backlight_param = -1; |
| 86 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); | 86 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); |
| 87 | static bool use_native_backlight_dmi = false; | 87 | static bool use_native_backlight_dmi = true; |
| 88 | 88 | ||
| 89 | static int register_count; | 89 | static int register_count; |
| 90 | static struct mutex video_list_lock; | 90 | static struct mutex video_list_lock; |
| @@ -417,6 +417,12 @@ static int __init video_set_use_native_backlight(const struct dmi_system_id *d) | |||
| 417 | return 0; | 417 | return 0; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | static int __init video_disable_native_backlight(const struct dmi_system_id *d) | ||
| 421 | { | ||
| 422 | use_native_backlight_dmi = false; | ||
| 423 | return 0; | ||
| 424 | } | ||
| 425 | |||
| 420 | static struct dmi_system_id video_dmi_table[] __initdata = { | 426 | static struct dmi_system_id video_dmi_table[] __initdata = { |
| 421 | /* | 427 | /* |
| 422 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | 428 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 |
| @@ -720,6 +726,41 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
| 720 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | 726 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), |
| 721 | }, | 727 | }, |
| 722 | }, | 728 | }, |
| 729 | |||
| 730 | /* | ||
| 731 | * These models have a working acpi_video backlight control, and using | ||
| 732 | * native backlight causes a regression where backlight does not work | ||
| 733 | * when userspace is not handling brightness key events. Disable | ||
| 734 | * native_backlight on these to fix this: | ||
| 735 | * https://bugzilla.kernel.org/show_bug.cgi?id=81691 | ||
| 736 | */ | ||
| 737 | { | ||
| 738 | .callback = video_disable_native_backlight, | ||
| 739 | .ident = "ThinkPad T420", | ||
| 740 | .matches = { | ||
| 741 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 742 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"), | ||
| 743 | }, | ||
| 744 | }, | ||
| 745 | { | ||
| 746 | .callback = video_disable_native_backlight, | ||
| 747 | .ident = "ThinkPad T520", | ||
| 748 | .matches = { | ||
| 749 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 750 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), | ||
| 751 | }, | ||
| 752 | }, | ||
| 753 | |||
| 754 | /* The native backlight controls do not work on some older machines */ | ||
| 755 | { | ||
| 756 | /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */ | ||
| 757 | .callback = video_disable_native_backlight, | ||
| 758 | .ident = "HP ENVY 15 Notebook", | ||
| 759 | .matches = { | ||
| 760 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 761 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), | ||
| 762 | }, | ||
| 763 | }, | ||
| 723 | {} | 764 | {} |
| 724 | }; | 765 | }; |
| 725 | 766 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a29f8012fb08..a0cc0edafc78 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -305,6 +305,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 305 | { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */ | 305 | { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */ |
| 306 | { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */ | 306 | { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */ |
| 307 | { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */ | 307 | { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */ |
| 308 | { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */ | ||
| 309 | { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */ | ||
| 310 | { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */ | ||
| 311 | { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */ | ||
| 312 | { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */ | ||
| 313 | { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ | ||
| 314 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ | ||
| 315 | { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ | ||
| 308 | 316 | ||
| 309 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 317 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
| 310 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 318 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| @@ -442,6 +450,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 442 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), | 450 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), |
| 443 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ | 451 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ |
| 444 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172), | 452 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172), |
| 453 | .driver_data = board_ahci_yes_fbs }, /* 88se9182 */ | ||
| 454 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9182), | ||
| 445 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ | 455 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ |
| 446 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), | 456 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), |
| 447 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ | 457 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ |
| @@ -1329,6 +1339,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1329 | else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) | 1339 | else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) |
| 1330 | ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; | 1340 | ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; |
| 1331 | 1341 | ||
| 1342 | /* | ||
| 1343 | * The JMicron chip 361/363 contains one SATA controller and one | ||
| 1344 | * PATA controller,for powering on these both controllers, we must | ||
| 1345 | * follow the sequence one by one, otherwise one of them can not be | ||
| 1346 | * powered on successfully, so here we disable the async suspend | ||
| 1347 | * method for these chips. | ||
| 1348 | */ | ||
| 1349 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && | ||
| 1350 | (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 || | ||
| 1351 | pdev->device == PCI_DEVICE_ID_JMICRON_JMB361)) | ||
| 1352 | device_disable_async_suspend(&pdev->dev); | ||
| 1353 | |||
| 1332 | /* acquire resources */ | 1354 | /* acquire resources */ |
| 1333 | rc = pcim_enable_device(pdev); | 1355 | rc = pcim_enable_device(pdev); |
| 1334 | if (rc) | 1356 | if (rc) |
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c index fc3df47fca35..032904402c95 100644 --- a/drivers/ata/ahci_tegra.c +++ b/drivers/ata/ahci_tegra.c | |||
| @@ -18,14 +18,17 @@ | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/ahci_platform.h> | 20 | #include <linux/ahci_platform.h> |
| 21 | #include <linux/reset.h> | ||
| 22 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
| 23 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 24 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 25 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
| 26 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 27 | #include <linux/tegra-powergate.h> | ||
| 28 | #include <linux/regulator/consumer.h> | 26 | #include <linux/regulator/consumer.h> |
| 27 | #include <linux/reset.h> | ||
| 28 | |||
| 29 | #include <soc/tegra/fuse.h> | ||
| 30 | #include <soc/tegra/pmc.h> | ||
| 31 | |||
| 29 | #include "ahci.h" | 32 | #include "ahci.h" |
| 30 | 33 | ||
| 31 | #define SATA_CONFIGURATION_0 0x180 | 34 | #define SATA_CONFIGURATION_0 0x180 |
| @@ -180,9 +183,12 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) | |||
| 180 | 183 | ||
| 181 | /* Pad calibration */ | 184 | /* Pad calibration */ |
| 182 | 185 | ||
| 183 | /* FIXME Always use calibration 0. Change this to read the calibration | 186 | ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val); |
| 184 | * fuse once the fuse driver has landed. */ | 187 | if (ret) { |
| 185 | val = 0; | 188 | dev_err(&tegra->pdev->dev, |
| 189 | "failed to read calibration fuse: %d\n", ret); | ||
| 190 | return ret; | ||
| 191 | } | ||
| 186 | 192 | ||
| 187 | calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; | 193 | calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; |
| 188 | 194 | ||
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index bc281115490b..f03aab187f4d 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
| @@ -78,6 +78,9 @@ | |||
| 78 | #define CFG_MEM_RAM_SHUTDOWN 0x00000070 | 78 | #define CFG_MEM_RAM_SHUTDOWN 0x00000070 |
| 79 | #define BLOCK_MEM_RDY 0x00000074 | 79 | #define BLOCK_MEM_RDY 0x00000074 |
| 80 | 80 | ||
| 81 | /* Max retry for link down */ | ||
| 82 | #define MAX_LINK_DOWN_RETRY 3 | ||
| 83 | |||
| 81 | struct xgene_ahci_context { | 84 | struct xgene_ahci_context { |
| 82 | struct ahci_host_priv *hpriv; | 85 | struct ahci_host_priv *hpriv; |
| 83 | struct device *dev; | 86 | struct device *dev; |
| @@ -145,6 +148,14 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) | |||
| 145 | return rc; | 148 | return rc; |
| 146 | } | 149 | } |
| 147 | 150 | ||
| 151 | static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx) | ||
| 152 | { | ||
| 153 | void __iomem *diagcsr = ctx->csr_diag; | ||
| 154 | |||
| 155 | return (readl(diagcsr + CFG_MEM_RAM_SHUTDOWN) == 0 && | ||
| 156 | readl(diagcsr + BLOCK_MEM_RDY) == 0xFFFFFFFF); | ||
| 157 | } | ||
| 158 | |||
| 148 | /** | 159 | /** |
| 149 | * xgene_ahci_read_id - Read ID data from the specified device | 160 | * xgene_ahci_read_id - Read ID data from the specified device |
| 150 | * @dev: device | 161 | * @dev: device |
| @@ -229,8 +240,11 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel) | |||
| 229 | * and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will | 240 | * and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will |
| 230 | * report disparity error and etc. In addition, during COMRESET, there can | 241 | * report disparity error and etc. In addition, during COMRESET, there can |
| 231 | * be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and | 242 | * be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and |
| 232 | * SERR_10B_8B_ERR, the PHY receiver line must be reseted. The following | 243 | * SERR_10B_8B_ERR, the PHY receiver line must be reseted. Also during long |
| 233 | * algorithm is followed to proper configure the hardware PHY during COMRESET: | 244 | * reboot cycle regression, sometimes the PHY reports link down even if the |
| 245 | * device is present because of speed negotiation failure. so need to retry | ||
| 246 | * the COMRESET to get the link up. The following algorithm is followed to | ||
| 247 | * proper configure the hardware PHY during COMRESET: | ||
| 234 | * | 248 | * |
| 235 | * Alg Part 1: | 249 | * Alg Part 1: |
| 236 | * 1. Start the PHY at Gen3 speed (default setting) | 250 | * 1. Start the PHY at Gen3 speed (default setting) |
| @@ -246,9 +260,15 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel) | |||
| 246 | * Alg Part 2: | 260 | * Alg Part 2: |
| 247 | * 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error | 261 | * 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error |
| 248 | * reported in the register PORT_SCR_ERR, then reset the PHY receiver line | 262 | * reported in the register PORT_SCR_ERR, then reset the PHY receiver line |
| 249 | * 2. Go to Alg Part 3 | 263 | * 2. Go to Alg Part 4 |
| 250 | * | 264 | * |
| 251 | * Alg Part 3: | 265 | * Alg Part 3: |
| 266 | * 1. Check the PORT_SCR_STAT to see whether device presence detected but PHY | ||
| 267 | * communication establishment failed and maximum link down attempts are | ||
| 268 | * less than Max attempts 3 then goto Alg Part 1. | ||
| 269 | * 2. Go to Alg Part 4. | ||
| 270 | * | ||
| 271 | * Alg Part 4: | ||
| 252 | * 1. Clear any pending from register PORT_SCR_ERR. | 272 | * 1. Clear any pending from register PORT_SCR_ERR. |
| 253 | * | 273 | * |
| 254 | * NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition | 274 | * NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition |
| @@ -267,19 +287,27 @@ static int xgene_ahci_do_hardreset(struct ata_link *link, | |||
| 267 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 287 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
| 268 | void __iomem *port_mmio = ahci_port_base(ap); | 288 | void __iomem *port_mmio = ahci_port_base(ap); |
| 269 | struct ata_taskfile tf; | 289 | struct ata_taskfile tf; |
| 290 | int link_down_retry = 0; | ||
| 270 | int rc; | 291 | int rc; |
| 271 | u32 val; | 292 | u32 val, sstatus; |
| 272 | 293 | ||
| 273 | /* clear D2H reception area to properly wait for D2H FIS */ | 294 | do { |
| 274 | ata_tf_init(link->device, &tf); | 295 | /* clear D2H reception area to properly wait for D2H FIS */ |
| 275 | tf.command = ATA_BUSY; | 296 | ata_tf_init(link->device, &tf); |
| 276 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 297 | tf.command = ATA_BUSY; |
| 277 | rc = sata_link_hardreset(link, timing, deadline, online, | 298 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
| 299 | rc = sata_link_hardreset(link, timing, deadline, online, | ||
| 278 | ahci_check_ready); | 300 | ahci_check_ready); |
| 301 | if (*online) { | ||
| 302 | val = readl(port_mmio + PORT_SCR_ERR); | ||
| 303 | if (val & (SERR_DISPARITY | SERR_10B_8B_ERR)) | ||
| 304 | dev_warn(ctx->dev, "link has error\n"); | ||
| 305 | break; | ||
| 306 | } | ||
| 279 | 307 | ||
| 280 | val = readl(port_mmio + PORT_SCR_ERR); | 308 | sata_scr_read(link, SCR_STATUS, &sstatus); |
| 281 | if (val & (SERR_DISPARITY | SERR_10B_8B_ERR)) | 309 | } while (link_down_retry++ < MAX_LINK_DOWN_RETRY && |
| 282 | dev_warn(ctx->dev, "link has error\n"); | 310 | (sstatus & 0xff) == 0x1); |
| 283 | 311 | ||
| 284 | /* clear all errors if any pending */ | 312 | /* clear all errors if any pending */ |
| 285 | val = readl(port_mmio + PORT_SCR_ERR); | 313 | val = readl(port_mmio + PORT_SCR_ERR); |
| @@ -344,7 +372,7 @@ static struct ata_port_operations xgene_ahci_ops = { | |||
| 344 | }; | 372 | }; |
| 345 | 373 | ||
| 346 | static const struct ata_port_info xgene_ahci_port_info = { | 374 | static const struct ata_port_info xgene_ahci_port_info = { |
| 347 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, | 375 | .flags = AHCI_FLAG_COMMON, |
| 348 | .pio_mask = ATA_PIO4, | 376 | .pio_mask = ATA_PIO4, |
| 349 | .udma_mask = ATA_UDMA6, | 377 | .udma_mask = ATA_UDMA6, |
| 350 | .port_ops = &xgene_ahci_ops, | 378 | .port_ops = &xgene_ahci_ops, |
| @@ -467,6 +495,11 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
| 467 | return -ENODEV; | 495 | return -ENODEV; |
| 468 | } | 496 | } |
| 469 | 497 | ||
| 498 | if (xgene_ahci_is_memram_inited(ctx)) { | ||
| 499 | dev_info(dev, "skip clock and PHY initialization\n"); | ||
| 500 | goto skip_clk_phy; | ||
| 501 | } | ||
| 502 | |||
| 470 | /* Due to errata, HW requires full toggle transition */ | 503 | /* Due to errata, HW requires full toggle transition */ |
| 471 | rc = ahci_platform_enable_clks(hpriv); | 504 | rc = ahci_platform_enable_clks(hpriv); |
| 472 | if (rc) | 505 | if (rc) |
| @@ -479,8 +512,8 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
| 479 | 512 | ||
| 480 | /* Configure the host controller */ | 513 | /* Configure the host controller */ |
| 481 | xgene_ahci_hw_init(hpriv); | 514 | xgene_ahci_hw_init(hpriv); |
| 482 | 515 | skip_clk_phy: | |
| 483 | hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ; | 516 | hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; |
| 484 | 517 | ||
| 485 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); | 518 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); |
| 486 | if (rc) | 519 | if (rc) |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 893e30e9a9ef..ffbe625e6fd2 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -340,6 +340,14 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
| 340 | { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, | 340 | { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, |
| 341 | /* SATA Controller IDE (Coleto Creek) */ | 341 | /* SATA Controller IDE (Coleto Creek) */ |
| 342 | { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 342 | { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| 343 | /* SATA Controller IDE (9 Series) */ | ||
| 344 | { 0x8086, 0x8c88, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, | ||
| 345 | /* SATA Controller IDE (9 Series) */ | ||
| 346 | { 0x8086, 0x8c89, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, | ||
| 347 | /* SATA Controller IDE (9 Series) */ | ||
| 348 | { 0x8086, 0x8c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
| 349 | /* SATA Controller IDE (9 Series) */ | ||
| 350 | { 0x8086, 0x8c81, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
| 343 | 351 | ||
| 344 | { } /* terminate list */ | 352 | { } /* terminate list */ |
| 345 | }; | 353 | }; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dbdc5d32343f..f3e7b9f894cd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4228,7 +4228,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4228 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4228 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
| 4229 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4229 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
| 4230 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4230 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
| 4231 | { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4231 | { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
| 4232 | 4232 | ||
| 4233 | /* | 4233 | /* |
| 4234 | * Some WD SATA-I drives spin up and down erratically when the link | 4234 | * Some WD SATA-I drives spin up and down erratically when the link |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 4d1a5d2c4287..47e418b8c8ba 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
| @@ -143,6 +143,18 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
| 143 | }; | 143 | }; |
| 144 | const struct ata_port_info *ppi[] = { &info, NULL }; | 144 | const struct ata_port_info *ppi[] = { &info, NULL }; |
| 145 | 145 | ||
| 146 | /* | ||
| 147 | * The JMicron chip 361/363 contains one SATA controller and one | ||
| 148 | * PATA controller,for powering on these both controllers, we must | ||
| 149 | * follow the sequence one by one, otherwise one of them can not be | ||
| 150 | * powered on successfully, so here we disable the async suspend | ||
| 151 | * method for these chips. | ||
| 152 | */ | ||
| 153 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && | ||
| 154 | (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 || | ||
| 155 | pdev->device == PCI_DEVICE_ID_JMICRON_JMB361)) | ||
| 156 | device_disable_async_suspend(&pdev->dev); | ||
| 157 | |||
| 146 | return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); | 158 | return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); |
| 147 | } | 159 | } |
| 148 | 160 | ||
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 2578fc16960a..1a24a5dc3940 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c | |||
| @@ -360,7 +360,7 @@ static int pata_s3c_wait_after_reset(struct ata_link *link, | |||
| 360 | /* | 360 | /* |
| 361 | * pata_s3c_bus_softreset - PATA device software reset | 361 | * pata_s3c_bus_softreset - PATA device software reset |
| 362 | */ | 362 | */ |
| 363 | static unsigned int pata_s3c_bus_softreset(struct ata_port *ap, | 363 | static int pata_s3c_bus_softreset(struct ata_port *ap, |
| 364 | unsigned long deadline) | 364 | unsigned long deadline) |
| 365 | { | 365 | { |
| 366 | struct ata_ioports *ioaddr = &ap->ioaddr; | 366 | struct ata_ioports *ioaddr = &ap->ioaddr; |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 4e006d74bef8..7f4cb76ed9fa 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
| @@ -585,7 +585,7 @@ static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, | |||
| 585 | * Note: Original code is ata_bus_softreset(). | 585 | * Note: Original code is ata_bus_softreset(). |
| 586 | */ | 586 | */ |
| 587 | 587 | ||
| 588 | static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | 588 | static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, |
| 589 | unsigned long deadline) | 589 | unsigned long deadline) |
| 590 | { | 590 | { |
| 591 | struct ata_ioports *ioaddr = &ap->ioaddr; | 591 | struct ata_ioports *ioaddr = &ap->ioaddr; |
| @@ -599,9 +599,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | |||
| 599 | udelay(20); | 599 | udelay(20); |
| 600 | out_be32(ioaddr->ctl_addr, ap->ctl); | 600 | out_be32(ioaddr->ctl_addr, ap->ctl); |
| 601 | 601 | ||
| 602 | scc_wait_after_reset(&ap->link, devmask, deadline); | 602 | return scc_wait_after_reset(&ap->link, devmask, deadline); |
| 603 | |||
| 604 | return 0; | ||
| 605 | } | 603 | } |
| 606 | 604 | ||
| 607 | /** | 605 | /** |
| @@ -618,7 +616,8 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, | |||
| 618 | { | 616 | { |
| 619 | struct ata_port *ap = link->ap; | 617 | struct ata_port *ap = link->ap; |
| 620 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; | 618 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; |
| 621 | unsigned int devmask = 0, err_mask; | 619 | unsigned int devmask = 0; |
| 620 | int rc; | ||
| 622 | u8 err; | 621 | u8 err; |
| 623 | 622 | ||
| 624 | DPRINTK("ENTER\n"); | 623 | DPRINTK("ENTER\n"); |
| @@ -634,9 +633,9 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, | |||
| 634 | 633 | ||
| 635 | /* issue bus reset */ | 634 | /* issue bus reset */ |
| 636 | DPRINTK("about to softreset, devmask=%x\n", devmask); | 635 | DPRINTK("about to softreset, devmask=%x\n", devmask); |
| 637 | err_mask = scc_bus_softreset(ap, devmask, deadline); | 636 | rc = scc_bus_softreset(ap, devmask, deadline); |
| 638 | if (err_mask) { | 637 | if (rc) { |
| 639 | ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", err_mask); | 638 | ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc); |
| 640 | return -EIO; | 639 | return -EIO; |
| 641 | } | 640 | } |
| 642 | 641 | ||
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 7d1326985bee..bfc90b8547f2 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
| @@ -146,6 +146,9 @@ struct regcache_ops { | |||
| 146 | enum regcache_type type; | 146 | enum regcache_type type; |
| 147 | int (*init)(struct regmap *map); | 147 | int (*init)(struct regmap *map); |
| 148 | int (*exit)(struct regmap *map); | 148 | int (*exit)(struct regmap *map); |
| 149 | #ifdef CONFIG_DEBUG_FS | ||
| 150 | void (*debugfs_init)(struct regmap *map); | ||
| 151 | #endif | ||
| 149 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); | 152 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); |
| 150 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); | 153 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); |
| 151 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); | 154 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 6a7e4fa12854..f3e8fe0cc650 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
| @@ -194,10 +194,6 @@ static void rbtree_debugfs_init(struct regmap *map) | |||
| 194 | { | 194 | { |
| 195 | debugfs_create_file("rbtree", 0400, map->debugfs, map, &rbtree_fops); | 195 | debugfs_create_file("rbtree", 0400, map->debugfs, map, &rbtree_fops); |
| 196 | } | 196 | } |
| 197 | #else | ||
| 198 | static void rbtree_debugfs_init(struct regmap *map) | ||
| 199 | { | ||
| 200 | } | ||
| 201 | #endif | 197 | #endif |
| 202 | 198 | ||
| 203 | static int regcache_rbtree_init(struct regmap *map) | 199 | static int regcache_rbtree_init(struct regmap *map) |
| @@ -222,8 +218,6 @@ static int regcache_rbtree_init(struct regmap *map) | |||
| 222 | goto err; | 218 | goto err; |
| 223 | } | 219 | } |
| 224 | 220 | ||
| 225 | rbtree_debugfs_init(map); | ||
| 226 | |||
| 227 | return 0; | 221 | return 0; |
| 228 | 222 | ||
| 229 | err: | 223 | err: |
| @@ -532,6 +526,9 @@ struct regcache_ops regcache_rbtree_ops = { | |||
| 532 | .name = "rbtree", | 526 | .name = "rbtree", |
| 533 | .init = regcache_rbtree_init, | 527 | .init = regcache_rbtree_init, |
| 534 | .exit = regcache_rbtree_exit, | 528 | .exit = regcache_rbtree_exit, |
| 529 | #ifdef CONFIG_DEBUG_FS | ||
| 530 | .debugfs_init = rbtree_debugfs_init, | ||
| 531 | #endif | ||
| 535 | .read = regcache_rbtree_read, | 532 | .read = regcache_rbtree_read, |
| 536 | .write = regcache_rbtree_write, | 533 | .write = regcache_rbtree_write, |
| 537 | .sync = regcache_rbtree_sync, | 534 | .sync = regcache_rbtree_sync, |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 29b4128da0b0..5617da6dc898 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
| @@ -698,7 +698,7 @@ int regcache_sync_block(struct regmap *map, void *block, | |||
| 698 | unsigned int block_base, unsigned int start, | 698 | unsigned int block_base, unsigned int start, |
| 699 | unsigned int end) | 699 | unsigned int end) |
| 700 | { | 700 | { |
| 701 | if (regmap_can_raw_write(map)) | 701 | if (regmap_can_raw_write(map) && !map->use_single_rw) |
| 702 | return regcache_sync_block_raw(map, block, cache_present, | 702 | return regcache_sync_block_raw(map, block, cache_present, |
| 703 | block_base, start, end); | 703 | block_base, start, end); |
| 704 | else | 704 | else |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 45d812c0ea77..65ea7b256b3e 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
| @@ -538,6 +538,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name) | |||
| 538 | 538 | ||
| 539 | next = rb_next(&range_node->node); | 539 | next = rb_next(&range_node->node); |
| 540 | } | 540 | } |
| 541 | |||
| 542 | if (map->cache_ops && map->cache_ops->debugfs_init) | ||
| 543 | map->cache_ops->debugfs_init(map); | ||
| 541 | } | 544 | } |
| 542 | 545 | ||
| 543 | void regmap_debugfs_exit(struct regmap *map) | 546 | void regmap_debugfs_exit(struct regmap *map) |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 78f43fb2fe84..1cf427bc0d4a 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
| @@ -109,7 +109,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) | |||
| 109 | 109 | ||
| 110 | bool regmap_volatile(struct regmap *map, unsigned int reg) | 110 | bool regmap_volatile(struct regmap *map, unsigned int reg) |
| 111 | { | 111 | { |
| 112 | if (!regmap_readable(map, reg)) | 112 | if (!map->format.format_write && !regmap_readable(map, reg)) |
| 113 | return false; | 113 | return false; |
| 114 | 114 | ||
| 115 | if (map->volatile_reg) | 115 | if (map->volatile_reg) |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 294a7dd25190..f032ed6dd459 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
| @@ -282,6 +282,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { | |||
| 282 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, | 282 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, |
| 283 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, | 283 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, |
| 284 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 284 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
| 285 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xA8DB */ | ||
| 285 | { 0, }, | 286 | { 0, }, |
| 286 | }; | 287 | }; |
| 287 | MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); | 288 | MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); |
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index c7d138eca731..3598110d2cef 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
| @@ -442,12 +442,15 @@ static int rd_nr; | |||
| 442 | int rd_size = CONFIG_BLK_DEV_RAM_SIZE; | 442 | int rd_size = CONFIG_BLK_DEV_RAM_SIZE; |
| 443 | static int max_part; | 443 | static int max_part; |
| 444 | static int part_shift; | 444 | static int part_shift; |
| 445 | static int part_show = 0; | ||
| 445 | module_param(rd_nr, int, S_IRUGO); | 446 | module_param(rd_nr, int, S_IRUGO); |
| 446 | MODULE_PARM_DESC(rd_nr, "Maximum number of brd devices"); | 447 | MODULE_PARM_DESC(rd_nr, "Maximum number of brd devices"); |
| 447 | module_param(rd_size, int, S_IRUGO); | 448 | module_param(rd_size, int, S_IRUGO); |
| 448 | MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes."); | 449 | MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes."); |
| 449 | module_param(max_part, int, S_IRUGO); | 450 | module_param(max_part, int, S_IRUGO); |
| 450 | MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); | 451 | MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); |
| 452 | module_param(part_show, int, S_IRUGO); | ||
| 453 | MODULE_PARM_DESC(part_show, "Control RAM disk visibility in /proc/partitions"); | ||
| 451 | MODULE_LICENSE("GPL"); | 454 | MODULE_LICENSE("GPL"); |
| 452 | MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); | 455 | MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); |
| 453 | MODULE_ALIAS("rd"); | 456 | MODULE_ALIAS("rd"); |
| @@ -501,7 +504,8 @@ static struct brd_device *brd_alloc(int i) | |||
| 501 | disk->fops = &brd_fops; | 504 | disk->fops = &brd_fops; |
| 502 | disk->private_data = brd; | 505 | disk->private_data = brd; |
| 503 | disk->queue = brd->brd_queue; | 506 | disk->queue = brd->brd_queue; |
| 504 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | 507 | if (!part_show) |
| 508 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | ||
| 505 | sprintf(disk->disk_name, "ram%d", i); | 509 | sprintf(disk->disk_name, "ram%d", i); |
| 506 | set_capacity(disk, rd_size * 2); | 510 | set_capacity(disk, rd_size * 2); |
| 507 | 511 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index db1e9560d8a7..5c8e7fe07745 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
| @@ -3918,7 +3918,6 @@ skip_create_disk: | |||
| 3918 | if (rv) { | 3918 | if (rv) { |
| 3919 | dev_err(&dd->pdev->dev, | 3919 | dev_err(&dd->pdev->dev, |
| 3920 | "Unable to allocate request queue\n"); | 3920 | "Unable to allocate request queue\n"); |
| 3921 | rv = -ENOMEM; | ||
| 3922 | goto block_queue_alloc_init_error; | 3921 | goto block_queue_alloc_init_error; |
| 3923 | } | 3922 | } |
| 3924 | 3923 | ||
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index a3b042c4d448..00d469c7f9f7 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -462,17 +462,21 @@ static int null_add_dev(void) | |||
| 462 | struct gendisk *disk; | 462 | struct gendisk *disk; |
| 463 | struct nullb *nullb; | 463 | struct nullb *nullb; |
| 464 | sector_t size; | 464 | sector_t size; |
| 465 | int rv; | ||
| 465 | 466 | ||
| 466 | nullb = kzalloc_node(sizeof(*nullb), GFP_KERNEL, home_node); | 467 | nullb = kzalloc_node(sizeof(*nullb), GFP_KERNEL, home_node); |
| 467 | if (!nullb) | 468 | if (!nullb) { |
| 469 | rv = -ENOMEM; | ||
| 468 | goto out; | 470 | goto out; |
| 471 | } | ||
| 469 | 472 | ||
| 470 | spin_lock_init(&nullb->lock); | 473 | spin_lock_init(&nullb->lock); |
| 471 | 474 | ||
| 472 | if (queue_mode == NULL_Q_MQ && use_per_node_hctx) | 475 | if (queue_mode == NULL_Q_MQ && use_per_node_hctx) |
| 473 | submit_queues = nr_online_nodes; | 476 | submit_queues = nr_online_nodes; |
| 474 | 477 | ||
| 475 | if (setup_queues(nullb)) | 478 | rv = setup_queues(nullb); |
| 479 | if (rv) | ||
| 476 | goto out_free_nullb; | 480 | goto out_free_nullb; |
| 477 | 481 | ||
| 478 | if (queue_mode == NULL_Q_MQ) { | 482 | if (queue_mode == NULL_Q_MQ) { |
| @@ -484,22 +488,29 @@ static int null_add_dev(void) | |||
| 484 | nullb->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; | 488 | nullb->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
| 485 | nullb->tag_set.driver_data = nullb; | 489 | nullb->tag_set.driver_data = nullb; |
| 486 | 490 | ||
| 487 | if (blk_mq_alloc_tag_set(&nullb->tag_set)) | 491 | rv = blk_mq_alloc_tag_set(&nullb->tag_set); |
| 492 | if (rv) | ||
| 488 | goto out_cleanup_queues; | 493 | goto out_cleanup_queues; |
| 489 | 494 | ||
| 490 | nullb->q = blk_mq_init_queue(&nullb->tag_set); | 495 | nullb->q = blk_mq_init_queue(&nullb->tag_set); |
| 491 | if (!nullb->q) | 496 | if (!nullb->q) { |
| 497 | rv = -ENOMEM; | ||
| 492 | goto out_cleanup_tags; | 498 | goto out_cleanup_tags; |
| 499 | } | ||
| 493 | } else if (queue_mode == NULL_Q_BIO) { | 500 | } else if (queue_mode == NULL_Q_BIO) { |
| 494 | nullb->q = blk_alloc_queue_node(GFP_KERNEL, home_node); | 501 | nullb->q = blk_alloc_queue_node(GFP_KERNEL, home_node); |
| 495 | if (!nullb->q) | 502 | if (!nullb->q) { |
| 503 | rv = -ENOMEM; | ||
| 496 | goto out_cleanup_queues; | 504 | goto out_cleanup_queues; |
| 505 | } | ||
| 497 | blk_queue_make_request(nullb->q, null_queue_bio); | 506 | blk_queue_make_request(nullb->q, null_queue_bio); |
| 498 | init_driver_queues(nullb); | 507 | init_driver_queues(nullb); |
| 499 | } else { | 508 | } else { |
| 500 | nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node); | 509 | nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node); |
| 501 | if (!nullb->q) | 510 | if (!nullb->q) { |
| 511 | rv = -ENOMEM; | ||
| 502 | goto out_cleanup_queues; | 512 | goto out_cleanup_queues; |
| 513 | } | ||
| 503 | blk_queue_prep_rq(nullb->q, null_rq_prep_fn); | 514 | blk_queue_prep_rq(nullb->q, null_rq_prep_fn); |
| 504 | blk_queue_softirq_done(nullb->q, null_softirq_done_fn); | 515 | blk_queue_softirq_done(nullb->q, null_softirq_done_fn); |
| 505 | init_driver_queues(nullb); | 516 | init_driver_queues(nullb); |
| @@ -509,8 +520,10 @@ static int null_add_dev(void) | |||
| 509 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, nullb->q); | 520 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, nullb->q); |
| 510 | 521 | ||
| 511 | disk = nullb->disk = alloc_disk_node(1, home_node); | 522 | disk = nullb->disk = alloc_disk_node(1, home_node); |
| 512 | if (!disk) | 523 | if (!disk) { |
| 524 | rv = -ENOMEM; | ||
| 513 | goto out_cleanup_blk_queue; | 525 | goto out_cleanup_blk_queue; |
| 526 | } | ||
| 514 | 527 | ||
| 515 | mutex_lock(&lock); | 528 | mutex_lock(&lock); |
| 516 | list_add_tail(&nullb->list, &nullb_list); | 529 | list_add_tail(&nullb->list, &nullb_list); |
| @@ -544,7 +557,7 @@ out_cleanup_queues: | |||
| 544 | out_free_nullb: | 557 | out_free_nullb: |
| 545 | kfree(nullb); | 558 | kfree(nullb); |
| 546 | out: | 559 | out: |
| 547 | return -ENOMEM; | 560 | return rv; |
| 548 | } | 561 | } |
| 549 | 562 | ||
| 550 | static int __init null_init(void) | 563 | static int __init null_init(void) |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 623c84145b79..4b97baf8afa3 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -5087,9 +5087,11 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) | |||
| 5087 | set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); | 5087 | set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); |
| 5088 | set_disk_ro(rbd_dev->disk, rbd_dev->mapping.read_only); | 5088 | set_disk_ro(rbd_dev->disk, rbd_dev->mapping.read_only); |
| 5089 | 5089 | ||
| 5090 | rbd_dev->rq_wq = alloc_workqueue(rbd_dev->disk->disk_name, 0, 0); | 5090 | rbd_dev->rq_wq = alloc_workqueue("%s", 0, 0, rbd_dev->disk->disk_name); |
| 5091 | if (!rbd_dev->rq_wq) | 5091 | if (!rbd_dev->rq_wq) { |
| 5092 | ret = -ENOMEM; | ||
| 5092 | goto err_out_mapping; | 5093 | goto err_out_mapping; |
| 5094 | } | ||
| 5093 | 5095 | ||
| 5094 | ret = rbd_bus_add_dev(rbd_dev); | 5096 | ret = rbd_bus_add_dev(rbd_dev); |
| 5095 | if (ret) | 5097 | if (ret) |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index ab3ea62e5dfc..c4328d9d9981 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
| @@ -1203,7 +1203,6 @@ static struct platform_driver ace_platform_driver = { | |||
| 1203 | .probe = ace_probe, | 1203 | .probe = ace_probe, |
| 1204 | .remove = ace_remove, | 1204 | .remove = ace_remove, |
| 1205 | .driver = { | 1205 | .driver = { |
| 1206 | .owner = THIS_MODULE, | ||
| 1207 | .name = "xsysace", | 1206 | .name = "xsysace", |
| 1208 | .of_match_table = ace_of_match, | 1207 | .of_match_table = ace_of_match, |
| 1209 | }, | 1208 | }, |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index dfa4024c448a..d00831c3d731 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
| @@ -378,7 +378,6 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) | |||
| 378 | /* Should NEVER happen. Return bio error if it does. */ | 378 | /* Should NEVER happen. Return bio error if it does. */ |
| 379 | if (unlikely(ret)) { | 379 | if (unlikely(ret)) { |
| 380 | pr_err("Decompression failed! err=%d, page=%u\n", ret, index); | 380 | pr_err("Decompression failed! err=%d, page=%u\n", ret, index); |
| 381 | atomic64_inc(&zram->stats.failed_reads); | ||
| 382 | return ret; | 381 | return ret; |
| 383 | } | 382 | } |
| 384 | 383 | ||
| @@ -547,8 +546,6 @@ out: | |||
| 547 | zcomp_strm_release(zram->comp, zstrm); | 546 | zcomp_strm_release(zram->comp, zstrm); |
| 548 | if (is_partial_io(bvec)) | 547 | if (is_partial_io(bvec)) |
| 549 | kfree(uncmem); | 548 | kfree(uncmem); |
| 550 | if (ret) | ||
| 551 | atomic64_inc(&zram->stats.failed_writes); | ||
| 552 | return ret; | 549 | return ret; |
| 553 | } | 550 | } |
| 554 | 551 | ||
| @@ -566,6 +563,13 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
| 566 | ret = zram_bvec_write(zram, bvec, index, offset); | 563 | ret = zram_bvec_write(zram, bvec, index, offset); |
| 567 | } | 564 | } |
| 568 | 565 | ||
| 566 | if (unlikely(ret)) { | ||
| 567 | if (rw == READ) | ||
| 568 | atomic64_inc(&zram->stats.failed_reads); | ||
| 569 | else | ||
| 570 | atomic64_inc(&zram->stats.failed_writes); | ||
| 571 | } | ||
| 572 | |||
| 569 | return ret; | 573 | return ret; |
| 570 | } | 574 | } |
| 571 | 575 | ||
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 5b0afde729cd..e0f725c87cc6 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h | |||
| @@ -84,7 +84,7 @@ struct zram_stats { | |||
| 84 | atomic64_t compr_data_size; /* compressed size of pages stored */ | 84 | atomic64_t compr_data_size; /* compressed size of pages stored */ |
| 85 | atomic64_t num_reads; /* failed + successful */ | 85 | atomic64_t num_reads; /* failed + successful */ |
| 86 | atomic64_t num_writes; /* --do-- */ | 86 | atomic64_t num_writes; /* --do-- */ |
| 87 | atomic64_t failed_reads; /* should NEVER! happen */ | 87 | atomic64_t failed_reads; /* can happen when memory is too low */ |
| 88 | atomic64_t failed_writes; /* can happen when memory is too low */ | 88 | atomic64_t failed_writes; /* can happen when memory is too low */ |
| 89 | atomic64_t invalid_io; /* non-page-aligned I/O requests */ | 89 | atomic64_t invalid_io; /* non-page-aligned I/O requests */ |
| 90 | atomic64_t notify_free; /* no. of swap slot free notifications */ | 90 | atomic64_t notify_free; /* no. of swap slot free notifications */ |
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c index 3266f8ff9311..a60f26400705 100644 --- a/drivers/bus/arm-ccn.c +++ b/drivers/bus/arm-ccn.c | |||
| @@ -586,6 +586,30 @@ static int arm_ccn_pmu_type_eq(u32 a, u32 b) | |||
| 586 | return 0; | 586 | return 0; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | static void arm_ccn_pmu_event_destroy(struct perf_event *event) | ||
| 590 | { | ||
| 591 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
| 592 | struct hw_perf_event *hw = &event->hw; | ||
| 593 | |||
| 594 | if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) { | ||
| 595 | clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask); | ||
| 596 | } else { | ||
| 597 | struct arm_ccn_component *source = | ||
| 598 | ccn->dt.pmu_counters[hw->idx].source; | ||
| 599 | |||
| 600 | if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP && | ||
| 601 | CCN_CONFIG_EVENT(event->attr.config) == | ||
| 602 | CCN_EVENT_WATCHPOINT) | ||
| 603 | clear_bit(hw->config_base, source->xp.dt_cmp_mask); | ||
| 604 | else | ||
| 605 | clear_bit(hw->config_base, source->pmu_events_mask); | ||
| 606 | clear_bit(hw->idx, ccn->dt.pmu_counters_mask); | ||
| 607 | } | ||
| 608 | |||
| 609 | ccn->dt.pmu_counters[hw->idx].source = NULL; | ||
| 610 | ccn->dt.pmu_counters[hw->idx].event = NULL; | ||
| 611 | } | ||
| 612 | |||
| 589 | static int arm_ccn_pmu_event_init(struct perf_event *event) | 613 | static int arm_ccn_pmu_event_init(struct perf_event *event) |
| 590 | { | 614 | { |
| 591 | struct arm_ccn *ccn; | 615 | struct arm_ccn *ccn; |
| @@ -599,6 +623,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event) | |||
| 599 | return -ENOENT; | 623 | return -ENOENT; |
| 600 | 624 | ||
| 601 | ccn = pmu_to_arm_ccn(event->pmu); | 625 | ccn = pmu_to_arm_ccn(event->pmu); |
| 626 | event->destroy = arm_ccn_pmu_event_destroy; | ||
| 602 | 627 | ||
| 603 | if (hw->sample_period) { | 628 | if (hw->sample_period) { |
| 604 | dev_warn(ccn->dev, "Sampling not supported!\n"); | 629 | dev_warn(ccn->dev, "Sampling not supported!\n"); |
| @@ -662,7 +687,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event) | |||
| 662 | } | 687 | } |
| 663 | if (e->num_vcs && vc >= e->num_vcs) { | 688 | if (e->num_vcs && vc >= e->num_vcs) { |
| 664 | dev_warn(ccn->dev, "Invalid vc %d for node/XP %d!\n", | 689 | dev_warn(ccn->dev, "Invalid vc %d for node/XP %d!\n", |
| 665 | port, node_xp); | 690 | vc, node_xp); |
| 666 | return -EINVAL; | 691 | return -EINVAL; |
| 667 | } | 692 | } |
| 668 | valid = 1; | 693 | valid = 1; |
| @@ -731,30 +756,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event) | |||
| 731 | return 0; | 756 | return 0; |
| 732 | } | 757 | } |
| 733 | 758 | ||
| 734 | static void arm_ccn_pmu_event_free(struct perf_event *event) | ||
| 735 | { | ||
| 736 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
| 737 | struct hw_perf_event *hw = &event->hw; | ||
| 738 | |||
| 739 | if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) { | ||
| 740 | clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask); | ||
| 741 | } else { | ||
| 742 | struct arm_ccn_component *source = | ||
| 743 | ccn->dt.pmu_counters[hw->idx].source; | ||
| 744 | |||
| 745 | if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP && | ||
| 746 | CCN_CONFIG_EVENT(event->attr.config) == | ||
| 747 | CCN_EVENT_WATCHPOINT) | ||
| 748 | clear_bit(hw->config_base, source->xp.dt_cmp_mask); | ||
| 749 | else | ||
| 750 | clear_bit(hw->config_base, source->pmu_events_mask); | ||
| 751 | clear_bit(hw->idx, ccn->dt.pmu_counters_mask); | ||
| 752 | } | ||
| 753 | |||
| 754 | ccn->dt.pmu_counters[hw->idx].source = NULL; | ||
| 755 | ccn->dt.pmu_counters[hw->idx].event = NULL; | ||
| 756 | } | ||
| 757 | |||
| 758 | static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx) | 759 | static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx) |
| 759 | { | 760 | { |
| 760 | u64 res; | 761 | u64 res; |
| @@ -1027,8 +1028,6 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) | |||
| 1027 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) | 1028 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) |
| 1028 | { | 1029 | { |
| 1029 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); | 1030 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); |
| 1030 | |||
| 1031 | arm_ccn_pmu_event_free(event); | ||
| 1032 | } | 1031 | } |
| 1033 | 1032 | ||
| 1034 | static void arm_ccn_pmu_event_read(struct perf_event *event) | 1033 | static void arm_ccn_pmu_event_read(struct perf_event *event) |
diff --git a/drivers/cpufreq/cpufreq_opp.c b/drivers/cpufreq/cpufreq_opp.c index f7a32d2326c6..773bcde893c0 100644 --- a/drivers/cpufreq/cpufreq_opp.c +++ b/drivers/cpufreq/cpufreq_opp.c | |||
| @@ -60,7 +60,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, | |||
| 60 | goto out; | 60 | goto out; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | freq_table = kcalloc(sizeof(*freq_table), (max_opps + 1), GFP_ATOMIC); | 63 | freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_ATOMIC); |
| 64 | if (!freq_table) { | 64 | if (!freq_table) { |
| 65 | ret = -ENOMEM; | 65 | ret = -ENOMEM; |
| 66 | goto out; | 66 | goto out; |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index c5eac949760d..0668b389c516 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -660,6 +660,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
| 660 | ICPU(0x3f, core_params), | 660 | ICPU(0x3f, core_params), |
| 661 | ICPU(0x45, core_params), | 661 | ICPU(0x45, core_params), |
| 662 | ICPU(0x46, core_params), | 662 | ICPU(0x46, core_params), |
| 663 | ICPU(0x4c, byt_params), | ||
| 663 | ICPU(0x4f, core_params), | 664 | ICPU(0x4f, core_params), |
| 664 | ICPU(0x56, core_params), | 665 | ICPU(0x56, core_params), |
| 665 | {} | 666 | {} |
| @@ -688,7 +689,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
| 688 | 689 | ||
| 689 | add_timer_on(&cpu->timer, cpunum); | 690 | add_timer_on(&cpu->timer, cpunum); |
| 690 | 691 | ||
| 691 | pr_info("Intel pstate controlling: cpu %d\n", cpunum); | 692 | pr_debug("Intel pstate controlling: cpu %d\n", cpunum); |
| 692 | 693 | ||
| 693 | return 0; | 694 | return 0; |
| 694 | } | 695 | } |
| @@ -707,10 +708,6 @@ static unsigned int intel_pstate_get(unsigned int cpu_num) | |||
| 707 | 708 | ||
| 708 | static int intel_pstate_set_policy(struct cpufreq_policy *policy) | 709 | static int intel_pstate_set_policy(struct cpufreq_policy *policy) |
| 709 | { | 710 | { |
| 710 | struct cpudata *cpu; | ||
| 711 | |||
| 712 | cpu = all_cpu_data[policy->cpu]; | ||
| 713 | |||
| 714 | if (!policy->cpuinfo.max_freq) | 711 | if (!policy->cpuinfo.max_freq) |
| 715 | return -ENODEV; | 712 | return -ENODEV; |
| 716 | 713 | ||
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 9a68225a757e..3f9791f07b8e 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
| @@ -501,7 +501,7 @@ static int check_mem_type(void __iomem *dmc_reg) | |||
| 501 | return val >> 8; | 501 | return val >> 8; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | 504 | static int s5pv210_cpu_init(struct cpufreq_policy *policy) |
| 505 | { | 505 | { |
| 506 | unsigned long mem_type; | 506 | unsigned long mem_type; |
| 507 | int ret; | 507 | int ret; |
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index 344d79fa3407..ef94c3b81f18 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c | |||
| @@ -138,25 +138,18 @@ static int bl_enter_powerdown(struct cpuidle_device *dev, | |||
| 138 | return idx; | 138 | return idx; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id) | 141 | static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int part_id) |
| 142 | { | 142 | { |
| 143 | struct cpuinfo_arm *cpu_info; | ||
| 144 | struct cpumask *cpumask; | 143 | struct cpumask *cpumask; |
| 145 | unsigned long cpuid; | ||
| 146 | int cpu; | 144 | int cpu; |
| 147 | 145 | ||
| 148 | cpumask = kzalloc(cpumask_size(), GFP_KERNEL); | 146 | cpumask = kzalloc(cpumask_size(), GFP_KERNEL); |
| 149 | if (!cpumask) | 147 | if (!cpumask) |
| 150 | return -ENOMEM; | 148 | return -ENOMEM; |
| 151 | 149 | ||
| 152 | for_each_possible_cpu(cpu) { | 150 | for_each_possible_cpu(cpu) |
| 153 | cpu_info = &per_cpu(cpu_data, cpu); | 151 | if (smp_cpuid_part(cpu) == part_id) |
| 154 | cpuid = is_smp() ? cpu_info->cpuid : read_cpuid_id(); | ||
| 155 | |||
| 156 | /* read cpu id part number */ | ||
| 157 | if ((cpuid & 0xFFF0) == cpu_id) | ||
| 158 | cpumask_set_cpu(cpu, cpumask); | 152 | cpumask_set_cpu(cpu, cpumask); |
| 159 | } | ||
| 160 | 153 | ||
| 161 | drv->cpumask = cpumask; | 154 | drv->cpumask = cpumask; |
| 162 | 155 | ||
diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c index 4222cb2aa96a..7bb9d65d9a2c 100644 --- a/drivers/dma-buf/fence.c +++ b/drivers/dma-buf/fence.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on); | 29 | EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on); |
| 30 | EXPORT_TRACEPOINT_SYMBOL(fence_emit); | 30 | EXPORT_TRACEPOINT_SYMBOL(fence_emit); |
| 31 | 31 | ||
| 32 | /** | 32 | /* |
| 33 | * fence context counter: each execution context should have its own | 33 | * fence context counter: each execution context should have its own |
| 34 | * fence context, this allows checking if fences belong to the same | 34 | * fence context, this allows checking if fences belong to the same |
| 35 | * context or not. One device can have multiple separate contexts, | 35 | * context or not. One device can have multiple separate contexts, |
diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index 6a9d89c93b1f..ae2ab14e64b3 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c | |||
| @@ -362,8 +362,9 @@ static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan) | |||
| 362 | vchan_cyclic_callback(&chan->desc->vdesc); | 362 | vchan_cyclic_callback(&chan->desc->vdesc); |
| 363 | } else { | 363 | } else { |
| 364 | if (chan->next_sg == chan->desc->num_sgs) { | 364 | if (chan->next_sg == chan->desc->num_sgs) { |
| 365 | chan->desc = NULL; | 365 | list_del(&chan->desc->vdesc.node); |
| 366 | vchan_cookie_complete(&chan->desc->vdesc); | 366 | vchan_cookie_complete(&chan->desc->vdesc); |
| 367 | chan->desc = NULL; | ||
| 367 | } | 368 | } |
| 368 | } | 369 | } |
| 369 | } | 370 | } |
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index f0a43646a2f3..5abe943e3404 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c | |||
| @@ -481,7 +481,7 @@ EXPORT_SYMBOL_GPL(efivar_entry_remove); | |||
| 481 | */ | 481 | */ |
| 482 | static void efivar_entry_list_del_unlock(struct efivar_entry *entry) | 482 | static void efivar_entry_list_del_unlock(struct efivar_entry *entry) |
| 483 | { | 483 | { |
| 484 | WARN_ON(!spin_is_locked(&__efivars->lock)); | 484 | lockdep_assert_held(&__efivars->lock); |
| 485 | 485 | ||
| 486 | list_del(&entry->list); | 486 | list_del(&entry->list); |
| 487 | spin_unlock_irq(&__efivars->lock); | 487 | spin_unlock_irq(&__efivars->lock); |
| @@ -507,7 +507,7 @@ int __efivar_entry_delete(struct efivar_entry *entry) | |||
| 507 | const struct efivar_operations *ops = __efivars->ops; | 507 | const struct efivar_operations *ops = __efivars->ops; |
| 508 | efi_status_t status; | 508 | efi_status_t status; |
| 509 | 509 | ||
| 510 | WARN_ON(!spin_is_locked(&__efivars->lock)); | 510 | lockdep_assert_held(&__efivars->lock); |
| 511 | 511 | ||
| 512 | status = ops->set_variable(entry->var.VariableName, | 512 | status = ops->set_variable(entry->var.VariableName, |
| 513 | &entry->var.VendorGuid, | 513 | &entry->var.VendorGuid, |
| @@ -667,7 +667,7 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid, | |||
| 667 | int strsize1, strsize2; | 667 | int strsize1, strsize2; |
| 668 | bool found = false; | 668 | bool found = false; |
| 669 | 669 | ||
| 670 | WARN_ON(!spin_is_locked(&__efivars->lock)); | 670 | lockdep_assert_held(&__efivars->lock); |
| 671 | 671 | ||
| 672 | list_for_each_entry_safe(entry, n, head, list) { | 672 | list_for_each_entry_safe(entry, n, head, list) { |
| 673 | strsize1 = ucs2_strsize(name, 1024); | 673 | strsize1 = ucs2_strsize(name, 1024); |
| @@ -739,7 +739,7 @@ int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, | |||
| 739 | const struct efivar_operations *ops = __efivars->ops; | 739 | const struct efivar_operations *ops = __efivars->ops; |
| 740 | efi_status_t status; | 740 | efi_status_t status; |
| 741 | 741 | ||
| 742 | WARN_ON(!spin_is_locked(&__efivars->lock)); | 742 | lockdep_assert_held(&__efivars->lock); |
| 743 | 743 | ||
| 744 | status = ops->get_variable(entry->var.VariableName, | 744 | status = ops->get_variable(entry->var.VariableName, |
| 745 | &entry->var.VendorGuid, | 745 | &entry->var.VendorGuid, |
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 41b2f40578d5..954b9f6b0ef8 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c | |||
| @@ -90,7 +90,7 @@ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev, | |||
| 90 | struct gpio_desc **dr; | 90 | struct gpio_desc **dr; |
| 91 | struct gpio_desc *desc; | 91 | struct gpio_desc *desc; |
| 92 | 92 | ||
| 93 | dr = devres_alloc(devm_gpiod_release, sizeof(struct gpiod_desc *), | 93 | dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), |
| 94 | GFP_KERNEL); | 94 | GFP_KERNEL); |
| 95 | if (!dr) | 95 | if (!dr) |
| 96 | return ERR_PTR(-ENOMEM); | 96 | return ERR_PTR(-ENOMEM); |
diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/gpio-bt8xx.c index 6557147d9331..7e4c43c18960 100644 --- a/drivers/gpio/gpio-bt8xx.c +++ b/drivers/gpio/gpio-bt8xx.c | |||
| @@ -241,9 +241,6 @@ static void bt8xxgpio_remove(struct pci_dev *pdev) | |||
| 241 | bgwrite(~0x0, BT848_INT_STAT); | 241 | bgwrite(~0x0, BT848_INT_STAT); |
| 242 | bgwrite(0x0, BT848_GPIO_OUT_EN); | 242 | bgwrite(0x0, BT848_GPIO_OUT_EN); |
| 243 | 243 | ||
| 244 | iounmap(bg->mmio); | ||
| 245 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 246 | pci_resource_len(pdev, 0)); | ||
| 247 | pci_disable_device(pdev); | 244 | pci_disable_device(pdev); |
| 248 | } | 245 | } |
| 249 | 246 | ||
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index ff9eb911b5e4..fa945ec9ccff 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c | |||
| @@ -407,9 +407,27 @@ static int lp_gpio_runtime_resume(struct device *dev) | |||
| 407 | return 0; | 407 | return 0; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | static int lp_gpio_resume(struct device *dev) | ||
| 411 | { | ||
| 412 | struct platform_device *pdev = to_platform_device(dev); | ||
| 413 | struct lp_gpio *lg = platform_get_drvdata(pdev); | ||
| 414 | unsigned long reg; | ||
| 415 | int i; | ||
| 416 | |||
| 417 | /* on some hardware suspend clears input sensing, re-enable it here */ | ||
| 418 | for (i = 0; i < lg->chip.ngpio; i++) { | ||
| 419 | if (gpiochip_is_requested(&lg->chip, i) != NULL) { | ||
| 420 | reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2); | ||
| 421 | outl(inl(reg) & ~GPINDIS_BIT, reg); | ||
| 422 | } | ||
| 423 | } | ||
| 424 | return 0; | ||
| 425 | } | ||
| 426 | |||
| 410 | static const struct dev_pm_ops lp_gpio_pm_ops = { | 427 | static const struct dev_pm_ops lp_gpio_pm_ops = { |
| 411 | .runtime_suspend = lp_gpio_runtime_suspend, | 428 | .runtime_suspend = lp_gpio_runtime_suspend, |
| 412 | .runtime_resume = lp_gpio_runtime_resume, | 429 | .runtime_resume = lp_gpio_runtime_resume, |
| 430 | .resume = lp_gpio_resume, | ||
| 413 | }; | 431 | }; |
| 414 | 432 | ||
| 415 | static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { | 433 | static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { |
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index c3145f91fda3..31ad5df5dbc9 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
| @@ -95,6 +95,9 @@ struct zynq_gpio { | |||
| 95 | struct clk *clk; | 95 | struct clk *clk; |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | static struct irq_chip zynq_gpio_level_irqchip; | ||
| 99 | static struct irq_chip zynq_gpio_edge_irqchip; | ||
| 100 | |||
| 98 | /** | 101 | /** |
| 99 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank | 102 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank |
| 100 | * for a given pin in the GPIO device | 103 | * for a given pin in the GPIO device |
| @@ -410,6 +413,15 @@ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type) | |||
| 410 | gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); | 413 | gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); |
| 411 | writel_relaxed(int_any, | 414 | writel_relaxed(int_any, |
| 412 | gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); | 415 | gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
| 416 | |||
| 417 | if (type & IRQ_TYPE_LEVEL_MASK) { | ||
| 418 | __irq_set_chip_handler_name_locked(irq_data->irq, | ||
| 419 | &zynq_gpio_level_irqchip, handle_fasteoi_irq, NULL); | ||
| 420 | } else { | ||
| 421 | __irq_set_chip_handler_name_locked(irq_data->irq, | ||
| 422 | &zynq_gpio_edge_irqchip, handle_level_irq, NULL); | ||
| 423 | } | ||
| 424 | |||
| 413 | return 0; | 425 | return 0; |
| 414 | } | 426 | } |
| 415 | 427 | ||
| @@ -424,9 +436,21 @@ static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) | |||
| 424 | } | 436 | } |
| 425 | 437 | ||
| 426 | /* irq chip descriptor */ | 438 | /* irq chip descriptor */ |
| 427 | static struct irq_chip zynq_gpio_irqchip = { | 439 | static struct irq_chip zynq_gpio_level_irqchip = { |
| 428 | .name = DRIVER_NAME, | 440 | .name = DRIVER_NAME, |
| 429 | .irq_enable = zynq_gpio_irq_enable, | 441 | .irq_enable = zynq_gpio_irq_enable, |
| 442 | .irq_eoi = zynq_gpio_irq_ack, | ||
| 443 | .irq_mask = zynq_gpio_irq_mask, | ||
| 444 | .irq_unmask = zynq_gpio_irq_unmask, | ||
| 445 | .irq_set_type = zynq_gpio_set_irq_type, | ||
| 446 | .irq_set_wake = zynq_gpio_set_wake, | ||
| 447 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | ||
| 448 | }; | ||
| 449 | |||
| 450 | static struct irq_chip zynq_gpio_edge_irqchip = { | ||
| 451 | .name = DRIVER_NAME, | ||
| 452 | .irq_enable = zynq_gpio_irq_enable, | ||
| 453 | .irq_ack = zynq_gpio_irq_ack, | ||
| 430 | .irq_mask = zynq_gpio_irq_mask, | 454 | .irq_mask = zynq_gpio_irq_mask, |
| 431 | .irq_unmask = zynq_gpio_irq_unmask, | 455 | .irq_unmask = zynq_gpio_irq_unmask, |
| 432 | .irq_set_type = zynq_gpio_set_irq_type, | 456 | .irq_set_type = zynq_gpio_set_irq_type, |
| @@ -469,10 +493,6 @@ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) | |||
| 469 | offset); | 493 | offset); |
| 470 | generic_handle_irq(gpio_irq); | 494 | generic_handle_irq(gpio_irq); |
| 471 | } | 495 | } |
| 472 | |||
| 473 | /* clear IRQ in HW */ | ||
| 474 | writel_relaxed(int_sts, gpio->base_addr + | ||
| 475 | ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); | ||
| 476 | } | 496 | } |
| 477 | } | 497 | } |
| 478 | 498 | ||
| @@ -610,14 +630,14 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
| 610 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + | 630 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + |
| 611 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); | 631 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); |
| 612 | 632 | ||
| 613 | ret = gpiochip_irqchip_add(chip, &zynq_gpio_irqchip, 0, | 633 | ret = gpiochip_irqchip_add(chip, &zynq_gpio_edge_irqchip, 0, |
| 614 | handle_simple_irq, IRQ_TYPE_NONE); | 634 | handle_level_irq, IRQ_TYPE_NONE); |
| 615 | if (ret) { | 635 | if (ret) { |
| 616 | dev_err(&pdev->dev, "Failed to add irq chip\n"); | 636 | dev_err(&pdev->dev, "Failed to add irq chip\n"); |
| 617 | goto err_rm_gpiochip; | 637 | goto err_rm_gpiochip; |
| 618 | } | 638 | } |
| 619 | 639 | ||
| 620 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_irqchip, irq, | 640 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, irq, |
| 621 | zynq_gpio_irqhandler); | 641 | zynq_gpio_irqhandler); |
| 622 | 642 | ||
| 623 | pm_runtime_set_active(&pdev->dev); | 643 | pm_runtime_set_active(&pdev->dev); |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 7cfdc2278905..604dbe60bdee 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -307,7 +307,5 @@ void of_gpiochip_add(struct gpio_chip *chip) | |||
| 307 | void of_gpiochip_remove(struct gpio_chip *chip) | 307 | void of_gpiochip_remove(struct gpio_chip *chip) |
| 308 | { | 308 | { |
| 309 | gpiochip_remove_pin_ranges(chip); | 309 | gpiochip_remove_pin_ranges(chip); |
| 310 | 310 | of_node_put(chip->of_node); | |
| 311 | if (chip->of_node) | ||
| 312 | of_node_put(chip->of_node); | ||
| 313 | } | 311 | } |
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index a2cc6be97983..b792194e0d9c 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c | |||
| @@ -67,6 +67,7 @@ static int ast_detect_chip(struct drm_device *dev) | |||
| 67 | { | 67 | { |
| 68 | struct ast_private *ast = dev->dev_private; | 68 | struct ast_private *ast = dev->dev_private; |
| 69 | uint32_t data, jreg; | 69 | uint32_t data, jreg; |
| 70 | ast_open_key(ast); | ||
| 70 | 71 | ||
| 71 | if (dev->pdev->device == PCI_CHIP_AST1180) { | 72 | if (dev->pdev->device == PCI_CHIP_AST1180) { |
| 72 | ast->chip = AST1100; | 73 | ast->chip = AST1100; |
| @@ -104,7 +105,7 @@ static int ast_detect_chip(struct drm_device *dev) | |||
| 104 | } | 105 | } |
| 105 | ast->vga2_clone = false; | 106 | ast->vga2_clone = false; |
| 106 | } else { | 107 | } else { |
| 107 | ast->chip = 2000; | 108 | ast->chip = AST2000; |
| 108 | DRM_INFO("AST 2000 detected\n"); | 109 | DRM_INFO("AST 2000 detected\n"); |
| 109 | } | 110 | } |
| 110 | } | 111 | } |
diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h index 4c761dcea972..05c01ea85294 100644 --- a/drivers/gpu/drm/ast/ast_tables.h +++ b/drivers/gpu/drm/ast/ast_tables.h | |||
| @@ -99,6 +99,7 @@ static struct ast_vbios_dclk_info dclk_table[] = { | |||
| 99 | {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */ | 99 | {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */ |
| 100 | {0x77, 0x58, 0x80}, /* 17: VCLK119 */ | 100 | {0x77, 0x58, 0x80}, /* 17: VCLK119 */ |
| 101 | {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */ | 101 | {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */ |
| 102 | {0x6a, 0x6d, 0x80}, /* 19: VCLK97_75 */ | ||
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | static struct ast_vbios_stdtable vbios_stdtable[] = { | 105 | static struct ast_vbios_stdtable vbios_stdtable[] = { |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fa2be249999c..90e773019eac 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -4696,8 +4696,9 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, | |||
| 4696 | return -EINVAL; | 4696 | return -EINVAL; |
| 4697 | 4697 | ||
| 4698 | /* overflow checks for 32bit size calculations */ | 4698 | /* overflow checks for 32bit size calculations */ |
| 4699 | /* NOTE: DIV_ROUND_UP() can overflow */ | ||
| 4699 | cpp = DIV_ROUND_UP(args->bpp, 8); | 4700 | cpp = DIV_ROUND_UP(args->bpp, 8); |
| 4700 | if (cpp > 0xffffffffU / args->width) | 4701 | if (!cpp || cpp > 0xffffffffU / args->width) |
| 4701 | return -EINVAL; | 4702 | return -EINVAL; |
| 4702 | stride = cpp * args->width; | 4703 | stride = cpp * args->width; |
| 4703 | if (args->height > 0xffffffffU / stride) | 4704 | if (args->height > 0xffffffffU / stride) |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2e7f03ad5ee2..9933c26017ed 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1336,12 +1336,17 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
| 1336 | 1336 | ||
| 1337 | intel_power_domains_init_hw(dev_priv); | 1337 | intel_power_domains_init_hw(dev_priv); |
| 1338 | 1338 | ||
| 1339 | /* | ||
| 1340 | * We enable some interrupt sources in our postinstall hooks, so mark | ||
| 1341 | * interrupts as enabled _before_ actually enabling them to avoid | ||
| 1342 | * special cases in our ordering checks. | ||
| 1343 | */ | ||
| 1344 | dev_priv->pm._irqs_disabled = false; | ||
| 1345 | |||
| 1339 | ret = drm_irq_install(dev, dev->pdev->irq); | 1346 | ret = drm_irq_install(dev, dev->pdev->irq); |
| 1340 | if (ret) | 1347 | if (ret) |
| 1341 | goto cleanup_gem_stolen; | 1348 | goto cleanup_gem_stolen; |
| 1342 | 1349 | ||
| 1343 | dev_priv->pm._irqs_disabled = false; | ||
| 1344 | |||
| 1345 | /* Important: The output setup functions called by modeset_init need | 1350 | /* Important: The output setup functions called by modeset_init need |
| 1346 | * working irqs for e.g. gmbus and dp aux transfers. */ | 1351 | * working irqs for e.g. gmbus and dp aux transfers. */ |
| 1347 | intel_modeset_init(dev); | 1352 | intel_modeset_init(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ec96f9a9724c..e27cdbe9d524 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -494,6 +494,36 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
| 494 | return true; | 494 | return true; |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) | ||
| 498 | { | ||
| 499 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 500 | |||
| 501 | dev_priv->long_hpd_port_mask = 0; | ||
| 502 | dev_priv->short_hpd_port_mask = 0; | ||
| 503 | dev_priv->hpd_event_bits = 0; | ||
| 504 | |||
| 505 | spin_unlock_irq(&dev_priv->irq_lock); | ||
| 506 | |||
| 507 | cancel_work_sync(&dev_priv->dig_port_work); | ||
| 508 | cancel_work_sync(&dev_priv->hotplug_work); | ||
| 509 | cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); | ||
| 510 | } | ||
| 511 | |||
| 512 | static void intel_suspend_encoders(struct drm_i915_private *dev_priv) | ||
| 513 | { | ||
| 514 | struct drm_device *dev = dev_priv->dev; | ||
| 515 | struct drm_encoder *encoder; | ||
| 516 | |||
| 517 | drm_modeset_lock_all(dev); | ||
| 518 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 519 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | ||
| 520 | |||
| 521 | if (intel_encoder->suspend) | ||
| 522 | intel_encoder->suspend(intel_encoder); | ||
| 523 | } | ||
| 524 | drm_modeset_unlock_all(dev); | ||
| 525 | } | ||
| 526 | |||
| 497 | static int i915_drm_freeze(struct drm_device *dev) | 527 | static int i915_drm_freeze(struct drm_device *dev) |
| 498 | { | 528 | { |
| 499 | struct drm_i915_private *dev_priv = dev->dev_private; | 529 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -538,6 +568,9 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
| 538 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | 568 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); |
| 539 | 569 | ||
| 540 | intel_runtime_pm_disable_interrupts(dev); | 570 | intel_runtime_pm_disable_interrupts(dev); |
| 571 | intel_hpd_cancel_work(dev_priv); | ||
| 572 | |||
| 573 | intel_suspend_encoders(dev_priv); | ||
| 541 | 574 | ||
| 542 | intel_suspend_gt_powersave(dev); | 575 | intel_suspend_gt_powersave(dev); |
| 543 | 576 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4412f6a4383b..3524306d8cfb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -184,6 +184,7 @@ enum hpd_pin { | |||
| 184 | if ((1 << (domain)) & (mask)) | 184 | if ((1 << (domain)) & (mask)) |
| 185 | 185 | ||
| 186 | struct drm_i915_private; | 186 | struct drm_i915_private; |
| 187 | struct i915_mm_struct; | ||
| 187 | struct i915_mmu_object; | 188 | struct i915_mmu_object; |
| 188 | 189 | ||
| 189 | enum intel_dpll_id { | 190 | enum intel_dpll_id { |
| @@ -1458,7 +1459,7 @@ struct drm_i915_private { | |||
| 1458 | } hpd_mark; | 1459 | } hpd_mark; |
| 1459 | } hpd_stats[HPD_NUM_PINS]; | 1460 | } hpd_stats[HPD_NUM_PINS]; |
| 1460 | u32 hpd_event_bits; | 1461 | u32 hpd_event_bits; |
| 1461 | struct timer_list hotplug_reenable_timer; | 1462 | struct delayed_work hotplug_reenable_work; |
| 1462 | 1463 | ||
| 1463 | struct i915_fbc fbc; | 1464 | struct i915_fbc fbc; |
| 1464 | struct i915_drrs drrs; | 1465 | struct i915_drrs drrs; |
| @@ -1506,9 +1507,8 @@ struct drm_i915_private { | |||
| 1506 | struct i915_gtt gtt; /* VM representing the global address space */ | 1507 | struct i915_gtt gtt; /* VM representing the global address space */ |
| 1507 | 1508 | ||
| 1508 | struct i915_gem_mm mm; | 1509 | struct i915_gem_mm mm; |
| 1509 | #if defined(CONFIG_MMU_NOTIFIER) | 1510 | DECLARE_HASHTABLE(mm_structs, 7); |
| 1510 | DECLARE_HASHTABLE(mmu_notifiers, 7); | 1511 | struct mutex mm_lock; |
| 1511 | #endif | ||
| 1512 | 1512 | ||
| 1513 | /* Kernel Modesetting */ | 1513 | /* Kernel Modesetting */ |
| 1514 | 1514 | ||
| @@ -1814,8 +1814,8 @@ struct drm_i915_gem_object { | |||
| 1814 | unsigned workers :4; | 1814 | unsigned workers :4; |
| 1815 | #define I915_GEM_USERPTR_MAX_WORKERS 15 | 1815 | #define I915_GEM_USERPTR_MAX_WORKERS 15 |
| 1816 | 1816 | ||
| 1817 | struct mm_struct *mm; | 1817 | struct i915_mm_struct *mm; |
| 1818 | struct i915_mmu_object *mn; | 1818 | struct i915_mmu_object *mmu_object; |
| 1819 | struct work_struct *work; | 1819 | struct work_struct *work; |
| 1820 | } userptr; | 1820 | } userptr; |
| 1821 | }; | 1821 | }; |
| @@ -2178,6 +2178,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | |||
| 2178 | extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); | 2178 | extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); |
| 2179 | extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); | 2179 | extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); |
| 2180 | int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on); | 2180 | int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on); |
| 2181 | void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); | ||
| 2181 | 2182 | ||
| 2182 | extern void intel_console_resume(struct work_struct *work); | 2183 | extern void intel_console_resume(struct work_struct *work); |
| 2183 | 2184 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ba7f5c6bb50d..ad55b06a3cb1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1590,10 +1590,13 @@ unlock: | |||
| 1590 | out: | 1590 | out: |
| 1591 | switch (ret) { | 1591 | switch (ret) { |
| 1592 | case -EIO: | 1592 | case -EIO: |
| 1593 | /* If this -EIO is due to a gpu hang, give the reset code a | 1593 | /* |
| 1594 | * chance to clean up the mess. Otherwise return the proper | 1594 | * We eat errors when the gpu is terminally wedged to avoid |
| 1595 | * SIGBUS. */ | 1595 | * userspace unduly crashing (gl has no provisions for mmaps to |
| 1596 | if (i915_terminally_wedged(&dev_priv->gpu_error)) { | 1596 | * fail). But any other -EIO isn't ours (e.g. swap in failure) |
| 1597 | * and so needs to be reported. | ||
| 1598 | */ | ||
| 1599 | if (!i915_terminally_wedged(&dev_priv->gpu_error)) { | ||
| 1597 | ret = VM_FAULT_SIGBUS; | 1600 | ret = VM_FAULT_SIGBUS; |
| 1598 | break; | 1601 | break; |
| 1599 | } | 1602 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index fe69fc837d9e..d38413997379 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -32,6 +32,15 @@ | |||
| 32 | #include <linux/mempolicy.h> | 32 | #include <linux/mempolicy.h> |
| 33 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
| 34 | 34 | ||
| 35 | struct i915_mm_struct { | ||
| 36 | struct mm_struct *mm; | ||
| 37 | struct drm_device *dev; | ||
| 38 | struct i915_mmu_notifier *mn; | ||
| 39 | struct hlist_node node; | ||
| 40 | struct kref kref; | ||
| 41 | struct work_struct work; | ||
| 42 | }; | ||
| 43 | |||
| 35 | #if defined(CONFIG_MMU_NOTIFIER) | 44 | #if defined(CONFIG_MMU_NOTIFIER) |
| 36 | #include <linux/interval_tree.h> | 45 | #include <linux/interval_tree.h> |
| 37 | 46 | ||
| @@ -41,16 +50,12 @@ struct i915_mmu_notifier { | |||
| 41 | struct mmu_notifier mn; | 50 | struct mmu_notifier mn; |
| 42 | struct rb_root objects; | 51 | struct rb_root objects; |
| 43 | struct list_head linear; | 52 | struct list_head linear; |
| 44 | struct drm_device *dev; | ||
| 45 | struct mm_struct *mm; | ||
| 46 | struct work_struct work; | ||
| 47 | unsigned long count; | ||
| 48 | unsigned long serial; | 53 | unsigned long serial; |
| 49 | bool has_linear; | 54 | bool has_linear; |
| 50 | }; | 55 | }; |
| 51 | 56 | ||
| 52 | struct i915_mmu_object { | 57 | struct i915_mmu_object { |
| 53 | struct i915_mmu_notifier *mmu; | 58 | struct i915_mmu_notifier *mn; |
| 54 | struct interval_tree_node it; | 59 | struct interval_tree_node it; |
| 55 | struct list_head link; | 60 | struct list_head link; |
| 56 | struct drm_i915_gem_object *obj; | 61 | struct drm_i915_gem_object *obj; |
| @@ -96,18 +101,18 @@ static void *invalidate_range__linear(struct i915_mmu_notifier *mn, | |||
| 96 | unsigned long start, | 101 | unsigned long start, |
| 97 | unsigned long end) | 102 | unsigned long end) |
| 98 | { | 103 | { |
| 99 | struct i915_mmu_object *mmu; | 104 | struct i915_mmu_object *mo; |
| 100 | unsigned long serial; | 105 | unsigned long serial; |
| 101 | 106 | ||
| 102 | restart: | 107 | restart: |
| 103 | serial = mn->serial; | 108 | serial = mn->serial; |
| 104 | list_for_each_entry(mmu, &mn->linear, link) { | 109 | list_for_each_entry(mo, &mn->linear, link) { |
| 105 | struct drm_i915_gem_object *obj; | 110 | struct drm_i915_gem_object *obj; |
| 106 | 111 | ||
| 107 | if (mmu->it.last < start || mmu->it.start > end) | 112 | if (mo->it.last < start || mo->it.start > end) |
| 108 | continue; | 113 | continue; |
| 109 | 114 | ||
| 110 | obj = mmu->obj; | 115 | obj = mo->obj; |
| 111 | drm_gem_object_reference(&obj->base); | 116 | drm_gem_object_reference(&obj->base); |
| 112 | spin_unlock(&mn->lock); | 117 | spin_unlock(&mn->lock); |
| 113 | 118 | ||
| @@ -160,130 +165,47 @@ static const struct mmu_notifier_ops i915_gem_userptr_notifier = { | |||
| 160 | }; | 165 | }; |
| 161 | 166 | ||
| 162 | static struct i915_mmu_notifier * | 167 | static struct i915_mmu_notifier * |
| 163 | __i915_mmu_notifier_lookup(struct drm_device *dev, struct mm_struct *mm) | 168 | i915_mmu_notifier_create(struct mm_struct *mm) |
| 164 | { | ||
| 165 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 166 | struct i915_mmu_notifier *mmu; | ||
| 167 | |||
| 168 | /* Protected by dev->struct_mutex */ | ||
| 169 | hash_for_each_possible(dev_priv->mmu_notifiers, mmu, node, (unsigned long)mm) | ||
| 170 | if (mmu->mm == mm) | ||
| 171 | return mmu; | ||
| 172 | |||
| 173 | return NULL; | ||
| 174 | } | ||
| 175 | |||
| 176 | static struct i915_mmu_notifier * | ||
| 177 | i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) | ||
| 178 | { | 169 | { |
| 179 | struct drm_i915_private *dev_priv = to_i915(dev); | 170 | struct i915_mmu_notifier *mn; |
| 180 | struct i915_mmu_notifier *mmu; | ||
| 181 | int ret; | 171 | int ret; |
| 182 | 172 | ||
| 183 | lockdep_assert_held(&dev->struct_mutex); | 173 | mn = kmalloc(sizeof(*mn), GFP_KERNEL); |
| 184 | 174 | if (mn == NULL) | |
| 185 | mmu = __i915_mmu_notifier_lookup(dev, mm); | ||
| 186 | if (mmu) | ||
| 187 | return mmu; | ||
| 188 | |||
| 189 | mmu = kmalloc(sizeof(*mmu), GFP_KERNEL); | ||
| 190 | if (mmu == NULL) | ||
| 191 | return ERR_PTR(-ENOMEM); | 175 | return ERR_PTR(-ENOMEM); |
| 192 | 176 | ||
| 193 | spin_lock_init(&mmu->lock); | 177 | spin_lock_init(&mn->lock); |
| 194 | mmu->dev = dev; | 178 | mn->mn.ops = &i915_gem_userptr_notifier; |
| 195 | mmu->mn.ops = &i915_gem_userptr_notifier; | 179 | mn->objects = RB_ROOT; |
| 196 | mmu->mm = mm; | 180 | mn->serial = 1; |
| 197 | mmu->objects = RB_ROOT; | 181 | INIT_LIST_HEAD(&mn->linear); |
| 198 | mmu->count = 0; | 182 | mn->has_linear = false; |
| 199 | mmu->serial = 1; | 183 | |
| 200 | INIT_LIST_HEAD(&mmu->linear); | 184 | /* Protected by mmap_sem (write-lock) */ |
| 201 | mmu->has_linear = false; | 185 | ret = __mmu_notifier_register(&mn->mn, mm); |
| 202 | |||
| 203 | /* Protected by mmap_sem (write-lock) */ | ||
| 204 | ret = __mmu_notifier_register(&mmu->mn, mm); | ||
| 205 | if (ret) { | 186 | if (ret) { |
| 206 | kfree(mmu); | 187 | kfree(mn); |
| 207 | return ERR_PTR(ret); | 188 | return ERR_PTR(ret); |
| 208 | } | 189 | } |
| 209 | 190 | ||
| 210 | /* Protected by dev->struct_mutex */ | 191 | return mn; |
| 211 | hash_add(dev_priv->mmu_notifiers, &mmu->node, (unsigned long)mm); | ||
| 212 | return mmu; | ||
| 213 | } | 192 | } |
| 214 | 193 | ||
| 215 | static void | 194 | static void __i915_mmu_notifier_update_serial(struct i915_mmu_notifier *mn) |
| 216 | __i915_mmu_notifier_destroy_worker(struct work_struct *work) | ||
| 217 | { | 195 | { |
| 218 | struct i915_mmu_notifier *mmu = container_of(work, typeof(*mmu), work); | 196 | if (++mn->serial == 0) |
| 219 | mmu_notifier_unregister(&mmu->mn, mmu->mm); | 197 | mn->serial = 1; |
| 220 | kfree(mmu); | ||
| 221 | } | ||
| 222 | |||
| 223 | static void | ||
| 224 | __i915_mmu_notifier_destroy(struct i915_mmu_notifier *mmu) | ||
| 225 | { | ||
| 226 | lockdep_assert_held(&mmu->dev->struct_mutex); | ||
| 227 | |||
| 228 | /* Protected by dev->struct_mutex */ | ||
| 229 | hash_del(&mmu->node); | ||
| 230 | |||
| 231 | /* Our lock ordering is: mmap_sem, mmu_notifier_scru, struct_mutex. | ||
| 232 | * We enter the function holding struct_mutex, therefore we need | ||
| 233 | * to drop our mutex prior to calling mmu_notifier_unregister in | ||
| 234 | * order to prevent lock inversion (and system-wide deadlock) | ||
| 235 | * between the mmap_sem and struct-mutex. Hence we defer the | ||
| 236 | * unregistration to a workqueue where we hold no locks. | ||
| 237 | */ | ||
| 238 | INIT_WORK(&mmu->work, __i915_mmu_notifier_destroy_worker); | ||
| 239 | schedule_work(&mmu->work); | ||
| 240 | } | ||
| 241 | |||
| 242 | static void __i915_mmu_notifier_update_serial(struct i915_mmu_notifier *mmu) | ||
| 243 | { | ||
| 244 | if (++mmu->serial == 0) | ||
| 245 | mmu->serial = 1; | ||
| 246 | } | ||
| 247 | |||
| 248 | static bool i915_mmu_notifier_has_linear(struct i915_mmu_notifier *mmu) | ||
| 249 | { | ||
| 250 | struct i915_mmu_object *mn; | ||
| 251 | |||
| 252 | list_for_each_entry(mn, &mmu->linear, link) | ||
| 253 | if (mn->is_linear) | ||
| 254 | return true; | ||
| 255 | |||
| 256 | return false; | ||
| 257 | } | ||
| 258 | |||
| 259 | static void | ||
| 260 | i915_mmu_notifier_del(struct i915_mmu_notifier *mmu, | ||
| 261 | struct i915_mmu_object *mn) | ||
| 262 | { | ||
| 263 | lockdep_assert_held(&mmu->dev->struct_mutex); | ||
| 264 | |||
| 265 | spin_lock(&mmu->lock); | ||
| 266 | list_del(&mn->link); | ||
| 267 | if (mn->is_linear) | ||
| 268 | mmu->has_linear = i915_mmu_notifier_has_linear(mmu); | ||
| 269 | else | ||
| 270 | interval_tree_remove(&mn->it, &mmu->objects); | ||
| 271 | __i915_mmu_notifier_update_serial(mmu); | ||
| 272 | spin_unlock(&mmu->lock); | ||
| 273 | |||
| 274 | /* Protected against _add() by dev->struct_mutex */ | ||
| 275 | if (--mmu->count == 0) | ||
| 276 | __i915_mmu_notifier_destroy(mmu); | ||
| 277 | } | 198 | } |
| 278 | 199 | ||
| 279 | static int | 200 | static int |
| 280 | i915_mmu_notifier_add(struct i915_mmu_notifier *mmu, | 201 | i915_mmu_notifier_add(struct drm_device *dev, |
| 281 | struct i915_mmu_object *mn) | 202 | struct i915_mmu_notifier *mn, |
| 203 | struct i915_mmu_object *mo) | ||
| 282 | { | 204 | { |
| 283 | struct interval_tree_node *it; | 205 | struct interval_tree_node *it; |
| 284 | int ret; | 206 | int ret; |
| 285 | 207 | ||
| 286 | ret = i915_mutex_lock_interruptible(mmu->dev); | 208 | ret = i915_mutex_lock_interruptible(dev); |
| 287 | if (ret) | 209 | if (ret) |
| 288 | return ret; | 210 | return ret; |
| 289 | 211 | ||
| @@ -291,11 +213,11 @@ i915_mmu_notifier_add(struct i915_mmu_notifier *mmu, | |||
| 291 | * remove the objects from the interval tree) before we do | 213 | * remove the objects from the interval tree) before we do |
| 292 | * the check for overlapping objects. | 214 | * the check for overlapping objects. |
| 293 | */ | 215 | */ |
| 294 | i915_gem_retire_requests(mmu->dev); | 216 | i915_gem_retire_requests(dev); |
| 295 | 217 | ||
| 296 | spin_lock(&mmu->lock); | 218 | spin_lock(&mn->lock); |
| 297 | it = interval_tree_iter_first(&mmu->objects, | 219 | it = interval_tree_iter_first(&mn->objects, |
| 298 | mn->it.start, mn->it.last); | 220 | mo->it.start, mo->it.last); |
| 299 | if (it) { | 221 | if (it) { |
| 300 | struct drm_i915_gem_object *obj; | 222 | struct drm_i915_gem_object *obj; |
| 301 | 223 | ||
| @@ -312,86 +234,122 @@ i915_mmu_notifier_add(struct i915_mmu_notifier *mmu, | |||
| 312 | 234 | ||
| 313 | obj = container_of(it, struct i915_mmu_object, it)->obj; | 235 | obj = container_of(it, struct i915_mmu_object, it)->obj; |
| 314 | if (!obj->userptr.workers) | 236 | if (!obj->userptr.workers) |
| 315 | mmu->has_linear = mn->is_linear = true; | 237 | mn->has_linear = mo->is_linear = true; |
| 316 | else | 238 | else |
| 317 | ret = -EAGAIN; | 239 | ret = -EAGAIN; |
| 318 | } else | 240 | } else |
| 319 | interval_tree_insert(&mn->it, &mmu->objects); | 241 | interval_tree_insert(&mo->it, &mn->objects); |
| 320 | 242 | ||
| 321 | if (ret == 0) { | 243 | if (ret == 0) { |
| 322 | list_add(&mn->link, &mmu->linear); | 244 | list_add(&mo->link, &mn->linear); |
| 323 | __i915_mmu_notifier_update_serial(mmu); | 245 | __i915_mmu_notifier_update_serial(mn); |
| 324 | } | 246 | } |
| 325 | spin_unlock(&mmu->lock); | 247 | spin_unlock(&mn->lock); |
| 326 | mutex_unlock(&mmu->dev->struct_mutex); | 248 | mutex_unlock(&dev->struct_mutex); |
| 327 | 249 | ||
| 328 | return ret; | 250 | return ret; |
| 329 | } | 251 | } |
| 330 | 252 | ||
| 253 | static bool i915_mmu_notifier_has_linear(struct i915_mmu_notifier *mn) | ||
| 254 | { | ||
| 255 | struct i915_mmu_object *mo; | ||
| 256 | |||
| 257 | list_for_each_entry(mo, &mn->linear, link) | ||
| 258 | if (mo->is_linear) | ||
| 259 | return true; | ||
| 260 | |||
| 261 | return false; | ||
| 262 | } | ||
| 263 | |||
| 264 | static void | ||
| 265 | i915_mmu_notifier_del(struct i915_mmu_notifier *mn, | ||
| 266 | struct i915_mmu_object *mo) | ||
| 267 | { | ||
| 268 | spin_lock(&mn->lock); | ||
| 269 | list_del(&mo->link); | ||
| 270 | if (mo->is_linear) | ||
| 271 | mn->has_linear = i915_mmu_notifier_has_linear(mn); | ||
| 272 | else | ||
| 273 | interval_tree_remove(&mo->it, &mn->objects); | ||
| 274 | __i915_mmu_notifier_update_serial(mn); | ||
| 275 | spin_unlock(&mn->lock); | ||
| 276 | } | ||
| 277 | |||
| 331 | static void | 278 | static void |
| 332 | i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) | 279 | i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) |
| 333 | { | 280 | { |
| 334 | struct i915_mmu_object *mn; | 281 | struct i915_mmu_object *mo; |
| 335 | 282 | ||
| 336 | mn = obj->userptr.mn; | 283 | mo = obj->userptr.mmu_object; |
| 337 | if (mn == NULL) | 284 | if (mo == NULL) |
| 338 | return; | 285 | return; |
| 339 | 286 | ||
| 340 | i915_mmu_notifier_del(mn->mmu, mn); | 287 | i915_mmu_notifier_del(mo->mn, mo); |
| 341 | obj->userptr.mn = NULL; | 288 | kfree(mo); |
| 289 | |||
| 290 | obj->userptr.mmu_object = NULL; | ||
| 291 | } | ||
| 292 | |||
| 293 | static struct i915_mmu_notifier * | ||
| 294 | i915_mmu_notifier_find(struct i915_mm_struct *mm) | ||
| 295 | { | ||
| 296 | if (mm->mn == NULL) { | ||
| 297 | down_write(&mm->mm->mmap_sem); | ||
| 298 | mutex_lock(&to_i915(mm->dev)->mm_lock); | ||
| 299 | if (mm->mn == NULL) | ||
| 300 | mm->mn = i915_mmu_notifier_create(mm->mm); | ||
| 301 | mutex_unlock(&to_i915(mm->dev)->mm_lock); | ||
| 302 | up_write(&mm->mm->mmap_sem); | ||
| 303 | } | ||
| 304 | return mm->mn; | ||
| 342 | } | 305 | } |
| 343 | 306 | ||
| 344 | static int | 307 | static int |
| 345 | i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, | 308 | i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, |
| 346 | unsigned flags) | 309 | unsigned flags) |
| 347 | { | 310 | { |
| 348 | struct i915_mmu_notifier *mmu; | 311 | struct i915_mmu_notifier *mn; |
| 349 | struct i915_mmu_object *mn; | 312 | struct i915_mmu_object *mo; |
| 350 | int ret; | 313 | int ret; |
| 351 | 314 | ||
| 352 | if (flags & I915_USERPTR_UNSYNCHRONIZED) | 315 | if (flags & I915_USERPTR_UNSYNCHRONIZED) |
| 353 | return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; | 316 | return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; |
| 354 | 317 | ||
| 355 | down_write(&obj->userptr.mm->mmap_sem); | 318 | if (WARN_ON(obj->userptr.mm == NULL)) |
| 356 | ret = i915_mutex_lock_interruptible(obj->base.dev); | 319 | return -EINVAL; |
| 357 | if (ret == 0) { | ||
| 358 | mmu = i915_mmu_notifier_get(obj->base.dev, obj->userptr.mm); | ||
| 359 | if (!IS_ERR(mmu)) | ||
| 360 | mmu->count++; /* preemptive add to act as a refcount */ | ||
| 361 | else | ||
| 362 | ret = PTR_ERR(mmu); | ||
| 363 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 364 | } | ||
| 365 | up_write(&obj->userptr.mm->mmap_sem); | ||
| 366 | if (ret) | ||
| 367 | return ret; | ||
| 368 | 320 | ||
| 369 | mn = kzalloc(sizeof(*mn), GFP_KERNEL); | 321 | mn = i915_mmu_notifier_find(obj->userptr.mm); |
| 370 | if (mn == NULL) { | 322 | if (IS_ERR(mn)) |
| 371 | ret = -ENOMEM; | 323 | return PTR_ERR(mn); |
| 372 | goto destroy_mmu; | ||
| 373 | } | ||
| 374 | 324 | ||
| 375 | mn->mmu = mmu; | 325 | mo = kzalloc(sizeof(*mo), GFP_KERNEL); |
| 376 | mn->it.start = obj->userptr.ptr; | 326 | if (mo == NULL) |
| 377 | mn->it.last = mn->it.start + obj->base.size - 1; | 327 | return -ENOMEM; |
| 378 | mn->obj = obj; | ||
| 379 | 328 | ||
| 380 | ret = i915_mmu_notifier_add(mmu, mn); | 329 | mo->mn = mn; |
| 381 | if (ret) | 330 | mo->it.start = obj->userptr.ptr; |
| 382 | goto free_mn; | 331 | mo->it.last = mo->it.start + obj->base.size - 1; |
| 332 | mo->obj = obj; | ||
| 383 | 333 | ||
| 384 | obj->userptr.mn = mn; | 334 | ret = i915_mmu_notifier_add(obj->base.dev, mn, mo); |
| 335 | if (ret) { | ||
| 336 | kfree(mo); | ||
| 337 | return ret; | ||
| 338 | } | ||
| 339 | |||
| 340 | obj->userptr.mmu_object = mo; | ||
| 385 | return 0; | 341 | return 0; |
| 342 | } | ||
| 343 | |||
| 344 | static void | ||
| 345 | i915_mmu_notifier_free(struct i915_mmu_notifier *mn, | ||
| 346 | struct mm_struct *mm) | ||
| 347 | { | ||
| 348 | if (mn == NULL) | ||
| 349 | return; | ||
| 386 | 350 | ||
| 387 | free_mn: | 351 | mmu_notifier_unregister(&mn->mn, mm); |
| 388 | kfree(mn); | 352 | kfree(mn); |
| 389 | destroy_mmu: | ||
| 390 | mutex_lock(&obj->base.dev->struct_mutex); | ||
| 391 | if (--mmu->count == 0) | ||
| 392 | __i915_mmu_notifier_destroy(mmu); | ||
| 393 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 394 | return ret; | ||
| 395 | } | 353 | } |
| 396 | 354 | ||
| 397 | #else | 355 | #else |
| @@ -413,15 +371,114 @@ i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, | |||
| 413 | 371 | ||
| 414 | return 0; | 372 | return 0; |
| 415 | } | 373 | } |
| 374 | |||
| 375 | static void | ||
| 376 | i915_mmu_notifier_free(struct i915_mmu_notifier *mn, | ||
| 377 | struct mm_struct *mm) | ||
| 378 | { | ||
| 379 | } | ||
| 380 | |||
| 416 | #endif | 381 | #endif |
| 417 | 382 | ||
| 383 | static struct i915_mm_struct * | ||
| 384 | __i915_mm_struct_find(struct drm_i915_private *dev_priv, struct mm_struct *real) | ||
| 385 | { | ||
| 386 | struct i915_mm_struct *mm; | ||
| 387 | |||
| 388 | /* Protected by dev_priv->mm_lock */ | ||
| 389 | hash_for_each_possible(dev_priv->mm_structs, mm, node, (unsigned long)real) | ||
| 390 | if (mm->mm == real) | ||
| 391 | return mm; | ||
| 392 | |||
| 393 | return NULL; | ||
| 394 | } | ||
| 395 | |||
| 396 | static int | ||
| 397 | i915_gem_userptr_init__mm_struct(struct drm_i915_gem_object *obj) | ||
| 398 | { | ||
| 399 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | ||
| 400 | struct i915_mm_struct *mm; | ||
| 401 | int ret = 0; | ||
| 402 | |||
| 403 | /* During release of the GEM object we hold the struct_mutex. This | ||
| 404 | * precludes us from calling mmput() at that time as that may be | ||
| 405 | * the last reference and so call exit_mmap(). exit_mmap() will | ||
| 406 | * attempt to reap the vma, and if we were holding a GTT mmap | ||
| 407 | * would then call drm_gem_vm_close() and attempt to reacquire | ||
| 408 | * the struct mutex. So in order to avoid that recursion, we have | ||
| 409 | * to defer releasing the mm reference until after we drop the | ||
| 410 | * struct_mutex, i.e. we need to schedule a worker to do the clean | ||
| 411 | * up. | ||
| 412 | */ | ||
| 413 | mutex_lock(&dev_priv->mm_lock); | ||
| 414 | mm = __i915_mm_struct_find(dev_priv, current->mm); | ||
| 415 | if (mm == NULL) { | ||
| 416 | mm = kmalloc(sizeof(*mm), GFP_KERNEL); | ||
| 417 | if (mm == NULL) { | ||
| 418 | ret = -ENOMEM; | ||
| 419 | goto out; | ||
| 420 | } | ||
| 421 | |||
| 422 | kref_init(&mm->kref); | ||
| 423 | mm->dev = obj->base.dev; | ||
| 424 | |||
| 425 | mm->mm = current->mm; | ||
| 426 | atomic_inc(¤t->mm->mm_count); | ||
| 427 | |||
| 428 | mm->mn = NULL; | ||
| 429 | |||
| 430 | /* Protected by dev_priv->mm_lock */ | ||
| 431 | hash_add(dev_priv->mm_structs, | ||
| 432 | &mm->node, (unsigned long)mm->mm); | ||
| 433 | } else | ||
| 434 | kref_get(&mm->kref); | ||
| 435 | |||
| 436 | obj->userptr.mm = mm; | ||
| 437 | out: | ||
| 438 | mutex_unlock(&dev_priv->mm_lock); | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | |||
| 442 | static void | ||
| 443 | __i915_mm_struct_free__worker(struct work_struct *work) | ||
| 444 | { | ||
| 445 | struct i915_mm_struct *mm = container_of(work, typeof(*mm), work); | ||
| 446 | i915_mmu_notifier_free(mm->mn, mm->mm); | ||
| 447 | mmdrop(mm->mm); | ||
| 448 | kfree(mm); | ||
| 449 | } | ||
| 450 | |||
| 451 | static void | ||
| 452 | __i915_mm_struct_free(struct kref *kref) | ||
| 453 | { | ||
| 454 | struct i915_mm_struct *mm = container_of(kref, typeof(*mm), kref); | ||
| 455 | |||
| 456 | /* Protected by dev_priv->mm_lock */ | ||
| 457 | hash_del(&mm->node); | ||
| 458 | mutex_unlock(&to_i915(mm->dev)->mm_lock); | ||
| 459 | |||
| 460 | INIT_WORK(&mm->work, __i915_mm_struct_free__worker); | ||
| 461 | schedule_work(&mm->work); | ||
| 462 | } | ||
| 463 | |||
| 464 | static void | ||
| 465 | i915_gem_userptr_release__mm_struct(struct drm_i915_gem_object *obj) | ||
| 466 | { | ||
| 467 | if (obj->userptr.mm == NULL) | ||
| 468 | return; | ||
| 469 | |||
| 470 | kref_put_mutex(&obj->userptr.mm->kref, | ||
| 471 | __i915_mm_struct_free, | ||
| 472 | &to_i915(obj->base.dev)->mm_lock); | ||
| 473 | obj->userptr.mm = NULL; | ||
| 474 | } | ||
| 475 | |||
| 418 | struct get_pages_work { | 476 | struct get_pages_work { |
| 419 | struct work_struct work; | 477 | struct work_struct work; |
| 420 | struct drm_i915_gem_object *obj; | 478 | struct drm_i915_gem_object *obj; |
| 421 | struct task_struct *task; | 479 | struct task_struct *task; |
| 422 | }; | 480 | }; |
| 423 | 481 | ||
| 424 | |||
| 425 | #if IS_ENABLED(CONFIG_SWIOTLB) | 482 | #if IS_ENABLED(CONFIG_SWIOTLB) |
| 426 | #define swiotlb_active() swiotlb_nr_tbl() | 483 | #define swiotlb_active() swiotlb_nr_tbl() |
| 427 | #else | 484 | #else |
| @@ -479,7 +536,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
| 479 | if (pvec == NULL) | 536 | if (pvec == NULL) |
| 480 | pvec = drm_malloc_ab(num_pages, sizeof(struct page *)); | 537 | pvec = drm_malloc_ab(num_pages, sizeof(struct page *)); |
| 481 | if (pvec != NULL) { | 538 | if (pvec != NULL) { |
| 482 | struct mm_struct *mm = obj->userptr.mm; | 539 | struct mm_struct *mm = obj->userptr.mm->mm; |
| 483 | 540 | ||
| 484 | down_read(&mm->mmap_sem); | 541 | down_read(&mm->mmap_sem); |
| 485 | while (pinned < num_pages) { | 542 | while (pinned < num_pages) { |
| @@ -545,7 +602,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 545 | 602 | ||
| 546 | pvec = NULL; | 603 | pvec = NULL; |
| 547 | pinned = 0; | 604 | pinned = 0; |
| 548 | if (obj->userptr.mm == current->mm) { | 605 | if (obj->userptr.mm->mm == current->mm) { |
| 549 | pvec = kmalloc(num_pages*sizeof(struct page *), | 606 | pvec = kmalloc(num_pages*sizeof(struct page *), |
| 550 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); | 607 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); |
| 551 | if (pvec == NULL) { | 608 | if (pvec == NULL) { |
| @@ -651,17 +708,13 @@ static void | |||
| 651 | i915_gem_userptr_release(struct drm_i915_gem_object *obj) | 708 | i915_gem_userptr_release(struct drm_i915_gem_object *obj) |
| 652 | { | 709 | { |
| 653 | i915_gem_userptr_release__mmu_notifier(obj); | 710 | i915_gem_userptr_release__mmu_notifier(obj); |
| 654 | 711 | i915_gem_userptr_release__mm_struct(obj); | |
| 655 | if (obj->userptr.mm) { | ||
| 656 | mmput(obj->userptr.mm); | ||
| 657 | obj->userptr.mm = NULL; | ||
| 658 | } | ||
| 659 | } | 712 | } |
| 660 | 713 | ||
| 661 | static int | 714 | static int |
| 662 | i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) | 715 | i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) |
| 663 | { | 716 | { |
| 664 | if (obj->userptr.mn) | 717 | if (obj->userptr.mmu_object) |
| 665 | return 0; | 718 | return 0; |
| 666 | 719 | ||
| 667 | return i915_gem_userptr_init__mmu_notifier(obj, 0); | 720 | return i915_gem_userptr_init__mmu_notifier(obj, 0); |
| @@ -736,7 +789,6 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file | |||
| 736 | return -ENODEV; | 789 | return -ENODEV; |
| 737 | } | 790 | } |
| 738 | 791 | ||
| 739 | /* Allocate the new object */ | ||
| 740 | obj = i915_gem_object_alloc(dev); | 792 | obj = i915_gem_object_alloc(dev); |
| 741 | if (obj == NULL) | 793 | if (obj == NULL) |
| 742 | return -ENOMEM; | 794 | return -ENOMEM; |
| @@ -754,8 +806,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file | |||
| 754 | * at binding. This means that we need to hook into the mmu_notifier | 806 | * at binding. This means that we need to hook into the mmu_notifier |
| 755 | * in order to detect if the mmu is destroyed. | 807 | * in order to detect if the mmu is destroyed. |
| 756 | */ | 808 | */ |
| 757 | ret = -ENOMEM; | 809 | ret = i915_gem_userptr_init__mm_struct(obj); |
| 758 | if ((obj->userptr.mm = get_task_mm(current))) | 810 | if (ret == 0) |
| 759 | ret = i915_gem_userptr_init__mmu_notifier(obj, args->flags); | 811 | ret = i915_gem_userptr_init__mmu_notifier(obj, args->flags); |
| 760 | if (ret == 0) | 812 | if (ret == 0) |
| 761 | ret = drm_gem_handle_create(file, &obj->base, &handle); | 813 | ret = drm_gem_handle_create(file, &obj->base, &handle); |
| @@ -772,9 +824,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file | |||
| 772 | int | 824 | int |
| 773 | i915_gem_init_userptr(struct drm_device *dev) | 825 | i915_gem_init_userptr(struct drm_device *dev) |
| 774 | { | 826 | { |
| 775 | #if defined(CONFIG_MMU_NOTIFIER) | ||
| 776 | struct drm_i915_private *dev_priv = to_i915(dev); | 827 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 777 | hash_init(dev_priv->mmu_notifiers); | 828 | mutex_init(&dev_priv->mm_lock); |
| 778 | #endif | 829 | hash_init(dev_priv->mm_structs); |
| 779 | return 0; | 830 | return 0; |
| 780 | } | 831 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 390ccc2a3096..0050ee9470f1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1189,8 +1189,8 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
| 1189 | * some connectors */ | 1189 | * some connectors */ |
| 1190 | if (hpd_disabled) { | 1190 | if (hpd_disabled) { |
| 1191 | drm_kms_helper_poll_enable(dev); | 1191 | drm_kms_helper_poll_enable(dev); |
| 1192 | mod_timer(&dev_priv->hotplug_reenable_timer, | 1192 | mod_delayed_work(system_wq, &dev_priv->hotplug_reenable_work, |
| 1193 | jiffies + msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); | 1193 | msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); |
| 1194 | } | 1194 | } |
| 1195 | 1195 | ||
| 1196 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1196 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| @@ -1213,11 +1213,6 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
| 1213 | drm_kms_helper_hotplug_event(dev); | 1213 | drm_kms_helper_hotplug_event(dev); |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | static void intel_hpd_irq_uninstall(struct drm_i915_private *dev_priv) | ||
| 1217 | { | ||
| 1218 | del_timer_sync(&dev_priv->hotplug_reenable_timer); | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | static void ironlake_rps_change_irq_handler(struct drm_device *dev) | 1216 | static void ironlake_rps_change_irq_handler(struct drm_device *dev) |
| 1222 | { | 1217 | { |
| 1223 | struct drm_i915_private *dev_priv = dev->dev_private; | 1218 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -3892,8 +3887,6 @@ static void gen8_irq_uninstall(struct drm_device *dev) | |||
| 3892 | if (!dev_priv) | 3887 | if (!dev_priv) |
| 3893 | return; | 3888 | return; |
| 3894 | 3889 | ||
| 3895 | intel_hpd_irq_uninstall(dev_priv); | ||
| 3896 | |||
| 3897 | gen8_irq_reset(dev); | 3890 | gen8_irq_reset(dev); |
| 3898 | } | 3891 | } |
| 3899 | 3892 | ||
| @@ -3908,8 +3901,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev) | |||
| 3908 | 3901 | ||
| 3909 | I915_WRITE(VLV_MASTER_IER, 0); | 3902 | I915_WRITE(VLV_MASTER_IER, 0); |
| 3910 | 3903 | ||
| 3911 | intel_hpd_irq_uninstall(dev_priv); | ||
| 3912 | |||
| 3913 | for_each_pipe(pipe) | 3904 | for_each_pipe(pipe) |
| 3914 | I915_WRITE(PIPESTAT(pipe), 0xffff); | 3905 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
| 3915 | 3906 | ||
| @@ -3988,8 +3979,6 @@ static void ironlake_irq_uninstall(struct drm_device *dev) | |||
| 3988 | if (!dev_priv) | 3979 | if (!dev_priv) |
| 3989 | return; | 3980 | return; |
| 3990 | 3981 | ||
| 3991 | intel_hpd_irq_uninstall(dev_priv); | ||
| 3992 | |||
| 3993 | ironlake_irq_reset(dev); | 3982 | ironlake_irq_reset(dev); |
| 3994 | } | 3983 | } |
| 3995 | 3984 | ||
| @@ -4360,8 +4349,6 @@ static void i915_irq_uninstall(struct drm_device * dev) | |||
| 4360 | struct drm_i915_private *dev_priv = dev->dev_private; | 4349 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 4361 | int pipe; | 4350 | int pipe; |
| 4362 | 4351 | ||
| 4363 | intel_hpd_irq_uninstall(dev_priv); | ||
| 4364 | |||
| 4365 | if (I915_HAS_HOTPLUG(dev)) { | 4352 | if (I915_HAS_HOTPLUG(dev)) { |
| 4366 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 4353 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
| 4367 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | 4354 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
| @@ -4598,8 +4585,6 @@ static void i965_irq_uninstall(struct drm_device * dev) | |||
| 4598 | if (!dev_priv) | 4585 | if (!dev_priv) |
| 4599 | return; | 4586 | return; |
| 4600 | 4587 | ||
| 4601 | intel_hpd_irq_uninstall(dev_priv); | ||
| 4602 | |||
| 4603 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 4588 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
| 4604 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | 4589 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
| 4605 | 4590 | ||
| @@ -4615,14 +4600,18 @@ static void i965_irq_uninstall(struct drm_device * dev) | |||
| 4615 | I915_WRITE(IIR, I915_READ(IIR)); | 4600 | I915_WRITE(IIR, I915_READ(IIR)); |
| 4616 | } | 4601 | } |
| 4617 | 4602 | ||
| 4618 | static void intel_hpd_irq_reenable(unsigned long data) | 4603 | static void intel_hpd_irq_reenable(struct work_struct *work) |
| 4619 | { | 4604 | { |
| 4620 | struct drm_i915_private *dev_priv = (struct drm_i915_private *)data; | 4605 | struct drm_i915_private *dev_priv = |
| 4606 | container_of(work, typeof(*dev_priv), | ||
| 4607 | hotplug_reenable_work.work); | ||
| 4621 | struct drm_device *dev = dev_priv->dev; | 4608 | struct drm_device *dev = dev_priv->dev; |
| 4622 | struct drm_mode_config *mode_config = &dev->mode_config; | 4609 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 4623 | unsigned long irqflags; | 4610 | unsigned long irqflags; |
| 4624 | int i; | 4611 | int i; |
| 4625 | 4612 | ||
| 4613 | intel_runtime_pm_get(dev_priv); | ||
| 4614 | |||
| 4626 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 4615 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
| 4627 | for (i = (HPD_NONE + 1); i < HPD_NUM_PINS; i++) { | 4616 | for (i = (HPD_NONE + 1); i < HPD_NUM_PINS; i++) { |
| 4628 | struct drm_connector *connector; | 4617 | struct drm_connector *connector; |
| @@ -4648,6 +4637,8 @@ static void intel_hpd_irq_reenable(unsigned long data) | |||
| 4648 | if (dev_priv->display.hpd_irq_setup) | 4637 | if (dev_priv->display.hpd_irq_setup) |
| 4649 | dev_priv->display.hpd_irq_setup(dev); | 4638 | dev_priv->display.hpd_irq_setup(dev); |
| 4650 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 4639 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| 4640 | |||
| 4641 | intel_runtime_pm_put(dev_priv); | ||
| 4651 | } | 4642 | } |
| 4652 | 4643 | ||
| 4653 | void intel_irq_init(struct drm_device *dev) | 4644 | void intel_irq_init(struct drm_device *dev) |
| @@ -4670,8 +4661,8 @@ void intel_irq_init(struct drm_device *dev) | |||
| 4670 | setup_timer(&dev_priv->gpu_error.hangcheck_timer, | 4661 | setup_timer(&dev_priv->gpu_error.hangcheck_timer, |
| 4671 | i915_hangcheck_elapsed, | 4662 | i915_hangcheck_elapsed, |
| 4672 | (unsigned long) dev); | 4663 | (unsigned long) dev); |
| 4673 | setup_timer(&dev_priv->hotplug_reenable_timer, intel_hpd_irq_reenable, | 4664 | INIT_DELAYED_WORK(&dev_priv->hotplug_reenable_work, |
| 4674 | (unsigned long) dev_priv); | 4665 | intel_hpd_irq_reenable); |
| 4675 | 4666 | ||
| 4676 | pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); | 4667 | pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); |
| 4677 | 4668 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e4d7607da2c4..f29b44c86a2f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -334,16 +334,20 @@ | |||
| 334 | #define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) | 334 | #define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) |
| 335 | #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) | 335 | #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) |
| 336 | #define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) | 336 | #define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) |
| 337 | #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) | 337 | |
| 338 | #define COLOR_BLT_CMD (2<<29 | 0x40<<22 | (5-2)) | ||
| 339 | #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) | ||
| 338 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) | 340 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) |
| 339 | #define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) | 341 | #define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) |
| 340 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) | 342 | #define BLT_WRITE_A (2<<20) |
| 341 | #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) | 343 | #define BLT_WRITE_RGB (1<<20) |
| 344 | #define BLT_WRITE_RGBA (BLT_WRITE_RGB | BLT_WRITE_A) | ||
| 342 | #define BLT_DEPTH_8 (0<<24) | 345 | #define BLT_DEPTH_8 (0<<24) |
| 343 | #define BLT_DEPTH_16_565 (1<<24) | 346 | #define BLT_DEPTH_16_565 (1<<24) |
| 344 | #define BLT_DEPTH_16_1555 (2<<24) | 347 | #define BLT_DEPTH_16_1555 (2<<24) |
| 345 | #define BLT_DEPTH_32 (3<<24) | 348 | #define BLT_DEPTH_32 (3<<24) |
| 346 | #define BLT_ROP_GXCOPY (0xcc<<16) | 349 | #define BLT_ROP_SRC_COPY (0xcc<<16) |
| 350 | #define BLT_ROP_COLOR_COPY (0xf0<<16) | ||
| 347 | #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ | 351 | #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ |
| 348 | #define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ | 352 | #define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ |
| 349 | #define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) | 353 | #define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index a66955037e4e..eee79e1c3222 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -1123,7 +1123,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) | |||
| 1123 | } | 1123 | } |
| 1124 | } | 1124 | } |
| 1125 | 1125 | ||
| 1126 | static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) | 1126 | static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id) |
| 1127 | { | 1127 | { |
| 1128 | DRM_DEBUG_KMS("Falling back to manually reading VBT from " | 1128 | DRM_DEBUG_KMS("Falling back to manually reading VBT from " |
| 1129 | "VBIOS ROM for %s\n", | 1129 | "VBIOS ROM for %s\n", |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 2efaf8e8d9c4..9212e6504e0f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -699,16 +699,21 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
| 699 | goto out; | 699 | goto out; |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | drm_modeset_acquire_init(&ctx, 0); | ||
| 703 | |||
| 702 | /* for pre-945g platforms use load detect */ | 704 | /* for pre-945g platforms use load detect */ |
| 703 | if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) { | 705 | if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) { |
| 704 | if (intel_crt_detect_ddc(connector)) | 706 | if (intel_crt_detect_ddc(connector)) |
| 705 | status = connector_status_connected; | 707 | status = connector_status_connected; |
| 706 | else | 708 | else |
| 707 | status = intel_crt_load_detect(crt); | 709 | status = intel_crt_load_detect(crt); |
| 708 | intel_release_load_detect_pipe(connector, &tmp, &ctx); | 710 | intel_release_load_detect_pipe(connector, &tmp); |
| 709 | } else | 711 | } else |
| 710 | status = connector_status_unknown; | 712 | status = connector_status_unknown; |
| 711 | 713 | ||
| 714 | drm_modeset_drop_locks(&ctx); | ||
| 715 | drm_modeset_acquire_fini(&ctx); | ||
| 716 | |||
| 712 | out: | 717 | out: |
| 713 | intel_display_power_put(dev_priv, power_domain); | 718 | intel_display_power_put(dev_priv, power_domain); |
| 714 | return status; | 719 | return status; |
| @@ -799,7 +804,7 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { | |||
| 799 | .destroy = intel_encoder_destroy, | 804 | .destroy = intel_encoder_destroy, |
| 800 | }; | 805 | }; |
| 801 | 806 | ||
| 802 | static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) | 807 | static int intel_no_crt_dmi_callback(const struct dmi_system_id *id) |
| 803 | { | 808 | { |
| 804 | DRM_INFO("Skipping CRT initialization for %s\n", id->ident); | 809 | DRM_INFO("Skipping CRT initialization for %s\n", id->ident); |
| 805 | return 1; | 810 | return 1; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 018fb7222f60..d8324c69fa86 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2233,6 +2233,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
| 2233 | if (need_vtd_wa(dev) && alignment < 256 * 1024) | 2233 | if (need_vtd_wa(dev) && alignment < 256 * 1024) |
| 2234 | alignment = 256 * 1024; | 2234 | alignment = 256 * 1024; |
| 2235 | 2235 | ||
| 2236 | /* | ||
| 2237 | * Global gtt pte registers are special registers which actually forward | ||
| 2238 | * writes to a chunk of system memory. Which means that there is no risk | ||
| 2239 | * that the register values disappear as soon as we call | ||
| 2240 | * intel_runtime_pm_put(), so it is correct to wrap only the | ||
| 2241 | * pin/unpin/fence and not more. | ||
| 2242 | */ | ||
| 2243 | intel_runtime_pm_get(dev_priv); | ||
| 2244 | |||
| 2236 | dev_priv->mm.interruptible = false; | 2245 | dev_priv->mm.interruptible = false; |
| 2237 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); | 2246 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); |
| 2238 | if (ret) | 2247 | if (ret) |
| @@ -2250,12 +2259,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
| 2250 | i915_gem_object_pin_fence(obj); | 2259 | i915_gem_object_pin_fence(obj); |
| 2251 | 2260 | ||
| 2252 | dev_priv->mm.interruptible = true; | 2261 | dev_priv->mm.interruptible = true; |
| 2262 | intel_runtime_pm_put(dev_priv); | ||
| 2253 | return 0; | 2263 | return 0; |
| 2254 | 2264 | ||
| 2255 | err_unpin: | 2265 | err_unpin: |
| 2256 | i915_gem_object_unpin_from_display_plane(obj); | 2266 | i915_gem_object_unpin_from_display_plane(obj); |
| 2257 | err_interruptible: | 2267 | err_interruptible: |
| 2258 | dev_priv->mm.interruptible = true; | 2268 | dev_priv->mm.interruptible = true; |
| 2269 | intel_runtime_pm_put(dev_priv); | ||
| 2259 | return ret; | 2270 | return ret; |
| 2260 | } | 2271 | } |
| 2261 | 2272 | ||
| @@ -4188,10 +4199,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
| 4188 | intel_set_pch_fifo_underrun_reporting(dev, pipe, false); | 4199 | intel_set_pch_fifo_underrun_reporting(dev, pipe, false); |
| 4189 | 4200 | ||
| 4190 | intel_disable_pipe(dev_priv, pipe); | 4201 | intel_disable_pipe(dev_priv, pipe); |
| 4191 | |||
| 4192 | if (intel_crtc->config.dp_encoder_is_mst) | ||
| 4193 | intel_ddi_set_vc_payload_alloc(crtc, false); | ||
| 4194 | |||
| 4195 | ironlake_pfit_disable(intel_crtc); | 4202 | ironlake_pfit_disable(intel_crtc); |
| 4196 | 4203 | ||
| 4197 | for_each_encoder_on_crtc(dev, crtc, encoder) | 4204 | for_each_encoder_on_crtc(dev, crtc, encoder) |
| @@ -4256,6 +4263,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
| 4256 | intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); | 4263 | intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); |
| 4257 | intel_disable_pipe(dev_priv, pipe); | 4264 | intel_disable_pipe(dev_priv, pipe); |
| 4258 | 4265 | ||
| 4266 | if (intel_crtc->config.dp_encoder_is_mst) | ||
| 4267 | intel_ddi_set_vc_payload_alloc(crtc, false); | ||
| 4268 | |||
| 4259 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); | 4269 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); |
| 4260 | 4270 | ||
| 4261 | ironlake_pfit_disable(intel_crtc); | 4271 | ironlake_pfit_disable(intel_crtc); |
| @@ -8240,6 +8250,15 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, | |||
| 8240 | goto fail_locked; | 8250 | goto fail_locked; |
| 8241 | } | 8251 | } |
| 8242 | 8252 | ||
| 8253 | /* | ||
| 8254 | * Global gtt pte registers are special registers which actually | ||
| 8255 | * forward writes to a chunk of system memory. Which means that | ||
| 8256 | * there is no risk that the register values disappear as soon | ||
| 8257 | * as we call intel_runtime_pm_put(), so it is correct to wrap | ||
| 8258 | * only the pin/unpin/fence and not more. | ||
| 8259 | */ | ||
| 8260 | intel_runtime_pm_get(dev_priv); | ||
| 8261 | |||
| 8243 | /* Note that the w/a also requires 2 PTE of padding following | 8262 | /* Note that the w/a also requires 2 PTE of padding following |
| 8244 | * the bo. We currently fill all unused PTE with the shadow | 8263 | * the bo. We currently fill all unused PTE with the shadow |
| 8245 | * page and so we should always have valid PTE following the | 8264 | * page and so we should always have valid PTE following the |
| @@ -8252,16 +8271,20 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, | |||
| 8252 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); | 8271 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); |
| 8253 | if (ret) { | 8272 | if (ret) { |
| 8254 | DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); | 8273 | DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); |
| 8274 | intel_runtime_pm_put(dev_priv); | ||
| 8255 | goto fail_locked; | 8275 | goto fail_locked; |
| 8256 | } | 8276 | } |
| 8257 | 8277 | ||
| 8258 | ret = i915_gem_object_put_fence(obj); | 8278 | ret = i915_gem_object_put_fence(obj); |
| 8259 | if (ret) { | 8279 | if (ret) { |
| 8260 | DRM_DEBUG_KMS("failed to release fence for cursor"); | 8280 | DRM_DEBUG_KMS("failed to release fence for cursor"); |
| 8281 | intel_runtime_pm_put(dev_priv); | ||
| 8261 | goto fail_unpin; | 8282 | goto fail_unpin; |
| 8262 | } | 8283 | } |
| 8263 | 8284 | ||
| 8264 | addr = i915_gem_obj_ggtt_offset(obj); | 8285 | addr = i915_gem_obj_ggtt_offset(obj); |
| 8286 | |||
| 8287 | intel_runtime_pm_put(dev_priv); | ||
| 8265 | } else { | 8288 | } else { |
| 8266 | int align = IS_I830(dev) ? 16 * 1024 : 256; | 8289 | int align = IS_I830(dev) ? 16 * 1024 : 256; |
| 8267 | ret = i915_gem_object_attach_phys(obj, align); | 8290 | ret = i915_gem_object_attach_phys(obj, align); |
| @@ -8462,8 +8485,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 8462 | connector->base.id, connector->name, | 8485 | connector->base.id, connector->name, |
| 8463 | encoder->base.id, encoder->name); | 8486 | encoder->base.id, encoder->name); |
| 8464 | 8487 | ||
| 8465 | drm_modeset_acquire_init(ctx, 0); | ||
| 8466 | |||
| 8467 | retry: | 8488 | retry: |
| 8468 | ret = drm_modeset_lock(&config->connection_mutex, ctx); | 8489 | ret = drm_modeset_lock(&config->connection_mutex, ctx); |
| 8469 | if (ret) | 8490 | if (ret) |
| @@ -8502,10 +8523,14 @@ retry: | |||
| 8502 | i++; | 8523 | i++; |
| 8503 | if (!(encoder->possible_crtcs & (1 << i))) | 8524 | if (!(encoder->possible_crtcs & (1 << i))) |
| 8504 | continue; | 8525 | continue; |
| 8505 | if (!possible_crtc->enabled) { | 8526 | if (possible_crtc->enabled) |
| 8506 | crtc = possible_crtc; | 8527 | continue; |
| 8507 | break; | 8528 | /* This can occur when applying the pipe A quirk on resume. */ |
| 8508 | } | 8529 | if (to_intel_crtc(possible_crtc)->new_enabled) |
| 8530 | continue; | ||
| 8531 | |||
| 8532 | crtc = possible_crtc; | ||
| 8533 | break; | ||
| 8509 | } | 8534 | } |
| 8510 | 8535 | ||
| 8511 | /* | 8536 | /* |
| @@ -8574,15 +8599,11 @@ fail_unlock: | |||
| 8574 | goto retry; | 8599 | goto retry; |
| 8575 | } | 8600 | } |
| 8576 | 8601 | ||
| 8577 | drm_modeset_drop_locks(ctx); | ||
| 8578 | drm_modeset_acquire_fini(ctx); | ||
| 8579 | |||
| 8580 | return false; | 8602 | return false; |
| 8581 | } | 8603 | } |
| 8582 | 8604 | ||
| 8583 | void intel_release_load_detect_pipe(struct drm_connector *connector, | 8605 | void intel_release_load_detect_pipe(struct drm_connector *connector, |
| 8584 | struct intel_load_detect_pipe *old, | 8606 | struct intel_load_detect_pipe *old) |
| 8585 | struct drm_modeset_acquire_ctx *ctx) | ||
| 8586 | { | 8607 | { |
| 8587 | struct intel_encoder *intel_encoder = | 8608 | struct intel_encoder *intel_encoder = |
| 8588 | intel_attached_encoder(connector); | 8609 | intel_attached_encoder(connector); |
| @@ -8606,17 +8627,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, | |||
| 8606 | drm_framebuffer_unreference(old->release_fb); | 8627 | drm_framebuffer_unreference(old->release_fb); |
| 8607 | } | 8628 | } |
| 8608 | 8629 | ||
| 8609 | goto unlock; | ||
| 8610 | return; | 8630 | return; |
| 8611 | } | 8631 | } |
| 8612 | 8632 | ||
| 8613 | /* Switch crtc and encoder back off if necessary */ | 8633 | /* Switch crtc and encoder back off if necessary */ |
| 8614 | if (old->dpms_mode != DRM_MODE_DPMS_ON) | 8634 | if (old->dpms_mode != DRM_MODE_DPMS_ON) |
| 8615 | connector->funcs->dpms(connector, old->dpms_mode); | 8635 | connector->funcs->dpms(connector, old->dpms_mode); |
| 8616 | |||
| 8617 | unlock: | ||
| 8618 | drm_modeset_drop_locks(ctx); | ||
| 8619 | drm_modeset_acquire_fini(ctx); | ||
| 8620 | } | 8636 | } |
| 8621 | 8637 | ||
| 8622 | static int i9xx_pll_refclk(struct drm_device *dev, | 8638 | static int i9xx_pll_refclk(struct drm_device *dev, |
| @@ -11700,8 +11716,8 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 11700 | }; | 11716 | }; |
| 11701 | const struct drm_rect clip = { | 11717 | const struct drm_rect clip = { |
| 11702 | /* integer pixels */ | 11718 | /* integer pixels */ |
| 11703 | .x2 = intel_crtc->config.pipe_src_w, | 11719 | .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, |
| 11704 | .y2 = intel_crtc->config.pipe_src_h, | 11720 | .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, |
| 11705 | }; | 11721 | }; |
| 11706 | bool visible; | 11722 | bool visible; |
| 11707 | int ret; | 11723 | int ret; |
| @@ -12488,6 +12504,9 @@ static struct intel_quirk intel_quirks[] = { | |||
| 12488 | /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ | 12504 | /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ |
| 12489 | { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, | 12505 | { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, |
| 12490 | 12506 | ||
| 12507 | /* Acer C720 Chromebook (Core i3 4005U) */ | ||
| 12508 | { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present }, | ||
| 12509 | |||
| 12491 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ | 12510 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ |
| 12492 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, | 12511 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, |
| 12493 | 12512 | ||
| @@ -12659,7 +12678,7 @@ static void intel_enable_pipe_a(struct drm_device *dev) | |||
| 12659 | struct intel_connector *connector; | 12678 | struct intel_connector *connector; |
| 12660 | struct drm_connector *crt = NULL; | 12679 | struct drm_connector *crt = NULL; |
| 12661 | struct intel_load_detect_pipe load_detect_temp; | 12680 | struct intel_load_detect_pipe load_detect_temp; |
| 12662 | struct drm_modeset_acquire_ctx ctx; | 12681 | struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx; |
| 12663 | 12682 | ||
| 12664 | /* We can't just switch on the pipe A, we need to set things up with a | 12683 | /* We can't just switch on the pipe A, we need to set things up with a |
| 12665 | * proper mode and output configuration. As a gross hack, enable pipe A | 12684 | * proper mode and output configuration. As a gross hack, enable pipe A |
| @@ -12676,10 +12695,8 @@ static void intel_enable_pipe_a(struct drm_device *dev) | |||
| 12676 | if (!crt) | 12695 | if (!crt) |
| 12677 | return; | 12696 | return; |
| 12678 | 12697 | ||
| 12679 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, &ctx)) | 12698 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx)) |
| 12680 | intel_release_load_detect_pipe(crt, &load_detect_temp, &ctx); | 12699 | intel_release_load_detect_pipe(crt, &load_detect_temp); |
| 12681 | |||
| 12682 | |||
| 12683 | } | 12700 | } |
| 12684 | 12701 | ||
| 12685 | static bool | 12702 | static bool |
| @@ -13112,7 +13129,7 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
| 13112 | * experience fancy races otherwise. | 13129 | * experience fancy races otherwise. |
| 13113 | */ | 13130 | */ |
| 13114 | drm_irq_uninstall(dev); | 13131 | drm_irq_uninstall(dev); |
| 13115 | cancel_work_sync(&dev_priv->hotplug_work); | 13132 | intel_hpd_cancel_work(dev_priv); |
| 13116 | dev_priv->pm._irqs_disabled = true; | 13133 | dev_priv->pm._irqs_disabled = true; |
| 13117 | 13134 | ||
| 13118 | /* | 13135 | /* |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ee3942f0b068..81d7681faa63 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -3553,6 +3553,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
| 3553 | if (WARN_ON(!intel_encoder->base.crtc)) | 3553 | if (WARN_ON(!intel_encoder->base.crtc)) |
| 3554 | return; | 3554 | return; |
| 3555 | 3555 | ||
| 3556 | if (!to_intel_crtc(intel_encoder->base.crtc)->active) | ||
| 3557 | return; | ||
| 3558 | |||
| 3556 | /* Try to read receiver status if the link appears to be up */ | 3559 | /* Try to read receiver status if the link appears to be up */ |
| 3557 | if (!intel_dp_get_link_status(intel_dp, link_status)) { | 3560 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
| 3558 | return; | 3561 | return; |
| @@ -3658,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
| 3658 | return intel_dp_detect_dpcd(intel_dp); | 3661 | return intel_dp_detect_dpcd(intel_dp); |
| 3659 | } | 3662 | } |
| 3660 | 3663 | ||
| 3661 | static enum drm_connector_status | 3664 | static int g4x_digital_port_connected(struct drm_device *dev, |
| 3662 | g4x_dp_detect(struct intel_dp *intel_dp) | 3665 | struct intel_digital_port *intel_dig_port) |
| 3663 | { | 3666 | { |
| 3664 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
| 3665 | struct drm_i915_private *dev_priv = dev->dev_private; | 3667 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3666 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
| 3667 | uint32_t bit; | 3668 | uint32_t bit; |
| 3668 | 3669 | ||
| 3669 | /* Can't disconnect eDP, but you can close the lid... */ | ||
| 3670 | if (is_edp(intel_dp)) { | ||
| 3671 | enum drm_connector_status status; | ||
| 3672 | |||
| 3673 | status = intel_panel_detect(dev); | ||
| 3674 | if (status == connector_status_unknown) | ||
| 3675 | status = connector_status_connected; | ||
| 3676 | return status; | ||
| 3677 | } | ||
| 3678 | |||
| 3679 | if (IS_VALLEYVIEW(dev)) { | 3670 | if (IS_VALLEYVIEW(dev)) { |
| 3680 | switch (intel_dig_port->port) { | 3671 | switch (intel_dig_port->port) { |
| 3681 | case PORT_B: | 3672 | case PORT_B: |
| @@ -3688,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
| 3688 | bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; | 3679 | bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; |
| 3689 | break; | 3680 | break; |
| 3690 | default: | 3681 | default: |
| 3691 | return connector_status_unknown; | 3682 | return -EINVAL; |
| 3692 | } | 3683 | } |
| 3693 | } else { | 3684 | } else { |
| 3694 | switch (intel_dig_port->port) { | 3685 | switch (intel_dig_port->port) { |
| @@ -3702,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
| 3702 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; | 3693 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; |
| 3703 | break; | 3694 | break; |
| 3704 | default: | 3695 | default: |
| 3705 | return connector_status_unknown; | 3696 | return -EINVAL; |
| 3706 | } | 3697 | } |
| 3707 | } | 3698 | } |
| 3708 | 3699 | ||
| 3709 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) | 3700 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) |
| 3701 | return 0; | ||
| 3702 | return 1; | ||
| 3703 | } | ||
| 3704 | |||
| 3705 | static enum drm_connector_status | ||
| 3706 | g4x_dp_detect(struct intel_dp *intel_dp) | ||
| 3707 | { | ||
| 3708 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
| 3709 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
| 3710 | int ret; | ||
| 3711 | |||
| 3712 | /* Can't disconnect eDP, but you can close the lid... */ | ||
| 3713 | if (is_edp(intel_dp)) { | ||
| 3714 | enum drm_connector_status status; | ||
| 3715 | |||
| 3716 | status = intel_panel_detect(dev); | ||
| 3717 | if (status == connector_status_unknown) | ||
| 3718 | status = connector_status_connected; | ||
| 3719 | return status; | ||
| 3720 | } | ||
| 3721 | |||
| 3722 | ret = g4x_digital_port_connected(dev, intel_dig_port); | ||
| 3723 | if (ret == -EINVAL) | ||
| 3724 | return connector_status_unknown; | ||
| 3725 | else if (ret == 0) | ||
| 3710 | return connector_status_disconnected; | 3726 | return connector_status_disconnected; |
| 3711 | 3727 | ||
| 3712 | return intel_dp_detect_dpcd(intel_dp); | 3728 | return intel_dp_detect_dpcd(intel_dp); |
| @@ -4003,6 +4019,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) | |||
| 4003 | kfree(intel_dig_port); | 4019 | kfree(intel_dig_port); |
| 4004 | } | 4020 | } |
| 4005 | 4021 | ||
| 4022 | static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | ||
| 4023 | { | ||
| 4024 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); | ||
| 4025 | |||
| 4026 | if (!is_edp(intel_dp)) | ||
| 4027 | return; | ||
| 4028 | |||
| 4029 | edp_panel_vdd_off_sync(intel_dp); | ||
| 4030 | } | ||
| 4031 | |||
| 4006 | static void intel_dp_encoder_reset(struct drm_encoder *encoder) | 4032 | static void intel_dp_encoder_reset(struct drm_encoder *encoder) |
| 4007 | { | 4033 | { |
| 4008 | intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); | 4034 | intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); |
| @@ -4037,18 +4063,30 @@ bool | |||
| 4037 | intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | 4063 | intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) |
| 4038 | { | 4064 | { |
| 4039 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 4065 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
| 4066 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
| 4040 | struct drm_device *dev = intel_dig_port->base.base.dev; | 4067 | struct drm_device *dev = intel_dig_port->base.base.dev; |
| 4041 | struct drm_i915_private *dev_priv = dev->dev_private; | 4068 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 4042 | int ret; | 4069 | enum intel_display_power_domain power_domain; |
| 4070 | bool ret = true; | ||
| 4071 | |||
| 4043 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) | 4072 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) |
| 4044 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; | 4073 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; |
| 4045 | 4074 | ||
| 4046 | DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port, | 4075 | DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port, |
| 4047 | long_hpd ? "long" : "short"); | 4076 | long_hpd ? "long" : "short"); |
| 4048 | 4077 | ||
| 4078 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
| 4079 | intel_display_power_get(dev_priv, power_domain); | ||
| 4080 | |||
| 4049 | if (long_hpd) { | 4081 | if (long_hpd) { |
| 4050 | if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) | 4082 | |
| 4051 | goto mst_fail; | 4083 | if (HAS_PCH_SPLIT(dev)) { |
| 4084 | if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) | ||
| 4085 | goto mst_fail; | ||
| 4086 | } else { | ||
| 4087 | if (g4x_digital_port_connected(dev, intel_dig_port) != 1) | ||
| 4088 | goto mst_fail; | ||
| 4089 | } | ||
| 4052 | 4090 | ||
| 4053 | if (!intel_dp_get_dpcd(intel_dp)) { | 4091 | if (!intel_dp_get_dpcd(intel_dp)) { |
| 4054 | goto mst_fail; | 4092 | goto mst_fail; |
| @@ -4061,8 +4099,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
| 4061 | 4099 | ||
| 4062 | } else { | 4100 | } else { |
| 4063 | if (intel_dp->is_mst) { | 4101 | if (intel_dp->is_mst) { |
| 4064 | ret = intel_dp_check_mst_status(intel_dp); | 4102 | if (intel_dp_check_mst_status(intel_dp) == -EINVAL) |
| 4065 | if (ret == -EINVAL) | ||
| 4066 | goto mst_fail; | 4103 | goto mst_fail; |
| 4067 | } | 4104 | } |
| 4068 | 4105 | ||
| @@ -4076,7 +4113,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
| 4076 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | 4113 | drm_modeset_unlock(&dev->mode_config.connection_mutex); |
| 4077 | } | 4114 | } |
| 4078 | } | 4115 | } |
| 4079 | return false; | 4116 | ret = false; |
| 4117 | goto put_power; | ||
| 4080 | mst_fail: | 4118 | mst_fail: |
| 4081 | /* if we were in MST mode, and device is not there get out of MST mode */ | 4119 | /* if we were in MST mode, and device is not there get out of MST mode */ |
| 4082 | if (intel_dp->is_mst) { | 4120 | if (intel_dp->is_mst) { |
| @@ -4084,7 +4122,10 @@ mst_fail: | |||
| 4084 | intel_dp->is_mst = false; | 4122 | intel_dp->is_mst = false; |
| 4085 | drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); | 4123 | drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); |
| 4086 | } | 4124 | } |
| 4087 | return true; | 4125 | put_power: |
| 4126 | intel_display_power_put(dev_priv, power_domain); | ||
| 4127 | |||
| 4128 | return ret; | ||
| 4088 | } | 4129 | } |
| 4089 | 4130 | ||
| 4090 | /* Return which DP Port should be selected for Transcoder DP control */ | 4131 | /* Return which DP Port should be selected for Transcoder DP control */ |
| @@ -4722,6 +4763,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
| 4722 | intel_encoder->disable = intel_disable_dp; | 4763 | intel_encoder->disable = intel_disable_dp; |
| 4723 | intel_encoder->get_hw_state = intel_dp_get_hw_state; | 4764 | intel_encoder->get_hw_state = intel_dp_get_hw_state; |
| 4724 | intel_encoder->get_config = intel_dp_get_config; | 4765 | intel_encoder->get_config = intel_dp_get_config; |
| 4766 | intel_encoder->suspend = intel_dp_encoder_suspend; | ||
| 4725 | if (IS_CHERRYVIEW(dev)) { | 4767 | if (IS_CHERRYVIEW(dev)) { |
| 4726 | intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; | 4768 | intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; |
| 4727 | intel_encoder->pre_enable = chv_pre_enable_dp; | 4769 | intel_encoder->pre_enable = chv_pre_enable_dp; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4b2664bd5b81..b8c8bbd8e5f9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -153,6 +153,12 @@ struct intel_encoder { | |||
| 153 | * be set correctly before calling this function. */ | 153 | * be set correctly before calling this function. */ |
| 154 | void (*get_config)(struct intel_encoder *, | 154 | void (*get_config)(struct intel_encoder *, |
| 155 | struct intel_crtc_config *pipe_config); | 155 | struct intel_crtc_config *pipe_config); |
| 156 | /* | ||
| 157 | * Called during system suspend after all pending requests for the | ||
| 158 | * encoder are flushed (for example for DP AUX transactions) and | ||
| 159 | * device interrupts are disabled. | ||
| 160 | */ | ||
| 161 | void (*suspend)(struct intel_encoder *); | ||
| 156 | int crtc_mask; | 162 | int crtc_mask; |
| 157 | enum hpd_pin hpd_pin; | 163 | enum hpd_pin hpd_pin; |
| 158 | }; | 164 | }; |
| @@ -830,8 +836,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 830 | struct intel_load_detect_pipe *old, | 836 | struct intel_load_detect_pipe *old, |
| 831 | struct drm_modeset_acquire_ctx *ctx); | 837 | struct drm_modeset_acquire_ctx *ctx); |
| 832 | void intel_release_load_detect_pipe(struct drm_connector *connector, | 838 | void intel_release_load_detect_pipe(struct drm_connector *connector, |
| 833 | struct intel_load_detect_pipe *old, | 839 | struct intel_load_detect_pipe *old); |
| 834 | struct drm_modeset_acquire_ctx *ctx); | ||
| 835 | int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 840 | int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
| 836 | struct drm_i915_gem_object *obj, | 841 | struct drm_i915_gem_object *obj, |
| 837 | struct intel_engine_cs *pipelined); | 842 | struct intel_engine_cs *pipelined); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 881361c0f27e..fdf40267249c 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -538,7 +538,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | |||
| 538 | .destroy = intel_encoder_destroy, | 538 | .destroy = intel_encoder_destroy, |
| 539 | }; | 539 | }; |
| 540 | 540 | ||
| 541 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | 541 | static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
| 542 | { | 542 | { |
| 543 | DRM_INFO("Skipping LVDS initialization for %s\n", id->ident); | 543 | DRM_INFO("Skipping LVDS initialization for %s\n", id->ident); |
| 544 | return 1; | 544 | return 1; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 59b028f0b1e8..8e374449c6b5 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -801,7 +801,7 @@ static void pch_enable_backlight(struct intel_connector *connector) | |||
| 801 | 801 | ||
| 802 | cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); | 802 | cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); |
| 803 | if (cpu_ctl2 & BLM_PWM_ENABLE) { | 803 | if (cpu_ctl2 & BLM_PWM_ENABLE) { |
| 804 | WARN(1, "cpu backlight already enabled\n"); | 804 | DRM_DEBUG_KMS("cpu backlight already enabled\n"); |
| 805 | cpu_ctl2 &= ~BLM_PWM_ENABLE; | 805 | cpu_ctl2 &= ~BLM_PWM_ENABLE; |
| 806 | I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); | 806 | I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); |
| 807 | } | 807 | } |
| @@ -845,7 +845,7 @@ static void i9xx_enable_backlight(struct intel_connector *connector) | |||
| 845 | 845 | ||
| 846 | ctl = I915_READ(BLC_PWM_CTL); | 846 | ctl = I915_READ(BLC_PWM_CTL); |
| 847 | if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { | 847 | if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { |
| 848 | WARN(1, "backlight already enabled\n"); | 848 | DRM_DEBUG_KMS("backlight already enabled\n"); |
| 849 | I915_WRITE(BLC_PWM_CTL, 0); | 849 | I915_WRITE(BLC_PWM_CTL, 0); |
| 850 | } | 850 | } |
| 851 | 851 | ||
| @@ -876,7 +876,7 @@ static void i965_enable_backlight(struct intel_connector *connector) | |||
| 876 | 876 | ||
| 877 | ctl2 = I915_READ(BLC_PWM_CTL2); | 877 | ctl2 = I915_READ(BLC_PWM_CTL2); |
| 878 | if (ctl2 & BLM_PWM_ENABLE) { | 878 | if (ctl2 & BLM_PWM_ENABLE) { |
| 879 | WARN(1, "backlight already enabled\n"); | 879 | DRM_DEBUG_KMS("backlight already enabled\n"); |
| 880 | ctl2 &= ~BLM_PWM_ENABLE; | 880 | ctl2 &= ~BLM_PWM_ENABLE; |
| 881 | I915_WRITE(BLC_PWM_CTL2, ctl2); | 881 | I915_WRITE(BLC_PWM_CTL2, ctl2); |
| 882 | } | 882 | } |
| @@ -910,7 +910,7 @@ static void vlv_enable_backlight(struct intel_connector *connector) | |||
| 910 | 910 | ||
| 911 | ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); | 911 | ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); |
| 912 | if (ctl2 & BLM_PWM_ENABLE) { | 912 | if (ctl2 & BLM_PWM_ENABLE) { |
| 913 | WARN(1, "backlight already enabled\n"); | 913 | DRM_DEBUG_KMS("backlight already enabled\n"); |
| 914 | ctl2 &= ~BLM_PWM_ENABLE; | 914 | ctl2 &= ~BLM_PWM_ENABLE; |
| 915 | I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); | 915 | I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); |
| 916 | } | 916 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 16371a444426..2d068edd1adc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -1363,54 +1363,66 @@ i965_dispatch_execbuffer(struct intel_engine_cs *ring, | |||
| 1363 | 1363 | ||
| 1364 | /* Just userspace ABI convention to limit the wa batch bo to a resonable size */ | 1364 | /* Just userspace ABI convention to limit the wa batch bo to a resonable size */ |
| 1365 | #define I830_BATCH_LIMIT (256*1024) | 1365 | #define I830_BATCH_LIMIT (256*1024) |
| 1366 | #define I830_TLB_ENTRIES (2) | ||
| 1367 | #define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) | ||
| 1366 | static int | 1368 | static int |
| 1367 | i830_dispatch_execbuffer(struct intel_engine_cs *ring, | 1369 | i830_dispatch_execbuffer(struct intel_engine_cs *ring, |
| 1368 | u64 offset, u32 len, | 1370 | u64 offset, u32 len, |
| 1369 | unsigned flags) | 1371 | unsigned flags) |
| 1370 | { | 1372 | { |
| 1373 | u32 cs_offset = ring->scratch.gtt_offset; | ||
| 1371 | int ret; | 1374 | int ret; |
| 1372 | 1375 | ||
| 1373 | if (flags & I915_DISPATCH_PINNED) { | 1376 | ret = intel_ring_begin(ring, 6); |
| 1374 | ret = intel_ring_begin(ring, 4); | 1377 | if (ret) |
| 1375 | if (ret) | 1378 | return ret; |
| 1376 | return ret; | ||
| 1377 | 1379 | ||
| 1378 | intel_ring_emit(ring, MI_BATCH_BUFFER); | 1380 | /* Evict the invalid PTE TLBs */ |
| 1379 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); | 1381 | intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA); |
| 1380 | intel_ring_emit(ring, offset + len - 8); | 1382 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096); |
| 1381 | intel_ring_emit(ring, MI_NOOP); | 1383 | intel_ring_emit(ring, I830_TLB_ENTRIES << 16 | 4); /* load each page */ |
| 1382 | intel_ring_advance(ring); | 1384 | intel_ring_emit(ring, cs_offset); |
| 1383 | } else { | 1385 | intel_ring_emit(ring, 0xdeadbeef); |
| 1384 | u32 cs_offset = ring->scratch.gtt_offset; | 1386 | intel_ring_emit(ring, MI_NOOP); |
| 1387 | intel_ring_advance(ring); | ||
| 1385 | 1388 | ||
| 1389 | if ((flags & I915_DISPATCH_PINNED) == 0) { | ||
| 1386 | if (len > I830_BATCH_LIMIT) | 1390 | if (len > I830_BATCH_LIMIT) |
| 1387 | return -ENOSPC; | 1391 | return -ENOSPC; |
| 1388 | 1392 | ||
| 1389 | ret = intel_ring_begin(ring, 9+3); | 1393 | ret = intel_ring_begin(ring, 6 + 2); |
| 1390 | if (ret) | 1394 | if (ret) |
| 1391 | return ret; | 1395 | return ret; |
| 1392 | /* Blit the batch (which has now all relocs applied) to the stable batch | 1396 | |
| 1393 | * scratch bo area (so that the CS never stumbles over its tlb | 1397 | /* Blit the batch (which has now all relocs applied) to the |
| 1394 | * invalidation bug) ... */ | 1398 | * stable batch scratch bo area (so that the CS never |
| 1395 | intel_ring_emit(ring, XY_SRC_COPY_BLT_CMD | | 1399 | * stumbles over its tlb invalidation bug) ... |
| 1396 | XY_SRC_COPY_BLT_WRITE_ALPHA | | 1400 | */ |
| 1397 | XY_SRC_COPY_BLT_WRITE_RGB); | 1401 | intel_ring_emit(ring, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); |
| 1398 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_GXCOPY | 4096); | 1402 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); |
| 1399 | intel_ring_emit(ring, 0); | 1403 | intel_ring_emit(ring, DIV_ROUND_UP(len, 4096) << 16 | 1024); |
| 1400 | intel_ring_emit(ring, (DIV_ROUND_UP(len, 4096) << 16) | 1024); | ||
| 1401 | intel_ring_emit(ring, cs_offset); | 1404 | intel_ring_emit(ring, cs_offset); |
| 1402 | intel_ring_emit(ring, 0); | ||
| 1403 | intel_ring_emit(ring, 4096); | 1405 | intel_ring_emit(ring, 4096); |
| 1404 | intel_ring_emit(ring, offset); | 1406 | intel_ring_emit(ring, offset); |
| 1407 | |||
| 1405 | intel_ring_emit(ring, MI_FLUSH); | 1408 | intel_ring_emit(ring, MI_FLUSH); |
| 1409 | intel_ring_emit(ring, MI_NOOP); | ||
| 1410 | intel_ring_advance(ring); | ||
| 1406 | 1411 | ||
| 1407 | /* ... and execute it. */ | 1412 | /* ... and execute it. */ |
| 1408 | intel_ring_emit(ring, MI_BATCH_BUFFER); | 1413 | offset = cs_offset; |
| 1409 | intel_ring_emit(ring, cs_offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); | ||
| 1410 | intel_ring_emit(ring, cs_offset + len - 8); | ||
| 1411 | intel_ring_advance(ring); | ||
| 1412 | } | 1414 | } |
| 1413 | 1415 | ||
| 1416 | ret = intel_ring_begin(ring, 4); | ||
| 1417 | if (ret) | ||
| 1418 | return ret; | ||
| 1419 | |||
| 1420 | intel_ring_emit(ring, MI_BATCH_BUFFER); | ||
| 1421 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); | ||
| 1422 | intel_ring_emit(ring, offset + len - 8); | ||
| 1423 | intel_ring_emit(ring, MI_NOOP); | ||
| 1424 | intel_ring_advance(ring); | ||
| 1425 | |||
| 1414 | return 0; | 1426 | return 0; |
| 1415 | } | 1427 | } |
| 1416 | 1428 | ||
| @@ -2200,7 +2212,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 2200 | 2212 | ||
| 2201 | /* Workaround batchbuffer to combat CS tlb bug. */ | 2213 | /* Workaround batchbuffer to combat CS tlb bug. */ |
| 2202 | if (HAS_BROKEN_CS_TLB(dev)) { | 2214 | if (HAS_BROKEN_CS_TLB(dev)) { |
| 2203 | obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT); | 2215 | obj = i915_gem_alloc_object(dev, I830_WA_SIZE); |
| 2204 | if (obj == NULL) { | 2216 | if (obj == NULL) { |
| 2205 | DRM_ERROR("Failed to allocate batch bo\n"); | 2217 | DRM_ERROR("Failed to allocate batch bo\n"); |
| 2206 | return -ENOMEM; | 2218 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index e211eef4b7e4..c14341ca3ef9 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -854,6 +854,10 @@ intel_enable_tv(struct intel_encoder *encoder) | |||
| 854 | struct drm_device *dev = encoder->base.dev; | 854 | struct drm_device *dev = encoder->base.dev; |
| 855 | struct drm_i915_private *dev_priv = dev->dev_private; | 855 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 856 | 856 | ||
| 857 | /* Prevents vblank waits from timing out in intel_tv_detect_type() */ | ||
| 858 | intel_wait_for_vblank(encoder->base.dev, | ||
| 859 | to_intel_crtc(encoder->base.crtc)->pipe); | ||
| 860 | |||
| 857 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); | 861 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); |
| 858 | } | 862 | } |
| 859 | 863 | ||
| @@ -1311,6 +1315,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
| 1311 | { | 1315 | { |
| 1312 | struct drm_display_mode mode; | 1316 | struct drm_display_mode mode; |
| 1313 | struct intel_tv *intel_tv = intel_attached_tv(connector); | 1317 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
| 1318 | enum drm_connector_status status; | ||
| 1314 | int type; | 1319 | int type; |
| 1315 | 1320 | ||
| 1316 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", | 1321 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", |
| @@ -1323,16 +1328,24 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
| 1323 | struct intel_load_detect_pipe tmp; | 1328 | struct intel_load_detect_pipe tmp; |
| 1324 | struct drm_modeset_acquire_ctx ctx; | 1329 | struct drm_modeset_acquire_ctx ctx; |
| 1325 | 1330 | ||
| 1331 | drm_modeset_acquire_init(&ctx, 0); | ||
| 1332 | |||
| 1326 | if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { | 1333 | if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { |
| 1327 | type = intel_tv_detect_type(intel_tv, connector); | 1334 | type = intel_tv_detect_type(intel_tv, connector); |
| 1328 | intel_release_load_detect_pipe(connector, &tmp, &ctx); | 1335 | intel_release_load_detect_pipe(connector, &tmp); |
| 1336 | status = type < 0 ? | ||
| 1337 | connector_status_disconnected : | ||
| 1338 | connector_status_connected; | ||
| 1329 | } else | 1339 | } else |
| 1330 | return connector_status_unknown; | 1340 | status = connector_status_unknown; |
| 1341 | |||
| 1342 | drm_modeset_drop_locks(&ctx); | ||
| 1343 | drm_modeset_acquire_fini(&ctx); | ||
| 1331 | } else | 1344 | } else |
| 1332 | return connector->status; | 1345 | return connector->status; |
| 1333 | 1346 | ||
| 1334 | if (type < 0) | 1347 | if (status != connector_status_connected) |
| 1335 | return connector_status_disconnected; | 1348 | return status; |
| 1336 | 1349 | ||
| 1337 | intel_tv->type = type; | 1350 | intel_tv->type = type; |
| 1338 | intel_tv_find_better_format(connector); | 1351 | intel_tv_find_better_format(connector); |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index a125a7e32742..c6c9b02e0ada 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c | |||
| @@ -258,28 +258,30 @@ static void set_hdmi_pdev(struct drm_device *dev, | |||
| 258 | priv->hdmi_pdev = pdev; | 258 | priv->hdmi_pdev = pdev; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | #ifdef CONFIG_OF | ||
| 262 | static int get_gpio(struct device *dev, struct device_node *of_node, const char *name) | ||
| 263 | { | ||
| 264 | int gpio = of_get_named_gpio(of_node, name, 0); | ||
| 265 | if (gpio < 0) { | ||
| 266 | char name2[32]; | ||
| 267 | snprintf(name2, sizeof(name2), "%s-gpio", name); | ||
| 268 | gpio = of_get_named_gpio(of_node, name2, 0); | ||
| 269 | if (gpio < 0) { | ||
| 270 | dev_err(dev, "failed to get gpio: %s (%d)\n", | ||
| 271 | name, gpio); | ||
| 272 | gpio = -1; | ||
| 273 | } | ||
| 274 | } | ||
| 275 | return gpio; | ||
| 276 | } | ||
| 277 | #endif | ||
| 278 | |||
| 261 | static int hdmi_bind(struct device *dev, struct device *master, void *data) | 279 | static int hdmi_bind(struct device *dev, struct device *master, void *data) |
| 262 | { | 280 | { |
| 263 | static struct hdmi_platform_config config = {}; | 281 | static struct hdmi_platform_config config = {}; |
| 264 | #ifdef CONFIG_OF | 282 | #ifdef CONFIG_OF |
| 265 | struct device_node *of_node = dev->of_node; | 283 | struct device_node *of_node = dev->of_node; |
| 266 | 284 | ||
| 267 | int get_gpio(const char *name) | ||
| 268 | { | ||
| 269 | int gpio = of_get_named_gpio(of_node, name, 0); | ||
| 270 | if (gpio < 0) { | ||
| 271 | char name2[32]; | ||
| 272 | snprintf(name2, sizeof(name2), "%s-gpio", name); | ||
| 273 | gpio = of_get_named_gpio(of_node, name2, 0); | ||
| 274 | if (gpio < 0) { | ||
| 275 | dev_err(dev, "failed to get gpio: %s (%d)\n", | ||
| 276 | name, gpio); | ||
| 277 | gpio = -1; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | return gpio; | ||
| 281 | } | ||
| 282 | |||
| 283 | if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) { | 285 | if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) { |
| 284 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; | 286 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; |
| 285 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; | 287 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; |
| @@ -312,12 +314,12 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 312 | } | 314 | } |
| 313 | 315 | ||
| 314 | config.mmio_name = "core_physical"; | 316 | config.mmio_name = "core_physical"; |
| 315 | config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk"); | 317 | config.ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk"); |
| 316 | config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data"); | 318 | config.ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data"); |
| 317 | config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd"); | 319 | config.hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd"); |
| 318 | config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en"); | 320 | config.mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en"); |
| 319 | config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel"); | 321 | config.mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel"); |
| 320 | config.mux_lpm_gpio = get_gpio("qcom,hdmi-tx-mux-lpm"); | 322 | config.mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm"); |
| 321 | 323 | ||
| 322 | #else | 324 | #else |
| 323 | static const char *hpd_clk_names[] = { | 325 | static const char *hpd_clk_names[] = { |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c index 902d7685d441..f408b69486a8 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | |||
| @@ -15,19 +15,25 @@ | |||
| 15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_COMMON_CLK | ||
| 18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| 19 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
| 21 | #endif | ||
| 20 | 22 | ||
| 21 | #include "hdmi.h" | 23 | #include "hdmi.h" |
| 22 | 24 | ||
| 23 | struct hdmi_phy_8960 { | 25 | struct hdmi_phy_8960 { |
| 24 | struct hdmi_phy base; | 26 | struct hdmi_phy base; |
| 25 | struct hdmi *hdmi; | 27 | struct hdmi *hdmi; |
| 28 | #ifdef CONFIG_COMMON_CLK | ||
| 26 | struct clk_hw pll_hw; | 29 | struct clk_hw pll_hw; |
| 27 | struct clk *pll; | 30 | struct clk *pll; |
| 28 | unsigned long pixclk; | 31 | unsigned long pixclk; |
| 32 | #endif | ||
| 29 | }; | 33 | }; |
| 30 | #define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base) | 34 | #define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base) |
| 35 | |||
| 36 | #ifdef CONFIG_COMMON_CLK | ||
| 31 | #define clk_to_phy(x) container_of(x, struct hdmi_phy_8960, pll_hw) | 37 | #define clk_to_phy(x) container_of(x, struct hdmi_phy_8960, pll_hw) |
| 32 | 38 | ||
| 33 | /* | 39 | /* |
| @@ -374,7 +380,7 @@ static struct clk_init_data pll_init = { | |||
| 374 | .parent_names = hdmi_pll_parents, | 380 | .parent_names = hdmi_pll_parents, |
| 375 | .num_parents = ARRAY_SIZE(hdmi_pll_parents), | 381 | .num_parents = ARRAY_SIZE(hdmi_pll_parents), |
| 376 | }; | 382 | }; |
| 377 | 383 | #endif | |
| 378 | 384 | ||
| 379 | /* | 385 | /* |
| 380 | * HDMI Phy: | 386 | * HDMI Phy: |
| @@ -480,12 +486,15 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi) | |||
| 480 | { | 486 | { |
| 481 | struct hdmi_phy_8960 *phy_8960; | 487 | struct hdmi_phy_8960 *phy_8960; |
| 482 | struct hdmi_phy *phy = NULL; | 488 | struct hdmi_phy *phy = NULL; |
| 483 | int ret, i; | 489 | int ret; |
| 490 | #ifdef CONFIG_COMMON_CLK | ||
| 491 | int i; | ||
| 484 | 492 | ||
| 485 | /* sanity check: */ | 493 | /* sanity check: */ |
| 486 | for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++) | 494 | for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++) |
| 487 | if (WARN_ON(freqtbl[i].rate < freqtbl[i+1].rate)) | 495 | if (WARN_ON(freqtbl[i].rate < freqtbl[i+1].rate)) |
| 488 | return ERR_PTR(-EINVAL); | 496 | return ERR_PTR(-EINVAL); |
| 497 | #endif | ||
| 489 | 498 | ||
| 490 | phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL); | 499 | phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL); |
| 491 | if (!phy_8960) { | 500 | if (!phy_8960) { |
| @@ -499,6 +508,7 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi) | |||
| 499 | 508 | ||
| 500 | phy_8960->hdmi = hdmi; | 509 | phy_8960->hdmi = hdmi; |
| 501 | 510 | ||
| 511 | #ifdef CONFIG_COMMON_CLK | ||
| 502 | phy_8960->pll_hw.init = &pll_init; | 512 | phy_8960->pll_hw.init = &pll_init; |
| 503 | phy_8960->pll = devm_clk_register(hdmi->dev->dev, &phy_8960->pll_hw); | 513 | phy_8960->pll = devm_clk_register(hdmi->dev->dev, &phy_8960->pll_hw); |
| 504 | if (IS_ERR(phy_8960->pll)) { | 514 | if (IS_ERR(phy_8960->pll)) { |
| @@ -506,6 +516,7 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi) | |||
| 506 | phy_8960->pll = NULL; | 516 | phy_8960->pll = NULL; |
| 507 | goto fail; | 517 | goto fail; |
| 508 | } | 518 | } |
| 519 | #endif | ||
| 509 | 520 | ||
| 510 | return phy; | 521 | return phy; |
| 511 | 522 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 74cebb51e8c2..c6c80ea28c35 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
| @@ -397,6 +397,7 @@ static void mdp4_crtc_prepare(struct drm_crtc *crtc) | |||
| 397 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 397 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 398 | DBG("%s", mdp4_crtc->name); | 398 | DBG("%s", mdp4_crtc->name); |
| 399 | /* make sure we hold a ref to mdp clks while setting up mode: */ | 399 | /* make sure we hold a ref to mdp clks while setting up mode: */ |
| 400 | drm_crtc_vblank_get(crtc); | ||
| 400 | mdp4_enable(get_kms(crtc)); | 401 | mdp4_enable(get_kms(crtc)); |
| 401 | mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 402 | mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 402 | } | 403 | } |
| @@ -407,6 +408,7 @@ static void mdp4_crtc_commit(struct drm_crtc *crtc) | |||
| 407 | crtc_flush(crtc); | 408 | crtc_flush(crtc); |
| 408 | /* drop the ref to mdp clk's that we got in prepare: */ | 409 | /* drop the ref to mdp clk's that we got in prepare: */ |
| 409 | mdp4_disable(get_kms(crtc)); | 410 | mdp4_disable(get_kms(crtc)); |
| 411 | drm_crtc_vblank_put(crtc); | ||
| 410 | } | 412 | } |
| 411 | 413 | ||
| 412 | static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | 414 | static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b447c01ad89c..fcf95680413d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -52,7 +52,7 @@ module_param(reglog, bool, 0600); | |||
| 52 | #define reglog 0 | 52 | #define reglog 0 |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | static char *vram; | 55 | static char *vram = "16m"; |
| 56 | MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); | 56 | MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); |
| 57 | module_param(vram, charp, 0); | 57 | module_param(vram, charp, 0); |
| 58 | 58 | ||
| @@ -974,12 +974,11 @@ static int msm_pdev_probe(struct platform_device *pdev) | |||
| 974 | 974 | ||
| 975 | for (i = 0; i < ARRAY_SIZE(devnames); i++) { | 975 | for (i = 0; i < ARRAY_SIZE(devnames); i++) { |
| 976 | struct device *dev; | 976 | struct device *dev; |
| 977 | int ret; | ||
| 978 | 977 | ||
| 979 | dev = bus_find_device_by_name(&platform_bus_type, | 978 | dev = bus_find_device_by_name(&platform_bus_type, |
| 980 | NULL, devnames[i]); | 979 | NULL, devnames[i]); |
| 981 | if (!dev) { | 980 | if (!dev) { |
| 982 | dev_info(master, "still waiting for %s\n", devnames[i]); | 981 | dev_info(&pdev->dev, "still waiting for %s\n", devnames[i]); |
| 983 | return -EPROBE_DEFER; | 982 | return -EPROBE_DEFER; |
| 984 | } | 983 | } |
| 985 | 984 | ||
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 9c5221ce391a..ab5bfd2d0ebf 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
| @@ -143,7 +143,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, | |||
| 143 | ret = msm_gem_get_iova_locked(fbdev->bo, 0, &paddr); | 143 | ret = msm_gem_get_iova_locked(fbdev->bo, 0, &paddr); |
| 144 | if (ret) { | 144 | if (ret) { |
| 145 | dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret); | 145 | dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret); |
| 146 | goto fail; | 146 | goto fail_unlock; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | fbi = framebuffer_alloc(0, dev->dev); | 149 | fbi = framebuffer_alloc(0, dev->dev); |
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 099af483fdf0..7acdaa5688b7 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c | |||
| @@ -27,8 +27,8 @@ struct msm_iommu { | |||
| 27 | static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, | 27 | static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, |
| 28 | unsigned long iova, int flags, void *arg) | 28 | unsigned long iova, int flags, void *arg) |
| 29 | { | 29 | { |
| 30 | DBG("*** fault: iova=%08lx, flags=%d", iova, flags); | 30 | pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags); |
| 31 | return -ENOSYS; | 31 | return 0; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) | 34 | static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) |
diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c index 8701968a9743..30a2911878f8 100644 --- a/drivers/gpu/drm/nouveau/core/core/parent.c +++ b/drivers/gpu/drm/nouveau/core/core/parent.c | |||
| @@ -86,7 +86,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size) | |||
| 86 | sclass = nv_parent(parent)->sclass; | 86 | sclass = nv_parent(parent)->sclass; |
| 87 | while (sclass) { | 87 | while (sclass) { |
| 88 | if (++nr < size) | 88 | if (++nr < size) |
| 89 | lclass[nr] = sclass->oclass->handle; | 89 | lclass[nr] = sclass->oclass->handle & 0xffff; |
| 90 | sclass = sclass->sclass; | 90 | sclass = sclass->sclass; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| @@ -96,7 +96,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size) | |||
| 96 | if (engine && (oclass = engine->sclass)) { | 96 | if (engine && (oclass = engine->sclass)) { |
| 97 | while (oclass->ofuncs) { | 97 | while (oclass->ofuncs) { |
| 98 | if (++nr < size) | 98 | if (++nr < size) |
| 99 | lclass[nr] = oclass->handle; | 99 | lclass[nr] = oclass->handle & 0xffff; |
| 100 | oclass++; | 100 | oclass++; |
| 101 | } | 101 | } |
| 102 | } | 102 | } |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 0013ad0db9ef..f77b7135ee4c 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
| @@ -76,7 +76,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
| 76 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o \ | 76 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o \ |
| 77 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ | 77 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ |
| 78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ | 78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ |
| 79 | si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ | 79 | si_blit_shaders.o radeon_prime.o cik.o cik_blit_shaders.o \ |
| 80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ | 80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ |
| 81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ | 81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ |
| 82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ | 82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index b1e11f8434e2..ac14b67621d3 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -405,16 +405,13 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | |||
| 405 | u8 msg[DP_DPCD_SIZE]; | 405 | u8 msg[DP_DPCD_SIZE]; |
| 406 | int ret; | 406 | int ret; |
| 407 | 407 | ||
| 408 | char dpcd_hex_dump[DP_DPCD_SIZE * 3]; | ||
| 409 | |||
| 410 | ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, | 408 | ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, |
| 411 | DP_DPCD_SIZE); | 409 | DP_DPCD_SIZE); |
| 412 | if (ret > 0) { | 410 | if (ret > 0) { |
| 413 | memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); | 411 | memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); |
| 414 | 412 | ||
| 415 | hex_dump_to_buffer(dig_connector->dpcd, sizeof(dig_connector->dpcd), | 413 | DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), |
| 416 | 32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false); | 414 | dig_connector->dpcd); |
| 417 | DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump); | ||
| 418 | 415 | ||
| 419 | radeon_dp_probe_oui(radeon_connector); | 416 | radeon_dp_probe_oui(radeon_connector); |
| 420 | 417 | ||
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 022561e28707..d416bb2ff48d 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
| @@ -869,6 +869,9 @@ static int ci_set_thermal_temperature_range(struct radeon_device *rdev, | |||
| 869 | WREG32_SMC(CG_THERMAL_CTRL, tmp); | 869 | WREG32_SMC(CG_THERMAL_CTRL, tmp); |
| 870 | #endif | 870 | #endif |
| 871 | 871 | ||
| 872 | rdev->pm.dpm.thermal.min_temp = low_temp; | ||
| 873 | rdev->pm.dpm.thermal.max_temp = high_temp; | ||
| 874 | |||
| 872 | return 0; | 875 | return 0; |
| 873 | } | 876 | } |
| 874 | 877 | ||
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b625646bf3e2..fa9565957f9d 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -3483,7 +3483,7 @@ static void cik_gpu_init(struct radeon_device *rdev) | |||
| 3483 | u32 mc_shared_chmap, mc_arb_ramcfg; | 3483 | u32 mc_shared_chmap, mc_arb_ramcfg; |
| 3484 | u32 hdp_host_path_cntl; | 3484 | u32 hdp_host_path_cntl; |
| 3485 | u32 tmp; | 3485 | u32 tmp; |
| 3486 | int i, j, k; | 3486 | int i, j; |
| 3487 | 3487 | ||
| 3488 | switch (rdev->family) { | 3488 | switch (rdev->family) { |
| 3489 | case CHIP_BONAIRE: | 3489 | case CHIP_BONAIRE: |
| @@ -3544,6 +3544,7 @@ static void cik_gpu_init(struct radeon_device *rdev) | |||
| 3544 | (rdev->pdev->device == 0x130B) || | 3544 | (rdev->pdev->device == 0x130B) || |
| 3545 | (rdev->pdev->device == 0x130E) || | 3545 | (rdev->pdev->device == 0x130E) || |
| 3546 | (rdev->pdev->device == 0x1315) || | 3546 | (rdev->pdev->device == 0x1315) || |
| 3547 | (rdev->pdev->device == 0x1318) || | ||
| 3547 | (rdev->pdev->device == 0x131B)) { | 3548 | (rdev->pdev->device == 0x131B)) { |
| 3548 | rdev->config.cik.max_cu_per_sh = 4; | 3549 | rdev->config.cik.max_cu_per_sh = 4; |
| 3549 | rdev->config.cik.max_backends_per_se = 1; | 3550 | rdev->config.cik.max_backends_per_se = 1; |
| @@ -3672,12 +3673,11 @@ static void cik_gpu_init(struct radeon_device *rdev) | |||
| 3672 | rdev->config.cik.max_sh_per_se, | 3673 | rdev->config.cik.max_sh_per_se, |
| 3673 | rdev->config.cik.max_backends_per_se); | 3674 | rdev->config.cik.max_backends_per_se); |
| 3674 | 3675 | ||
| 3676 | rdev->config.cik.active_cus = 0; | ||
| 3675 | for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { | 3677 | for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { |
| 3676 | for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { | 3678 | for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { |
| 3677 | for (k = 0; k < rdev->config.cik.max_cu_per_sh; k++) { | 3679 | rdev->config.cik.active_cus += |
| 3678 | rdev->config.cik.active_cus += | 3680 | hweight32(cik_get_cu_active_bitmap(rdev, i, j)); |
| 3679 | hweight32(cik_get_cu_active_bitmap(rdev, i, j)); | ||
| 3680 | } | ||
| 3681 | } | 3681 | } |
| 3682 | } | 3682 | } |
| 3683 | 3683 | ||
| @@ -3801,7 +3801,7 @@ int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 3801 | radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | 3801 | radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); |
| 3802 | radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2)); | 3802 | radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2)); |
| 3803 | radeon_ring_write(ring, 0xDEADBEEF); | 3803 | radeon_ring_write(ring, 0xDEADBEEF); |
| 3804 | radeon_ring_unlock_commit(rdev, ring); | 3804 | radeon_ring_unlock_commit(rdev, ring, false); |
| 3805 | 3805 | ||
| 3806 | for (i = 0; i < rdev->usec_timeout; i++) { | 3806 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 3807 | tmp = RREG32(scratch); | 3807 | tmp = RREG32(scratch); |
| @@ -3920,6 +3920,17 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, | |||
| 3920 | radeon_ring_write(ring, 0); | 3920 | radeon_ring_write(ring, 0); |
| 3921 | } | 3921 | } |
| 3922 | 3922 | ||
| 3923 | /** | ||
| 3924 | * cik_semaphore_ring_emit - emit a semaphore on the CP ring | ||
| 3925 | * | ||
| 3926 | * @rdev: radeon_device pointer | ||
| 3927 | * @ring: radeon ring buffer object | ||
| 3928 | * @semaphore: radeon semaphore object | ||
| 3929 | * @emit_wait: Is this a sempahore wait? | ||
| 3930 | * | ||
| 3931 | * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP | ||
| 3932 | * from running ahead of semaphore waits. | ||
| 3933 | */ | ||
| 3923 | bool cik_semaphore_ring_emit(struct radeon_device *rdev, | 3934 | bool cik_semaphore_ring_emit(struct radeon_device *rdev, |
| 3924 | struct radeon_ring *ring, | 3935 | struct radeon_ring *ring, |
| 3925 | struct radeon_semaphore *semaphore, | 3936 | struct radeon_semaphore *semaphore, |
| @@ -3932,6 +3943,12 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 3932 | radeon_ring_write(ring, lower_32_bits(addr)); | 3943 | radeon_ring_write(ring, lower_32_bits(addr)); |
| 3933 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); | 3944 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); |
| 3934 | 3945 | ||
| 3946 | if (emit_wait && ring->idx == RADEON_RING_TYPE_GFX_INDEX) { | ||
| 3947 | /* Prevent the PFP from running ahead of the semaphore wait */ | ||
| 3948 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
| 3949 | radeon_ring_write(ring, 0x0); | ||
| 3950 | } | ||
| 3951 | |||
| 3935 | return true; | 3952 | return true; |
| 3936 | } | 3953 | } |
| 3937 | 3954 | ||
| @@ -4004,7 +4021,7 @@ int cik_copy_cpdma(struct radeon_device *rdev, | |||
| 4004 | return r; | 4021 | return r; |
| 4005 | } | 4022 | } |
| 4006 | 4023 | ||
| 4007 | radeon_ring_unlock_commit(rdev, ring); | 4024 | radeon_ring_unlock_commit(rdev, ring, false); |
| 4008 | radeon_semaphore_free(rdev, &sem, *fence); | 4025 | radeon_semaphore_free(rdev, &sem, *fence); |
| 4009 | 4026 | ||
| 4010 | return r; | 4027 | return r; |
| @@ -4103,7 +4120,7 @@ int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 4103 | ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2); | 4120 | ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2); |
| 4104 | ib.ptr[2] = 0xDEADBEEF; | 4121 | ib.ptr[2] = 0xDEADBEEF; |
| 4105 | ib.length_dw = 3; | 4122 | ib.length_dw = 3; |
| 4106 | r = radeon_ib_schedule(rdev, &ib, NULL); | 4123 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 4107 | if (r) { | 4124 | if (r) { |
| 4108 | radeon_scratch_free(rdev, scratch); | 4125 | radeon_scratch_free(rdev, scratch); |
| 4109 | radeon_ib_free(rdev, &ib); | 4126 | radeon_ib_free(rdev, &ib); |
| @@ -4324,7 +4341,7 @@ static int cik_cp_gfx_start(struct radeon_device *rdev) | |||
| 4324 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | 4341 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ |
| 4325 | radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ | 4342 | radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ |
| 4326 | 4343 | ||
| 4327 | radeon_ring_unlock_commit(rdev, ring); | 4344 | radeon_ring_unlock_commit(rdev, ring, false); |
| 4328 | 4345 | ||
| 4329 | return 0; | 4346 | return 0; |
| 4330 | } | 4347 | } |
| @@ -5732,20 +5749,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 5732 | WREG32(0x15D8, 0); | 5749 | WREG32(0x15D8, 0); |
| 5733 | WREG32(0x15DC, 0); | 5750 | WREG32(0x15DC, 0); |
| 5734 | 5751 | ||
| 5735 | /* empty context1-15 */ | 5752 | /* restore context1-15 */ |
| 5736 | /* FIXME start with 4G, once using 2 level pt switch to full | ||
| 5737 | * vm size space | ||
| 5738 | */ | ||
| 5739 | /* set vm size, must be a multiple of 4 */ | 5753 | /* set vm size, must be a multiple of 4 */ |
| 5740 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 5754 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
| 5741 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); | 5755 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); |
| 5742 | for (i = 1; i < 16; i++) { | 5756 | for (i = 1; i < 16; i++) { |
| 5743 | if (i < 8) | 5757 | if (i < 8) |
| 5744 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 5758 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| 5745 | rdev->gart.table_addr >> 12); | 5759 | rdev->vm_manager.saved_table_addr[i]); |
| 5746 | else | 5760 | else |
| 5747 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), | 5761 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), |
| 5748 | rdev->gart.table_addr >> 12); | 5762 | rdev->vm_manager.saved_table_addr[i]); |
| 5749 | } | 5763 | } |
| 5750 | 5764 | ||
| 5751 | /* enable context1-15 */ | 5765 | /* enable context1-15 */ |
| @@ -5810,6 +5824,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 5810 | */ | 5824 | */ |
| 5811 | static void cik_pcie_gart_disable(struct radeon_device *rdev) | 5825 | static void cik_pcie_gart_disable(struct radeon_device *rdev) |
| 5812 | { | 5826 | { |
| 5827 | unsigned i; | ||
| 5828 | |||
| 5829 | for (i = 1; i < 16; ++i) { | ||
| 5830 | uint32_t reg; | ||
| 5831 | if (i < 8) | ||
| 5832 | reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2); | ||
| 5833 | else | ||
| 5834 | reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2); | ||
| 5835 | rdev->vm_manager.saved_table_addr[i] = RREG32(reg); | ||
| 5836 | } | ||
| 5837 | |||
| 5813 | /* Disable all tables */ | 5838 | /* Disable all tables */ |
| 5814 | WREG32(VM_CONTEXT0_CNTL, 0); | 5839 | WREG32(VM_CONTEXT0_CNTL, 0); |
| 5815 | WREG32(VM_CONTEXT1_CNTL, 0); | 5840 | WREG32(VM_CONTEXT1_CNTL, 0); |
| @@ -5958,14 +5983,14 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 5958 | 5983 | ||
| 5959 | /* update SH_MEM_* regs */ | 5984 | /* update SH_MEM_* regs */ |
| 5960 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5985 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
| 5961 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 5986 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
| 5962 | WRITE_DATA_DST_SEL(0))); | 5987 | WRITE_DATA_DST_SEL(0))); |
| 5963 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); | 5988 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); |
| 5964 | radeon_ring_write(ring, 0); | 5989 | radeon_ring_write(ring, 0); |
| 5965 | radeon_ring_write(ring, VMID(vm->id)); | 5990 | radeon_ring_write(ring, VMID(vm->id)); |
| 5966 | 5991 | ||
| 5967 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); | 5992 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); |
| 5968 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 5993 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
| 5969 | WRITE_DATA_DST_SEL(0))); | 5994 | WRITE_DATA_DST_SEL(0))); |
| 5970 | radeon_ring_write(ring, SH_MEM_BASES >> 2); | 5995 | radeon_ring_write(ring, SH_MEM_BASES >> 2); |
| 5971 | radeon_ring_write(ring, 0); | 5996 | radeon_ring_write(ring, 0); |
| @@ -5976,7 +6001,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 5976 | radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */ | 6001 | radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */ |
| 5977 | 6002 | ||
| 5978 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 6003 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
| 5979 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 6004 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
| 5980 | WRITE_DATA_DST_SEL(0))); | 6005 | WRITE_DATA_DST_SEL(0))); |
| 5981 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); | 6006 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); |
| 5982 | radeon_ring_write(ring, 0); | 6007 | radeon_ring_write(ring, 0); |
| @@ -5987,7 +6012,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 5987 | 6012 | ||
| 5988 | /* bits 0-15 are the VM contexts0-15 */ | 6013 | /* bits 0-15 are the VM contexts0-15 */ |
| 5989 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 6014 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
| 5990 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 6015 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
| 5991 | WRITE_DATA_DST_SEL(0))); | 6016 | WRITE_DATA_DST_SEL(0))); |
| 5992 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 6017 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
| 5993 | radeon_ring_write(ring, 0); | 6018 | radeon_ring_write(ring, 0); |
| @@ -9538,6 +9563,9 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) | |||
| 9538 | int ret, i; | 9563 | int ret, i; |
| 9539 | u16 tmp16; | 9564 | u16 tmp16; |
| 9540 | 9565 | ||
| 9566 | if (pci_is_root_bus(rdev->pdev->bus)) | ||
| 9567 | return; | ||
| 9568 | |||
| 9541 | if (radeon_pcie_gen2 == 0) | 9569 | if (radeon_pcie_gen2 == 0) |
| 9542 | return; | 9570 | return; |
| 9543 | 9571 | ||
| @@ -9764,7 +9792,8 @@ static void cik_program_aspm(struct radeon_device *rdev) | |||
| 9764 | if (orig != data) | 9792 | if (orig != data) |
| 9765 | WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); | 9793 | WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); |
| 9766 | 9794 | ||
| 9767 | if (!disable_clkreq) { | 9795 | if (!disable_clkreq && |
| 9796 | !pci_is_root_bus(rdev->pdev->bus)) { | ||
| 9768 | struct pci_dev *root = rdev->pdev->bus->self; | 9797 | struct pci_dev *root = rdev->pdev->bus->self; |
| 9769 | u32 lnkcap; | 9798 | u32 lnkcap; |
| 9770 | 9799 | ||
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index bcf480510ac2..192278bc993c 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
| @@ -596,7 +596,7 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
| 596 | return r; | 596 | return r; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | radeon_ring_unlock_commit(rdev, ring); | 599 | radeon_ring_unlock_commit(rdev, ring, false); |
| 600 | radeon_semaphore_free(rdev, &sem, *fence); | 600 | radeon_semaphore_free(rdev, &sem, *fence); |
| 601 | 601 | ||
| 602 | return r; | 602 | return r; |
| @@ -638,7 +638,7 @@ int cik_sdma_ring_test(struct radeon_device *rdev, | |||
| 638 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr)); | 638 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr)); |
| 639 | radeon_ring_write(ring, 1); /* number of DWs to follow */ | 639 | radeon_ring_write(ring, 1); /* number of DWs to follow */ |
| 640 | radeon_ring_write(ring, 0xDEADBEEF); | 640 | radeon_ring_write(ring, 0xDEADBEEF); |
| 641 | radeon_ring_unlock_commit(rdev, ring); | 641 | radeon_ring_unlock_commit(rdev, ring, false); |
| 642 | 642 | ||
| 643 | for (i = 0; i < rdev->usec_timeout; i++) { | 643 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 644 | tmp = readl(ptr); | 644 | tmp = readl(ptr); |
| @@ -695,7 +695,7 @@ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 695 | ib.ptr[4] = 0xDEADBEEF; | 695 | ib.ptr[4] = 0xDEADBEEF; |
| 696 | ib.length_dw = 5; | 696 | ib.length_dw = 5; |
| 697 | 697 | ||
| 698 | r = radeon_ib_schedule(rdev, &ib, NULL); | 698 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 699 | if (r) { | 699 | if (r) { |
| 700 | radeon_ib_free(rdev, &ib); | 700 | radeon_ib_free(rdev, &ib); |
| 701 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 701 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4fedd14e670a..dbca60c7d097 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -2869,7 +2869,7 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
| 2869 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | 2869 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); |
| 2870 | radeon_ring_write(ring, 0); | 2870 | radeon_ring_write(ring, 0); |
| 2871 | radeon_ring_write(ring, 0); | 2871 | radeon_ring_write(ring, 0); |
| 2872 | radeon_ring_unlock_commit(rdev, ring); | 2872 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2873 | 2873 | ||
| 2874 | cp_me = 0xff; | 2874 | cp_me = 0xff; |
| 2875 | WREG32(CP_ME_CNTL, cp_me); | 2875 | WREG32(CP_ME_CNTL, cp_me); |
| @@ -2912,7 +2912,7 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
| 2912 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | 2912 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ |
| 2913 | radeon_ring_write(ring, 0x00000010); /* */ | 2913 | radeon_ring_write(ring, 0x00000010); /* */ |
| 2914 | 2914 | ||
| 2915 | radeon_ring_unlock_commit(rdev, ring); | 2915 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2916 | 2916 | ||
| 2917 | return 0; | 2917 | return 0; |
| 2918 | } | 2918 | } |
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index 478caefe0fef..afaba388c36d 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c | |||
| @@ -155,7 +155,7 @@ int evergreen_copy_dma(struct radeon_device *rdev, | |||
| 155 | return r; | 155 | return r; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | radeon_ring_unlock_commit(rdev, ring); | 158 | radeon_ring_unlock_commit(rdev, ring, false); |
| 159 | radeon_semaphore_free(rdev, &sem, *fence); | 159 | radeon_semaphore_free(rdev, &sem, *fence); |
| 160 | 160 | ||
| 161 | return r; | 161 | return r; |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 9ef8c38f2d66..8b58e11b64fa 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
| @@ -1438,14 +1438,14 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) | |||
| 1438 | return kv_enable_uvd_dpm(rdev, !gate); | 1438 | return kv_enable_uvd_dpm(rdev, !gate); |
| 1439 | } | 1439 | } |
| 1440 | 1440 | ||
| 1441 | static u8 kv_get_vce_boot_level(struct radeon_device *rdev) | 1441 | static u8 kv_get_vce_boot_level(struct radeon_device *rdev, u32 evclk) |
| 1442 | { | 1442 | { |
| 1443 | u8 i; | 1443 | u8 i; |
| 1444 | struct radeon_vce_clock_voltage_dependency_table *table = | 1444 | struct radeon_vce_clock_voltage_dependency_table *table = |
| 1445 | &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; | 1445 | &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; |
| 1446 | 1446 | ||
| 1447 | for (i = 0; i < table->count; i++) { | 1447 | for (i = 0; i < table->count; i++) { |
| 1448 | if (table->entries[i].evclk >= 0) /* XXX */ | 1448 | if (table->entries[i].evclk >= evclk) |
| 1449 | break; | 1449 | break; |
| 1450 | } | 1450 | } |
| 1451 | 1451 | ||
| @@ -1468,7 +1468,7 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, | |||
| 1468 | if (pi->caps_stable_p_state) | 1468 | if (pi->caps_stable_p_state) |
| 1469 | pi->vce_boot_level = table->count - 1; | 1469 | pi->vce_boot_level = table->count - 1; |
| 1470 | else | 1470 | else |
| 1471 | pi->vce_boot_level = kv_get_vce_boot_level(rdev); | 1471 | pi->vce_boot_level = kv_get_vce_boot_level(rdev, radeon_new_state->evclk); |
| 1472 | 1472 | ||
| 1473 | ret = kv_copy_bytes_to_smc(rdev, | 1473 | ret = kv_copy_bytes_to_smc(rdev, |
| 1474 | pi->dpm_table_start + | 1474 | pi->dpm_table_start + |
| @@ -2726,7 +2726,10 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
| 2726 | pi->caps_sclk_ds = true; | 2726 | pi->caps_sclk_ds = true; |
| 2727 | pi->enable_auto_thermal_throttling = true; | 2727 | pi->enable_auto_thermal_throttling = true; |
| 2728 | pi->disable_nb_ps3_in_battery = false; | 2728 | pi->disable_nb_ps3_in_battery = false; |
| 2729 | pi->bapm_enable = true; | 2729 | if (radeon_bapm == 0) |
| 2730 | pi->bapm_enable = false; | ||
| 2731 | else | ||
| 2732 | pi->bapm_enable = true; | ||
| 2730 | pi->voltage_drop_t = 0; | 2733 | pi->voltage_drop_t = 0; |
| 2731 | pi->caps_sclk_throttle_low_notification = false; | 2734 | pi->caps_sclk_throttle_low_notification = false; |
| 2732 | pi->caps_fps = false; /* true? */ | 2735 | pi->caps_fps = false; /* true? */ |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 327b85f7fd0d..3faee58946dd 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -1271,7 +1271,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1271 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); | 1271 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); |
| 1272 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); | 1272 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); |
| 1273 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 1273 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| 1274 | rdev->gart.table_addr >> 12); | 1274 | rdev->vm_manager.saved_table_addr[i]); |
| 1275 | } | 1275 | } |
| 1276 | 1276 | ||
| 1277 | /* enable context1-7 */ | 1277 | /* enable context1-7 */ |
| @@ -1303,6 +1303,13 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1303 | 1303 | ||
| 1304 | static void cayman_pcie_gart_disable(struct radeon_device *rdev) | 1304 | static void cayman_pcie_gart_disable(struct radeon_device *rdev) |
| 1305 | { | 1305 | { |
| 1306 | unsigned i; | ||
| 1307 | |||
| 1308 | for (i = 1; i < 8; ++i) { | ||
| 1309 | rdev->vm_manager.saved_table_addr[i] = RREG32( | ||
| 1310 | VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2)); | ||
| 1311 | } | ||
| 1312 | |||
| 1306 | /* Disable all tables */ | 1313 | /* Disable all tables */ |
| 1307 | WREG32(VM_CONTEXT0_CNTL, 0); | 1314 | WREG32(VM_CONTEXT0_CNTL, 0); |
| 1308 | WREG32(VM_CONTEXT1_CNTL, 0); | 1315 | WREG32(VM_CONTEXT1_CNTL, 0); |
| @@ -1505,7 +1512,7 @@ static int cayman_cp_start(struct radeon_device *rdev) | |||
| 1505 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | 1512 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); |
| 1506 | radeon_ring_write(ring, 0); | 1513 | radeon_ring_write(ring, 0); |
| 1507 | radeon_ring_write(ring, 0); | 1514 | radeon_ring_write(ring, 0); |
| 1508 | radeon_ring_unlock_commit(rdev, ring); | 1515 | radeon_ring_unlock_commit(rdev, ring, false); |
| 1509 | 1516 | ||
| 1510 | cayman_cp_enable(rdev, true); | 1517 | cayman_cp_enable(rdev, true); |
| 1511 | 1518 | ||
| @@ -1547,7 +1554,7 @@ static int cayman_cp_start(struct radeon_device *rdev) | |||
| 1547 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | 1554 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ |
| 1548 | radeon_ring_write(ring, 0x00000010); /* */ | 1555 | radeon_ring_write(ring, 0x00000010); /* */ |
| 1549 | 1556 | ||
| 1550 | radeon_ring_unlock_commit(rdev, ring); | 1557 | radeon_ring_unlock_commit(rdev, ring, false); |
| 1551 | 1558 | ||
| 1552 | /* XXX init other rings */ | 1559 | /* XXX init other rings */ |
| 1553 | 1560 | ||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 04b5940b8923..4c5ec44ff328 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -925,7 +925,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
| 925 | if (fence) { | 925 | if (fence) { |
| 926 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); | 926 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
| 927 | } | 927 | } |
| 928 | radeon_ring_unlock_commit(rdev, ring); | 928 | radeon_ring_unlock_commit(rdev, ring, false); |
| 929 | return r; | 929 | return r; |
| 930 | } | 930 | } |
| 931 | 931 | ||
| @@ -958,7 +958,7 @@ void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 958 | RADEON_ISYNC_ANY3D_IDLE2D | | 958 | RADEON_ISYNC_ANY3D_IDLE2D | |
| 959 | RADEON_ISYNC_WAIT_IDLEGUI | | 959 | RADEON_ISYNC_WAIT_IDLEGUI | |
| 960 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); | 960 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
| 961 | radeon_ring_unlock_commit(rdev, ring); | 961 | radeon_ring_unlock_commit(rdev, ring, false); |
| 962 | } | 962 | } |
| 963 | 963 | ||
| 964 | 964 | ||
| @@ -3638,7 +3638,7 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 3638 | } | 3638 | } |
| 3639 | radeon_ring_write(ring, PACKET0(scratch, 0)); | 3639 | radeon_ring_write(ring, PACKET0(scratch, 0)); |
| 3640 | radeon_ring_write(ring, 0xDEADBEEF); | 3640 | radeon_ring_write(ring, 0xDEADBEEF); |
| 3641 | radeon_ring_unlock_commit(rdev, ring); | 3641 | radeon_ring_unlock_commit(rdev, ring, false); |
| 3642 | for (i = 0; i < rdev->usec_timeout; i++) { | 3642 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 3643 | tmp = RREG32(scratch); | 3643 | tmp = RREG32(scratch); |
| 3644 | if (tmp == 0xDEADBEEF) { | 3644 | if (tmp == 0xDEADBEEF) { |
| @@ -3700,7 +3700,7 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 3700 | ib.ptr[6] = PACKET2(0); | 3700 | ib.ptr[6] = PACKET2(0); |
| 3701 | ib.ptr[7] = PACKET2(0); | 3701 | ib.ptr[7] = PACKET2(0); |
| 3702 | ib.length_dw = 8; | 3702 | ib.length_dw = 8; |
| 3703 | r = radeon_ib_schedule(rdev, &ib, NULL); | 3703 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 3704 | if (r) { | 3704 | if (r) { |
| 3705 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 3705 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
| 3706 | goto free_ib; | 3706 | goto free_ib; |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 58f0473aa73f..67780374a652 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
| @@ -121,7 +121,7 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
| 121 | if (fence) { | 121 | if (fence) { |
| 122 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); | 122 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
| 123 | } | 123 | } |
| 124 | radeon_ring_unlock_commit(rdev, ring); | 124 | radeon_ring_unlock_commit(rdev, ring, false); |
| 125 | return r; | 125 | return r; |
| 126 | } | 126 | } |
| 127 | 127 | ||
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 75b30338c226..1bc4704034ce 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -295,7 +295,7 @@ void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 295 | radeon_ring_write(ring, | 295 | radeon_ring_write(ring, |
| 296 | R300_GEOMETRY_ROUND_NEAREST | | 296 | R300_GEOMETRY_ROUND_NEAREST | |
| 297 | R300_COLOR_ROUND_NEAREST); | 297 | R300_COLOR_ROUND_NEAREST); |
| 298 | radeon_ring_unlock_commit(rdev, ring); | 298 | radeon_ring_unlock_commit(rdev, ring, false); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | static void r300_errata(struct radeon_device *rdev) | 301 | static void r300_errata(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 802b19220a21..2828605aef3f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
| @@ -219,7 +219,7 @@ static void r420_cp_errata_init(struct radeon_device *rdev) | |||
| 219 | radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1)); | 219 | radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1)); |
| 220 | radeon_ring_write(ring, rdev->config.r300.resync_scratch); | 220 | radeon_ring_write(ring, rdev->config.r300.resync_scratch); |
| 221 | radeon_ring_write(ring, 0xDEADBEEF); | 221 | radeon_ring_write(ring, 0xDEADBEEF); |
| 222 | radeon_ring_unlock_commit(rdev, ring); | 222 | radeon_ring_unlock_commit(rdev, ring, false); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | static void r420_cp_errata_fini(struct radeon_device *rdev) | 225 | static void r420_cp_errata_fini(struct radeon_device *rdev) |
| @@ -232,7 +232,7 @@ static void r420_cp_errata_fini(struct radeon_device *rdev) | |||
| 232 | radeon_ring_lock(rdev, ring, 8); | 232 | radeon_ring_lock(rdev, ring, 8); |
| 233 | radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); | 233 | radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); |
| 234 | radeon_ring_write(ring, R300_RB3D_DC_FINISH); | 234 | radeon_ring_write(ring, R300_RB3D_DC_FINISH); |
| 235 | radeon_ring_unlock_commit(rdev, ring); | 235 | radeon_ring_unlock_commit(rdev, ring, false); |
| 236 | radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); | 236 | radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); |
| 237 | } | 237 | } |
| 238 | 238 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c70a504d96af..3cfb50056f7a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1812,7 +1812,6 @@ static void r600_gpu_init(struct radeon_device *rdev) | |||
| 1812 | { | 1812 | { |
| 1813 | u32 tiling_config; | 1813 | u32 tiling_config; |
| 1814 | u32 ramcfg; | 1814 | u32 ramcfg; |
| 1815 | u32 cc_rb_backend_disable; | ||
| 1816 | u32 cc_gc_shader_pipe_config; | 1815 | u32 cc_gc_shader_pipe_config; |
| 1817 | u32 tmp; | 1816 | u32 tmp; |
| 1818 | int i, j; | 1817 | int i, j; |
| @@ -1939,29 +1938,20 @@ static void r600_gpu_init(struct radeon_device *rdev) | |||
| 1939 | } | 1938 | } |
| 1940 | tiling_config |= BANK_SWAPS(1); | 1939 | tiling_config |= BANK_SWAPS(1); |
| 1941 | 1940 | ||
| 1942 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; | ||
| 1943 | tmp = R6XX_MAX_BACKENDS - | ||
| 1944 | r600_count_pipe_bits((cc_rb_backend_disable >> 16) & R6XX_MAX_BACKENDS_MASK); | ||
| 1945 | if (tmp < rdev->config.r600.max_backends) { | ||
| 1946 | rdev->config.r600.max_backends = tmp; | ||
| 1947 | } | ||
| 1948 | |||
| 1949 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0x00ffff00; | 1941 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0x00ffff00; |
| 1950 | tmp = R6XX_MAX_PIPES - | ||
| 1951 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R6XX_MAX_PIPES_MASK); | ||
| 1952 | if (tmp < rdev->config.r600.max_pipes) { | ||
| 1953 | rdev->config.r600.max_pipes = tmp; | ||
| 1954 | } | ||
| 1955 | tmp = R6XX_MAX_SIMDS - | ||
| 1956 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK); | ||
| 1957 | if (tmp < rdev->config.r600.max_simds) { | ||
| 1958 | rdev->config.r600.max_simds = tmp; | ||
| 1959 | } | ||
| 1960 | tmp = rdev->config.r600.max_simds - | 1942 | tmp = rdev->config.r600.max_simds - |
| 1961 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK); | 1943 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK); |
| 1962 | rdev->config.r600.active_simds = tmp; | 1944 | rdev->config.r600.active_simds = tmp; |
| 1963 | 1945 | ||
| 1964 | disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R6XX_MAX_BACKENDS_MASK; | 1946 | disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R6XX_MAX_BACKENDS_MASK; |
| 1947 | tmp = 0; | ||
| 1948 | for (i = 0; i < rdev->config.r600.max_backends; i++) | ||
| 1949 | tmp |= (1 << i); | ||
| 1950 | /* if all the backends are disabled, fix it up here */ | ||
| 1951 | if ((disabled_rb_mask & tmp) == tmp) { | ||
| 1952 | for (i = 0; i < rdev->config.r600.max_backends; i++) | ||
| 1953 | disabled_rb_mask &= ~(1 << i); | ||
| 1954 | } | ||
| 1965 | tmp = (tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; | 1955 | tmp = (tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; |
| 1966 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.r600.max_backends, | 1956 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.r600.max_backends, |
| 1967 | R6XX_MAX_BACKENDS, disabled_rb_mask); | 1957 | R6XX_MAX_BACKENDS, disabled_rb_mask); |
| @@ -2547,7 +2537,7 @@ int r600_cp_start(struct radeon_device *rdev) | |||
| 2547 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | 2537 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); |
| 2548 | radeon_ring_write(ring, 0); | 2538 | radeon_ring_write(ring, 0); |
| 2549 | radeon_ring_write(ring, 0); | 2539 | radeon_ring_write(ring, 0); |
| 2550 | radeon_ring_unlock_commit(rdev, ring); | 2540 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2551 | 2541 | ||
| 2552 | cp_me = 0xff; | 2542 | cp_me = 0xff; |
| 2553 | WREG32(R_0086D8_CP_ME_CNTL, cp_me); | 2543 | WREG32(R_0086D8_CP_ME_CNTL, cp_me); |
| @@ -2683,7 +2673,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 2683 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2673 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
| 2684 | radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 2674 | radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
| 2685 | radeon_ring_write(ring, 0xDEADBEEF); | 2675 | radeon_ring_write(ring, 0xDEADBEEF); |
| 2686 | radeon_ring_unlock_commit(rdev, ring); | 2676 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2687 | for (i = 0; i < rdev->usec_timeout; i++) { | 2677 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 2688 | tmp = RREG32(scratch); | 2678 | tmp = RREG32(scratch); |
| 2689 | if (tmp == 0xDEADBEEF) | 2679 | if (tmp == 0xDEADBEEF) |
| @@ -2753,6 +2743,17 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
| 2753 | } | 2743 | } |
| 2754 | } | 2744 | } |
| 2755 | 2745 | ||
| 2746 | /** | ||
| 2747 | * r600_semaphore_ring_emit - emit a semaphore on the CP ring | ||
| 2748 | * | ||
| 2749 | * @rdev: radeon_device pointer | ||
| 2750 | * @ring: radeon ring buffer object | ||
| 2751 | * @semaphore: radeon semaphore object | ||
| 2752 | * @emit_wait: Is this a sempahore wait? | ||
| 2753 | * | ||
| 2754 | * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP | ||
| 2755 | * from running ahead of semaphore waits. | ||
| 2756 | */ | ||
| 2756 | bool r600_semaphore_ring_emit(struct radeon_device *rdev, | 2757 | bool r600_semaphore_ring_emit(struct radeon_device *rdev, |
| 2757 | struct radeon_ring *ring, | 2758 | struct radeon_ring *ring, |
| 2758 | struct radeon_semaphore *semaphore, | 2759 | struct radeon_semaphore *semaphore, |
| @@ -2768,6 +2769,13 @@ bool r600_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 2768 | radeon_ring_write(ring, lower_32_bits(addr)); | 2769 | radeon_ring_write(ring, lower_32_bits(addr)); |
| 2769 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); | 2770 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); |
| 2770 | 2771 | ||
| 2772 | /* PFP_SYNC_ME packet only exists on 7xx+, only enable it on eg+ */ | ||
| 2773 | if (emit_wait && (rdev->family >= CHIP_CEDAR)) { | ||
| 2774 | /* Prevent the PFP from running ahead of the semaphore wait */ | ||
| 2775 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
| 2776 | radeon_ring_write(ring, 0x0); | ||
| 2777 | } | ||
| 2778 | |||
| 2771 | return true; | 2779 | return true; |
| 2772 | } | 2780 | } |
| 2773 | 2781 | ||
| @@ -2845,7 +2853,7 @@ int r600_copy_cpdma(struct radeon_device *rdev, | |||
| 2845 | return r; | 2853 | return r; |
| 2846 | } | 2854 | } |
| 2847 | 2855 | ||
| 2848 | radeon_ring_unlock_commit(rdev, ring); | 2856 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2849 | radeon_semaphore_free(rdev, &sem, *fence); | 2857 | radeon_semaphore_free(rdev, &sem, *fence); |
| 2850 | 2858 | ||
| 2851 | return r; | 2859 | return r; |
| @@ -3165,7 +3173,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 3165 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 3173 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
| 3166 | ib.ptr[2] = 0xDEADBEEF; | 3174 | ib.ptr[2] = 0xDEADBEEF; |
| 3167 | ib.length_dw = 3; | 3175 | ib.length_dw = 3; |
| 3168 | r = radeon_ib_schedule(rdev, &ib, NULL); | 3176 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 3169 | if (r) { | 3177 | if (r) { |
| 3170 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 3178 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
| 3171 | goto free_ib; | 3179 | goto free_ib; |
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index 4969cef44a19..51fd98553eaf 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
| @@ -261,7 +261,7 @@ int r600_dma_ring_test(struct radeon_device *rdev, | |||
| 261 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); | 261 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); |
| 262 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff); | 262 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff); |
| 263 | radeon_ring_write(ring, 0xDEADBEEF); | 263 | radeon_ring_write(ring, 0xDEADBEEF); |
| 264 | radeon_ring_unlock_commit(rdev, ring); | 264 | radeon_ring_unlock_commit(rdev, ring, false); |
| 265 | 265 | ||
| 266 | for (i = 0; i < rdev->usec_timeout; i++) { | 266 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 267 | tmp = readl(ptr); | 267 | tmp = readl(ptr); |
| @@ -368,7 +368,7 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 368 | ib.ptr[3] = 0xDEADBEEF; | 368 | ib.ptr[3] = 0xDEADBEEF; |
| 369 | ib.length_dw = 4; | 369 | ib.length_dw = 4; |
| 370 | 370 | ||
| 371 | r = radeon_ib_schedule(rdev, &ib, NULL); | 371 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 372 | if (r) { | 372 | if (r) { |
| 373 | radeon_ib_free(rdev, &ib); | 373 | radeon_ib_free(rdev, &ib); |
| 374 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 374 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
| @@ -493,7 +493,7 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
| 493 | return r; | 493 | return r; |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | radeon_ring_unlock_commit(rdev, ring); | 496 | radeon_ring_unlock_commit(rdev, ring, false); |
| 497 | radeon_semaphore_free(rdev, &sem, *fence); | 497 | radeon_semaphore_free(rdev, &sem, *fence); |
| 498 | 498 | ||
| 499 | return r; | 499 | return r; |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index f94e7a9afe75..0c4a7d8d93e0 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -1597,6 +1597,7 @@ | |||
| 1597 | */ | 1597 | */ |
| 1598 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) | 1598 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) |
| 1599 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) | 1599 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) |
| 1600 | #define PACKET3_PFP_SYNC_ME 0x42 /* r7xx+ only */ | ||
| 1600 | #define PACKET3_SURFACE_SYNC 0x43 | 1601 | #define PACKET3_SURFACE_SYNC 0x43 |
| 1601 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 1602 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
| 1602 | # define PACKET3_FULL_CACHE_ENA (1 << 20) /* r7xx+ only */ | 1603 | # define PACKET3_FULL_CACHE_ENA (1 << 20) /* r7xx+ only */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9e1732eb402c..5f05b4c84338 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -105,6 +105,7 @@ extern int radeon_vm_size; | |||
| 105 | extern int radeon_vm_block_size; | 105 | extern int radeon_vm_block_size; |
| 106 | extern int radeon_deep_color; | 106 | extern int radeon_deep_color; |
| 107 | extern int radeon_use_pflipirq; | 107 | extern int radeon_use_pflipirq; |
| 108 | extern int radeon_bapm; | ||
| 108 | 109 | ||
| 109 | /* | 110 | /* |
| 110 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 111 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
| @@ -914,6 +915,8 @@ struct radeon_vm_manager { | |||
| 914 | u64 vram_base_offset; | 915 | u64 vram_base_offset; |
| 915 | /* is vm enabled? */ | 916 | /* is vm enabled? */ |
| 916 | bool enabled; | 917 | bool enabled; |
| 918 | /* for hw to save the PD addr on suspend/resume */ | ||
| 919 | uint32_t saved_table_addr[RADEON_NUM_VM]; | ||
| 917 | }; | 920 | }; |
| 918 | 921 | ||
| 919 | /* | 922 | /* |
| @@ -967,7 +970,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
| 967 | unsigned size); | 970 | unsigned size); |
| 968 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); | 971 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); |
| 969 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | 972 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, |
| 970 | struct radeon_ib *const_ib); | 973 | struct radeon_ib *const_ib, bool hdp_flush); |
| 971 | int radeon_ib_pool_init(struct radeon_device *rdev); | 974 | int radeon_ib_pool_init(struct radeon_device *rdev); |
| 972 | void radeon_ib_pool_fini(struct radeon_device *rdev); | 975 | void radeon_ib_pool_fini(struct radeon_device *rdev); |
| 973 | int radeon_ib_ring_tests(struct radeon_device *rdev); | 976 | int radeon_ib_ring_tests(struct radeon_device *rdev); |
| @@ -977,8 +980,10 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, | |||
| 977 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); | 980 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); |
| 978 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 981 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
| 979 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 982 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
| 980 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); | 983 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp, |
| 981 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); | 984 | bool hdp_flush); |
| 985 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp, | ||
| 986 | bool hdp_flush); | ||
| 982 | void radeon_ring_undo(struct radeon_ring *ring); | 987 | void radeon_ring_undo(struct radeon_ring *ring); |
| 983 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); | 988 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); |
| 984 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 989 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 92b2d8dd4735..e74c7e387dde 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -447,6 +447,13 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 447 | } | 447 | } |
| 448 | } | 448 | } |
| 449 | 449 | ||
| 450 | /* Fujitsu D3003-S2 board lists DVI-I as DVI-I and VGA */ | ||
| 451 | if ((dev->pdev->device == 0x9805) && | ||
| 452 | (dev->pdev->subsystem_vendor == 0x1734) && | ||
| 453 | (dev->pdev->subsystem_device == 0x11bd)) { | ||
| 454 | if (*connector_type == DRM_MODE_CONNECTOR_VGA) | ||
| 455 | return false; | ||
| 456 | } | ||
| 450 | 457 | ||
| 451 | return true; | 458 | return true; |
| 452 | } | 459 | } |
| @@ -2281,19 +2288,31 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r | |||
| 2281 | (controller->ucFanParameters & | 2288 | (controller->ucFanParameters & |
| 2282 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 2289 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
| 2283 | rdev->pm.int_thermal_type = THERMAL_TYPE_KV; | 2290 | rdev->pm.int_thermal_type = THERMAL_TYPE_KV; |
| 2284 | } else if ((controller->ucType == | 2291 | } else if (controller->ucType == |
| 2285 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | 2292 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) { |
| 2286 | (controller->ucType == | 2293 | DRM_INFO("External GPIO thermal controller %s fan control\n", |
| 2287 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || | 2294 | (controller->ucFanParameters & |
| 2288 | (controller->ucType == | 2295 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
| 2289 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { | 2296 | rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO; |
| 2290 | DRM_INFO("Special thermal controller config\n"); | 2297 | } else if (controller->ucType == |
| 2298 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) { | ||
| 2299 | DRM_INFO("ADT7473 with internal thermal controller %s fan control\n", | ||
| 2300 | (controller->ucFanParameters & | ||
| 2301 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2302 | rdev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL; | ||
| 2303 | } else if (controller->ucType == | ||
| 2304 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) { | ||
| 2305 | DRM_INFO("EMC2103 with internal thermal controller %s fan control\n", | ||
| 2306 | (controller->ucFanParameters & | ||
| 2307 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2308 | rdev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL; | ||
| 2291 | } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) { | 2309 | } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) { |
| 2292 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | 2310 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", |
| 2293 | pp_lib_thermal_controller_names[controller->ucType], | 2311 | pp_lib_thermal_controller_names[controller->ucType], |
| 2294 | controller->ucI2cAddress >> 1, | 2312 | controller->ucI2cAddress >> 1, |
| 2295 | (controller->ucFanParameters & | 2313 | (controller->ucFanParameters & |
| 2296 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 2314 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
| 2315 | rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL; | ||
| 2297 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | 2316 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); |
| 2298 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | 2317 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
| 2299 | if (rdev->pm.i2c_bus) { | 2318 | if (rdev->pm.i2c_bus) { |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ee712c199b25..83f382e8e40e 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -132,7 +132,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
| 132 | * the buffers used for read only, which doubles the range | 132 | * the buffers used for read only, which doubles the range |
| 133 | * to 0 to 31. 32 is reserved for the kernel driver. | 133 | * to 0 to 31. 32 is reserved for the kernel driver. |
| 134 | */ | 134 | */ |
| 135 | priority = (r->flags & 0xf) * 2 + !!r->write_domain; | 135 | priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2 |
| 136 | + !!r->write_domain; | ||
| 136 | 137 | ||
| 137 | /* the first reloc of an UVD job is the msg and that must be in | 138 | /* the first reloc of an UVD job is the msg and that must be in |
| 138 | VRAM, also but everything into VRAM on AGP cards to avoid | 139 | VRAM, also but everything into VRAM on AGP cards to avoid |
| @@ -450,7 +451,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
| 450 | radeon_vce_note_usage(rdev); | 451 | radeon_vce_note_usage(rdev); |
| 451 | 452 | ||
| 452 | radeon_cs_sync_rings(parser); | 453 | radeon_cs_sync_rings(parser); |
| 453 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); | 454 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
| 454 | if (r) { | 455 | if (r) { |
| 455 | DRM_ERROR("Failed to schedule IB !\n"); | 456 | DRM_ERROR("Failed to schedule IB !\n"); |
| 456 | } | 457 | } |
| @@ -541,9 +542,9 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 541 | 542 | ||
| 542 | if ((rdev->family >= CHIP_TAHITI) && | 543 | if ((rdev->family >= CHIP_TAHITI) && |
| 543 | (parser->chunk_const_ib_idx != -1)) { | 544 | (parser->chunk_const_ib_idx != -1)) { |
| 544 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib); | 545 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true); |
| 545 | } else { | 546 | } else { |
| 546 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); | 547 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
| 547 | } | 548 | } |
| 548 | 549 | ||
| 549 | out: | 550 | out: |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c8ea050c8fa4..6a219bcee66d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1680,8 +1680,8 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
| 1680 | radeon_save_bios_scratch_regs(rdev); | 1680 | radeon_save_bios_scratch_regs(rdev); |
| 1681 | /* block TTM */ | 1681 | /* block TTM */ |
| 1682 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 1682 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
| 1683 | radeon_pm_suspend(rdev); | ||
| 1684 | radeon_suspend(rdev); | 1683 | radeon_suspend(rdev); |
| 1684 | radeon_hpd_fini(rdev); | ||
| 1685 | 1685 | ||
| 1686 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1686 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
| 1687 | ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i], | 1687 | ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i], |
| @@ -1726,9 +1726,39 @@ retry: | |||
| 1726 | } | 1726 | } |
| 1727 | } | 1727 | } |
| 1728 | 1728 | ||
| 1729 | radeon_pm_resume(rdev); | 1729 | if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { |
| 1730 | /* do dpm late init */ | ||
| 1731 | r = radeon_pm_late_init(rdev); | ||
| 1732 | if (r) { | ||
| 1733 | rdev->pm.dpm_enabled = false; | ||
| 1734 | DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); | ||
| 1735 | } | ||
| 1736 | } else { | ||
| 1737 | /* resume old pm late */ | ||
| 1738 | radeon_pm_resume(rdev); | ||
| 1739 | } | ||
| 1740 | |||
| 1741 | /* init dig PHYs, disp eng pll */ | ||
| 1742 | if (rdev->is_atom_bios) { | ||
| 1743 | radeon_atom_encoder_init(rdev); | ||
| 1744 | radeon_atom_disp_eng_pll_init(rdev); | ||
| 1745 | /* turn on the BL */ | ||
| 1746 | if (rdev->mode_info.bl_encoder) { | ||
| 1747 | u8 bl_level = radeon_get_backlight_level(rdev, | ||
| 1748 | rdev->mode_info.bl_encoder); | ||
| 1749 | radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder, | ||
| 1750 | bl_level); | ||
| 1751 | } | ||
| 1752 | } | ||
| 1753 | /* reset hpd state */ | ||
| 1754 | radeon_hpd_init(rdev); | ||
| 1755 | |||
| 1730 | drm_helper_resume_force_mode(rdev->ddev); | 1756 | drm_helper_resume_force_mode(rdev->ddev); |
| 1731 | 1757 | ||
| 1758 | /* set the power state here in case we are a PX system or headless */ | ||
| 1759 | if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) | ||
| 1760 | radeon_pm_compute_clocks(rdev); | ||
| 1761 | |||
| 1732 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 1762 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
| 1733 | if (r) { | 1763 | if (r) { |
| 1734 | /* bad news, how to tell it to userspace ? */ | 1764 | /* bad news, how to tell it to userspace ? */ |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 092d067f93e1..8df888908833 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -180,6 +180,7 @@ int radeon_vm_size = 8; | |||
| 180 | int radeon_vm_block_size = -1; | 180 | int radeon_vm_block_size = -1; |
| 181 | int radeon_deep_color = 0; | 181 | int radeon_deep_color = 0; |
| 182 | int radeon_use_pflipirq = 2; | 182 | int radeon_use_pflipirq = 2; |
| 183 | int radeon_bapm = -1; | ||
| 183 | 184 | ||
| 184 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 185 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
| 185 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 186 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
| @@ -259,6 +260,9 @@ module_param_named(deep_color, radeon_deep_color, int, 0444); | |||
| 259 | MODULE_PARM_DESC(use_pflipirq, "Pflip irqs for pageflip completion (0 = disable, 1 = as fallback, 2 = exclusive (default))"); | 260 | MODULE_PARM_DESC(use_pflipirq, "Pflip irqs for pageflip completion (0 = disable, 1 = as fallback, 2 = exclusive (default))"); |
| 260 | module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444); | 261 | module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444); |
| 261 | 262 | ||
| 263 | MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); | ||
| 264 | module_param_named(bapm, radeon_bapm, int, 0444); | ||
| 265 | |||
| 262 | static struct pci_device_id pciidlist[] = { | 266 | static struct pci_device_id pciidlist[] = { |
| 263 | radeon_PCI_IDS | 267 | radeon_PCI_IDS |
| 264 | }; | 268 | }; |
diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 65b0c213488d..5bf2c0a05827 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c | |||
| @@ -107,6 +107,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 107 | * @rdev: radeon_device pointer | 107 | * @rdev: radeon_device pointer |
| 108 | * @ib: IB object to schedule | 108 | * @ib: IB object to schedule |
| 109 | * @const_ib: Const IB to schedule (SI only) | 109 | * @const_ib: Const IB to schedule (SI only) |
| 110 | * @hdp_flush: Whether or not to perform an HDP cache flush | ||
| 110 | * | 111 | * |
| 111 | * Schedule an IB on the associated ring (all asics). | 112 | * Schedule an IB on the associated ring (all asics). |
| 112 | * Returns 0 on success, error on failure. | 113 | * Returns 0 on success, error on failure. |
| @@ -122,7 +123,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 122 | * to SI there was just a DE IB. | 123 | * to SI there was just a DE IB. |
| 123 | */ | 124 | */ |
| 124 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | 125 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, |
| 125 | struct radeon_ib *const_ib) | 126 | struct radeon_ib *const_ib, bool hdp_flush) |
| 126 | { | 127 | { |
| 127 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 128 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
| 128 | int r = 0; | 129 | int r = 0; |
| @@ -176,7 +177,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
| 176 | if (ib->vm) | 177 | if (ib->vm) |
| 177 | radeon_vm_fence(rdev, ib->vm, ib->fence); | 178 | radeon_vm_fence(rdev, ib->vm, ib->fence); |
| 178 | 179 | ||
| 179 | radeon_ring_unlock_commit(rdev, ring); | 180 | radeon_ring_unlock_commit(rdev, ring, hdp_flush); |
| 180 | return 0; | 181 | return 0; |
| 181 | } | 182 | } |
| 182 | 183 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 23314be49480..164898b0010c 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -460,10 +460,6 @@ static ssize_t radeon_get_dpm_state(struct device *dev, | |||
| 460 | struct radeon_device *rdev = ddev->dev_private; | 460 | struct radeon_device *rdev = ddev->dev_private; |
| 461 | enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; | 461 | enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; |
| 462 | 462 | ||
| 463 | if ((rdev->flags & RADEON_IS_PX) && | ||
| 464 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
| 465 | return snprintf(buf, PAGE_SIZE, "off\n"); | ||
| 466 | |||
| 467 | return snprintf(buf, PAGE_SIZE, "%s\n", | 463 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 468 | (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : | 464 | (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : |
| 469 | (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); | 465 | (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); |
| @@ -477,11 +473,6 @@ static ssize_t radeon_set_dpm_state(struct device *dev, | |||
| 477 | struct drm_device *ddev = dev_get_drvdata(dev); | 473 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 478 | struct radeon_device *rdev = ddev->dev_private; | 474 | struct radeon_device *rdev = ddev->dev_private; |
| 479 | 475 | ||
| 480 | /* Can't set dpm state when the card is off */ | ||
| 481 | if ((rdev->flags & RADEON_IS_PX) && | ||
| 482 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 485 | mutex_lock(&rdev->pm.mutex); | 476 | mutex_lock(&rdev->pm.mutex); |
| 486 | if (strncmp("battery", buf, strlen("battery")) == 0) | 477 | if (strncmp("battery", buf, strlen("battery")) == 0) |
| 487 | rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; | 478 | rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; |
| @@ -495,7 +486,12 @@ static ssize_t radeon_set_dpm_state(struct device *dev, | |||
| 495 | goto fail; | 486 | goto fail; |
| 496 | } | 487 | } |
| 497 | mutex_unlock(&rdev->pm.mutex); | 488 | mutex_unlock(&rdev->pm.mutex); |
| 498 | radeon_pm_compute_clocks(rdev); | 489 | |
| 490 | /* Can't set dpm state when the card is off */ | ||
| 491 | if (!(rdev->flags & RADEON_IS_PX) || | ||
| 492 | (ddev->switch_power_state == DRM_SWITCH_POWER_ON)) | ||
| 493 | radeon_pm_compute_clocks(rdev); | ||
| 494 | |||
| 499 | fail: | 495 | fail: |
| 500 | return count; | 496 | return count; |
| 501 | } | 497 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 5b4e0cf231a0..d65607902537 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -177,16 +177,18 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
| 177 | * | 177 | * |
| 178 | * @rdev: radeon_device pointer | 178 | * @rdev: radeon_device pointer |
| 179 | * @ring: radeon_ring structure holding ring information | 179 | * @ring: radeon_ring structure holding ring information |
| 180 | * @hdp_flush: Whether or not to perform an HDP cache flush | ||
| 180 | * | 181 | * |
| 181 | * Update the wptr (write pointer) to tell the GPU to | 182 | * Update the wptr (write pointer) to tell the GPU to |
| 182 | * execute new commands on the ring buffer (all asics). | 183 | * execute new commands on the ring buffer (all asics). |
| 183 | */ | 184 | */ |
| 184 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) | 185 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring, |
| 186 | bool hdp_flush) | ||
| 185 | { | 187 | { |
| 186 | /* If we are emitting the HDP flush via the ring buffer, we need to | 188 | /* If we are emitting the HDP flush via the ring buffer, we need to |
| 187 | * do it before padding. | 189 | * do it before padding. |
| 188 | */ | 190 | */ |
| 189 | if (rdev->asic->ring[ring->idx]->hdp_flush) | 191 | if (hdp_flush && rdev->asic->ring[ring->idx]->hdp_flush) |
| 190 | rdev->asic->ring[ring->idx]->hdp_flush(rdev, ring); | 192 | rdev->asic->ring[ring->idx]->hdp_flush(rdev, ring); |
| 191 | /* We pad to match fetch size */ | 193 | /* We pad to match fetch size */ |
| 192 | while (ring->wptr & ring->align_mask) { | 194 | while (ring->wptr & ring->align_mask) { |
| @@ -196,7 +198,7 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 196 | /* If we are emitting the HDP flush via MMIO, we need to do it after | 198 | /* If we are emitting the HDP flush via MMIO, we need to do it after |
| 197 | * all CPU writes to VRAM finished. | 199 | * all CPU writes to VRAM finished. |
| 198 | */ | 200 | */ |
| 199 | if (rdev->asic->mmio_hdp_flush) | 201 | if (hdp_flush && rdev->asic->mmio_hdp_flush) |
| 200 | rdev->asic->mmio_hdp_flush(rdev); | 202 | rdev->asic->mmio_hdp_flush(rdev); |
| 201 | radeon_ring_set_wptr(rdev, ring); | 203 | radeon_ring_set_wptr(rdev, ring); |
| 202 | } | 204 | } |
| @@ -207,12 +209,14 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 207 | * | 209 | * |
| 208 | * @rdev: radeon_device pointer | 210 | * @rdev: radeon_device pointer |
| 209 | * @ring: radeon_ring structure holding ring information | 211 | * @ring: radeon_ring structure holding ring information |
| 212 | * @hdp_flush: Whether or not to perform an HDP cache flush | ||
| 210 | * | 213 | * |
| 211 | * Call radeon_ring_commit() then unlock the ring (all asics). | 214 | * Call radeon_ring_commit() then unlock the ring (all asics). |
| 212 | */ | 215 | */ |
| 213 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) | 216 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring, |
| 217 | bool hdp_flush) | ||
| 214 | { | 218 | { |
| 215 | radeon_ring_commit(rdev, ring); | 219 | radeon_ring_commit(rdev, ring, hdp_flush); |
| 216 | mutex_unlock(&rdev->ring_lock); | 220 | mutex_unlock(&rdev->ring_lock); |
| 217 | } | 221 | } |
| 218 | 222 | ||
| @@ -372,7 +376,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 372 | radeon_ring_write(ring, data[i]); | 376 | radeon_ring_write(ring, data[i]); |
| 373 | } | 377 | } |
| 374 | 378 | ||
| 375 | radeon_ring_unlock_commit(rdev, ring); | 379 | radeon_ring_unlock_commit(rdev, ring, false); |
| 376 | kfree(data); | 380 | kfree(data); |
| 377 | return 0; | 381 | return 0; |
| 378 | } | 382 | } |
| @@ -400,9 +404,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
| 400 | /* Allocate ring buffer */ | 404 | /* Allocate ring buffer */ |
| 401 | if (ring->ring_obj == NULL) { | 405 | if (ring->ring_obj == NULL) { |
| 402 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, | 406 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, |
| 403 | RADEON_GEM_DOMAIN_GTT, | 407 | RADEON_GEM_DOMAIN_GTT, 0, |
| 404 | (rdev->flags & RADEON_IS_PCIE) ? | ||
| 405 | RADEON_GEM_GTT_WC : 0, | ||
| 406 | NULL, &ring->ring_obj); | 408 | NULL, &ring->ring_obj); |
| 407 | if (r) { | 409 | if (r) { |
| 408 | dev_err(rdev->dev, "(%d) ring create failed\n", r); | 410 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index dbd6bcde92de..abd6753a570a 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | int radeon_semaphore_create(struct radeon_device *rdev, | 34 | int radeon_semaphore_create(struct radeon_device *rdev, |
| 35 | struct radeon_semaphore **semaphore) | 35 | struct radeon_semaphore **semaphore) |
| 36 | { | 36 | { |
| 37 | uint32_t *cpu_addr; | 37 | uint64_t *cpu_addr; |
| 38 | int i, r; | 38 | int i, r; |
| 39 | 39 | ||
| 40 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); | 40 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); |
| @@ -179,7 +179,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
| 179 | continue; | 179 | continue; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | radeon_ring_commit(rdev, &rdev->ring[i]); | 182 | radeon_ring_commit(rdev, &rdev->ring[i], false); |
| 183 | radeon_fence_note_sync(fence, ring); | 183 | radeon_fence_note_sync(fence, ring); |
| 184 | 184 | ||
| 185 | semaphore->gpu_addr += 8; | 185 | semaphore->gpu_addr += 8; |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 5adf4207453d..17bc3dced9f1 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
| @@ -288,7 +288,7 @@ static int radeon_test_create_and_emit_fence(struct radeon_device *rdev, | |||
| 288 | return r; | 288 | return r; |
| 289 | } | 289 | } |
| 290 | radeon_fence_emit(rdev, fence, ring->idx); | 290 | radeon_fence_emit(rdev, fence, ring->idx); |
| 291 | radeon_ring_unlock_commit(rdev, ring); | 291 | radeon_ring_unlock_commit(rdev, ring, false); |
| 292 | } | 292 | } |
| 293 | return 0; | 293 | return 0; |
| 294 | } | 294 | } |
| @@ -313,7 +313,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
| 313 | goto out_cleanup; | 313 | goto out_cleanup; |
| 314 | } | 314 | } |
| 315 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | 315 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); |
| 316 | radeon_ring_unlock_commit(rdev, ringA); | 316 | radeon_ring_unlock_commit(rdev, ringA, false); |
| 317 | 317 | ||
| 318 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1); | 318 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1); |
| 319 | if (r) | 319 | if (r) |
| @@ -325,7 +325,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
| 325 | goto out_cleanup; | 325 | goto out_cleanup; |
| 326 | } | 326 | } |
| 327 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | 327 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); |
| 328 | radeon_ring_unlock_commit(rdev, ringA); | 328 | radeon_ring_unlock_commit(rdev, ringA, false); |
| 329 | 329 | ||
| 330 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2); | 330 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2); |
| 331 | if (r) | 331 | if (r) |
| @@ -344,7 +344,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
| 344 | goto out_cleanup; | 344 | goto out_cleanup; |
| 345 | } | 345 | } |
| 346 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); | 346 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); |
| 347 | radeon_ring_unlock_commit(rdev, ringB); | 347 | radeon_ring_unlock_commit(rdev, ringB, false); |
| 348 | 348 | ||
| 349 | r = radeon_fence_wait(fence1, false); | 349 | r = radeon_fence_wait(fence1, false); |
| 350 | if (r) { | 350 | if (r) { |
| @@ -365,7 +365,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
| 365 | goto out_cleanup; | 365 | goto out_cleanup; |
| 366 | } | 366 | } |
| 367 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); | 367 | radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore); |
| 368 | radeon_ring_unlock_commit(rdev, ringB); | 368 | radeon_ring_unlock_commit(rdev, ringB, false); |
| 369 | 369 | ||
| 370 | r = radeon_fence_wait(fence2, false); | 370 | r = radeon_fence_wait(fence2, false); |
| 371 | if (r) { | 371 | if (r) { |
| @@ -408,7 +408,7 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
| 408 | goto out_cleanup; | 408 | goto out_cleanup; |
| 409 | } | 409 | } |
| 410 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); | 410 | radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); |
| 411 | radeon_ring_unlock_commit(rdev, ringA); | 411 | radeon_ring_unlock_commit(rdev, ringA, false); |
| 412 | 412 | ||
| 413 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA); | 413 | r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA); |
| 414 | if (r) | 414 | if (r) |
| @@ -420,7 +420,7 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
| 420 | goto out_cleanup; | 420 | goto out_cleanup; |
| 421 | } | 421 | } |
| 422 | radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore); | 422 | radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore); |
| 423 | radeon_ring_unlock_commit(rdev, ringB); | 423 | radeon_ring_unlock_commit(rdev, ringB, false); |
| 424 | r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB); | 424 | r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB); |
| 425 | if (r) | 425 | if (r) |
| 426 | goto out_cleanup; | 426 | goto out_cleanup; |
| @@ -442,7 +442,7 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
| 442 | goto out_cleanup; | 442 | goto out_cleanup; |
| 443 | } | 443 | } |
| 444 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); | 444 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); |
| 445 | radeon_ring_unlock_commit(rdev, ringC); | 445 | radeon_ring_unlock_commit(rdev, ringC, false); |
| 446 | 446 | ||
| 447 | for (i = 0; i < 30; ++i) { | 447 | for (i = 0; i < 30; ++i) { |
| 448 | mdelay(100); | 448 | mdelay(100); |
| @@ -468,7 +468,7 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, | |||
| 468 | goto out_cleanup; | 468 | goto out_cleanup; |
| 469 | } | 469 | } |
| 470 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); | 470 | radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore); |
| 471 | radeon_ring_unlock_commit(rdev, ringC); | 471 | radeon_ring_unlock_commit(rdev, ringC, false); |
| 472 | 472 | ||
| 473 | mdelay(1000); | 473 | mdelay(1000); |
| 474 | 474 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6bf55ec85b62..341848a14376 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
| @@ -646,7 +646,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, | |||
| 646 | ib.ptr[i] = PACKET2(0); | 646 | ib.ptr[i] = PACKET2(0); |
| 647 | ib.length_dw = 16; | 647 | ib.length_dw = 16; |
| 648 | 648 | ||
| 649 | r = radeon_ib_schedule(rdev, &ib, NULL); | 649 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 650 | if (r) | 650 | if (r) |
| 651 | goto err; | 651 | goto err; |
| 652 | ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence); | 652 | ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index f9b70a43aa52..c7190aadbd89 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
| @@ -368,7 +368,7 @@ int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring, | |||
| 368 | for (i = ib.length_dw; i < ib_size_dw; ++i) | 368 | for (i = ib.length_dw; i < ib_size_dw; ++i) |
| 369 | ib.ptr[i] = 0x0; | 369 | ib.ptr[i] = 0x0; |
| 370 | 370 | ||
| 371 | r = radeon_ib_schedule(rdev, &ib, NULL); | 371 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 372 | if (r) { | 372 | if (r) { |
| 373 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 373 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
| 374 | } | 374 | } |
| @@ -425,7 +425,7 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, | |||
| 425 | for (i = ib.length_dw; i < ib_size_dw; ++i) | 425 | for (i = ib.length_dw; i < ib_size_dw; ++i) |
| 426 | ib.ptr[i] = 0x0; | 426 | ib.ptr[i] = 0x0; |
| 427 | 427 | ||
| 428 | r = radeon_ib_schedule(rdev, &ib, NULL); | 428 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 429 | if (r) { | 429 | if (r) { |
| 430 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 430 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
| 431 | } | 431 | } |
| @@ -715,7 +715,7 @@ int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 715 | return r; | 715 | return r; |
| 716 | } | 716 | } |
| 717 | radeon_ring_write(ring, VCE_CMD_END); | 717 | radeon_ring_write(ring, VCE_CMD_END); |
| 718 | radeon_ring_unlock_commit(rdev, ring); | 718 | radeon_ring_unlock_commit(rdev, ring, false); |
| 719 | 719 | ||
| 720 | for (i = 0; i < rdev->usec_timeout; i++) { | 720 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 721 | if (vce_v1_0_get_rptr(rdev, ring) != rptr) | 721 | if (vce_v1_0_get_rptr(rdev, ring) != rptr) |
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index ccae4d9dc3de..088ffdc2f577 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
| @@ -420,7 +420,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, | |||
| 420 | radeon_asic_vm_pad_ib(rdev, &ib); | 420 | radeon_asic_vm_pad_ib(rdev, &ib); |
| 421 | WARN_ON(ib.length_dw > 64); | 421 | WARN_ON(ib.length_dw > 64); |
| 422 | 422 | ||
| 423 | r = radeon_ib_schedule(rdev, &ib, NULL); | 423 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 424 | if (r) | 424 | if (r) |
| 425 | goto error; | 425 | goto error; |
| 426 | 426 | ||
| @@ -483,6 +483,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
| 483 | /* add a clone of the bo_va to clear the old address */ | 483 | /* add a clone of the bo_va to clear the old address */ |
| 484 | struct radeon_bo_va *tmp; | 484 | struct radeon_bo_va *tmp; |
| 485 | tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); | 485 | tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); |
| 486 | if (!tmp) { | ||
| 487 | mutex_unlock(&vm->mutex); | ||
| 488 | return -ENOMEM; | ||
| 489 | } | ||
| 486 | tmp->it.start = bo_va->it.start; | 490 | tmp->it.start = bo_va->it.start; |
| 487 | tmp->it.last = bo_va->it.last; | 491 | tmp->it.last = bo_va->it.last; |
| 488 | tmp->vm = vm; | 492 | tmp->vm = vm; |
| @@ -693,7 +697,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
| 693 | radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj); | 697 | radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj); |
| 694 | radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); | 698 | radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); |
| 695 | WARN_ON(ib.length_dw > ndw); | 699 | WARN_ON(ib.length_dw > ndw); |
| 696 | r = radeon_ib_schedule(rdev, &ib, NULL); | 700 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 697 | if (r) { | 701 | if (r) { |
| 698 | radeon_ib_free(rdev, &ib); | 702 | radeon_ib_free(rdev, &ib); |
| 699 | return r; | 703 | return r; |
| @@ -957,7 +961,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
| 957 | WARN_ON(ib.length_dw > ndw); | 961 | WARN_ON(ib.length_dw > ndw); |
| 958 | 962 | ||
| 959 | radeon_semaphore_sync_to(ib.semaphore, vm->fence); | 963 | radeon_semaphore_sync_to(ib.semaphore, vm->fence); |
| 960 | r = radeon_ib_schedule(rdev, &ib, NULL); | 964 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 961 | if (r) { | 965 | if (r) { |
| 962 | radeon_ib_free(rdev, &ib); | 966 | radeon_ib_free(rdev, &ib); |
| 963 | return r; | 967 | return r; |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 3e21e869015f..8a477bf1fdb3 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -124,7 +124,7 @@ void rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 124 | radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); | 124 | radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); |
| 125 | radeon_ring_write(ring, PACKET0(0x20C8, 0)); | 125 | radeon_ring_write(ring, PACKET0(0x20C8, 0)); |
| 126 | radeon_ring_write(ring, 0); | 126 | radeon_ring_write(ring, 0); |
| 127 | radeon_ring_unlock_commit(rdev, ring); | 127 | radeon_ring_unlock_commit(rdev, ring, false); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | int rv515_mc_wait_for_idle(struct radeon_device *rdev) | 130 | int rv515_mc_wait_for_idle(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 2983f17ea1b3..d9f5ce715c9b 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -1177,7 +1177,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 1177 | u32 hdp_host_path_cntl; | 1177 | u32 hdp_host_path_cntl; |
| 1178 | u32 sq_dyn_gpr_size_simd_ab_0; | 1178 | u32 sq_dyn_gpr_size_simd_ab_0; |
| 1179 | u32 gb_tiling_config = 0; | 1179 | u32 gb_tiling_config = 0; |
| 1180 | u32 cc_rb_backend_disable = 0; | ||
| 1181 | u32 cc_gc_shader_pipe_config = 0; | 1180 | u32 cc_gc_shader_pipe_config = 0; |
| 1182 | u32 mc_arb_ramcfg; | 1181 | u32 mc_arb_ramcfg; |
| 1183 | u32 db_debug4, tmp; | 1182 | u32 db_debug4, tmp; |
| @@ -1311,21 +1310,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 1311 | WREG32(SPI_CONFIG_CNTL, 0); | 1310 | WREG32(SPI_CONFIG_CNTL, 0); |
| 1312 | } | 1311 | } |
| 1313 | 1312 | ||
| 1314 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; | ||
| 1315 | tmp = R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_rb_backend_disable >> 16); | ||
| 1316 | if (tmp < rdev->config.rv770.max_backends) { | ||
| 1317 | rdev->config.rv770.max_backends = tmp; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; | 1313 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; |
| 1321 | tmp = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R7XX_MAX_PIPES_MASK); | ||
| 1322 | if (tmp < rdev->config.rv770.max_pipes) { | ||
| 1323 | rdev->config.rv770.max_pipes = tmp; | ||
| 1324 | } | ||
| 1325 | tmp = R7XX_MAX_SIMDS - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK); | ||
| 1326 | if (tmp < rdev->config.rv770.max_simds) { | ||
| 1327 | rdev->config.rv770.max_simds = tmp; | ||
| 1328 | } | ||
| 1329 | tmp = rdev->config.rv770.max_simds - | 1314 | tmp = rdev->config.rv770.max_simds - |
| 1330 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK); | 1315 | r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK); |
| 1331 | rdev->config.rv770.active_simds = tmp; | 1316 | rdev->config.rv770.active_simds = tmp; |
| @@ -1348,6 +1333,14 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 1348 | rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes; | 1333 | rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes; |
| 1349 | 1334 | ||
| 1350 | disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK; | 1335 | disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK; |
| 1336 | tmp = 0; | ||
| 1337 | for (i = 0; i < rdev->config.rv770.max_backends; i++) | ||
| 1338 | tmp |= (1 << i); | ||
| 1339 | /* if all the backends are disabled, fix it up here */ | ||
| 1340 | if ((disabled_rb_mask & tmp) == tmp) { | ||
| 1341 | for (i = 0; i < rdev->config.rv770.max_backends; i++) | ||
| 1342 | disabled_rb_mask &= ~(1 << i); | ||
| 1343 | } | ||
| 1351 | tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; | 1344 | tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; |
| 1352 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends, | 1345 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends, |
| 1353 | R7XX_MAX_BACKENDS, disabled_rb_mask); | 1346 | R7XX_MAX_BACKENDS, disabled_rb_mask); |
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index bbf2e076ee45..74426ac2bb5c 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c | |||
| @@ -90,7 +90,7 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
| 90 | return r; | 90 | return r; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | radeon_ring_unlock_commit(rdev, ring); | 93 | radeon_ring_unlock_commit(rdev, ring, false); |
| 94 | radeon_semaphore_free(rdev, &sem, *fence); | 94 | radeon_semaphore_free(rdev, &sem, *fence); |
| 95 | 95 | ||
| 96 | return r; | 96 | return r; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 011779bd2b3d..6bce40847753 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -3057,7 +3057,7 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
| 3057 | u32 sx_debug_1; | 3057 | u32 sx_debug_1; |
| 3058 | u32 hdp_host_path_cntl; | 3058 | u32 hdp_host_path_cntl; |
| 3059 | u32 tmp; | 3059 | u32 tmp; |
| 3060 | int i, j, k; | 3060 | int i, j; |
| 3061 | 3061 | ||
| 3062 | switch (rdev->family) { | 3062 | switch (rdev->family) { |
| 3063 | case CHIP_TAHITI: | 3063 | case CHIP_TAHITI: |
| @@ -3255,12 +3255,11 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
| 3255 | rdev->config.si.max_sh_per_se, | 3255 | rdev->config.si.max_sh_per_se, |
| 3256 | rdev->config.si.max_cu_per_sh); | 3256 | rdev->config.si.max_cu_per_sh); |
| 3257 | 3257 | ||
| 3258 | rdev->config.si.active_cus = 0; | ||
| 3258 | for (i = 0; i < rdev->config.si.max_shader_engines; i++) { | 3259 | for (i = 0; i < rdev->config.si.max_shader_engines; i++) { |
| 3259 | for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { | 3260 | for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { |
| 3260 | for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) { | 3261 | rdev->config.si.active_cus += |
| 3261 | rdev->config.si.active_cus += | 3262 | hweight32(si_get_cu_active_bitmap(rdev, i, j)); |
| 3262 | hweight32(si_get_cu_active_bitmap(rdev, i, j)); | ||
| 3263 | } | ||
| 3264 | } | 3263 | } |
| 3265 | } | 3264 | } |
| 3266 | 3265 | ||
| @@ -3541,7 +3540,7 @@ static int si_cp_start(struct radeon_device *rdev) | |||
| 3541 | radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); | 3540 | radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); |
| 3542 | radeon_ring_write(ring, 0xc000); | 3541 | radeon_ring_write(ring, 0xc000); |
| 3543 | radeon_ring_write(ring, 0xe000); | 3542 | radeon_ring_write(ring, 0xe000); |
| 3544 | radeon_ring_unlock_commit(rdev, ring); | 3543 | radeon_ring_unlock_commit(rdev, ring, false); |
| 3545 | 3544 | ||
| 3546 | si_cp_enable(rdev, true); | 3545 | si_cp_enable(rdev, true); |
| 3547 | 3546 | ||
| @@ -3570,7 +3569,7 @@ static int si_cp_start(struct radeon_device *rdev) | |||
| 3570 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | 3569 | radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ |
| 3571 | radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ | 3570 | radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ |
| 3572 | 3571 | ||
| 3573 | radeon_ring_unlock_commit(rdev, ring); | 3572 | radeon_ring_unlock_commit(rdev, ring, false); |
| 3574 | 3573 | ||
| 3575 | for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { | 3574 | for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { |
| 3576 | ring = &rdev->ring[i]; | 3575 | ring = &rdev->ring[i]; |
| @@ -3580,7 +3579,7 @@ static int si_cp_start(struct radeon_device *rdev) | |||
| 3580 | radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); | 3579 | radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); |
| 3581 | radeon_ring_write(ring, 0); | 3580 | radeon_ring_write(ring, 0); |
| 3582 | 3581 | ||
| 3583 | radeon_ring_unlock_commit(rdev, ring); | 3582 | radeon_ring_unlock_commit(rdev, ring, false); |
| 3584 | } | 3583 | } |
| 3585 | 3584 | ||
| 3586 | return 0; | 3585 | return 0; |
| @@ -4291,10 +4290,10 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4291 | for (i = 1; i < 16; i++) { | 4290 | for (i = 1; i < 16; i++) { |
| 4292 | if (i < 8) | 4291 | if (i < 8) |
| 4293 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 4292 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
| 4294 | rdev->gart.table_addr >> 12); | 4293 | rdev->vm_manager.saved_table_addr[i]); |
| 4295 | else | 4294 | else |
| 4296 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), | 4295 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), |
| 4297 | rdev->gart.table_addr >> 12); | 4296 | rdev->vm_manager.saved_table_addr[i]); |
| 4298 | } | 4297 | } |
| 4299 | 4298 | ||
| 4300 | /* enable context1-15 */ | 4299 | /* enable context1-15 */ |
| @@ -4326,6 +4325,17 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4326 | 4325 | ||
| 4327 | static void si_pcie_gart_disable(struct radeon_device *rdev) | 4326 | static void si_pcie_gart_disable(struct radeon_device *rdev) |
| 4328 | { | 4327 | { |
| 4328 | unsigned i; | ||
| 4329 | |||
| 4330 | for (i = 1; i < 16; ++i) { | ||
| 4331 | uint32_t reg; | ||
| 4332 | if (i < 8) | ||
| 4333 | reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2); | ||
| 4334 | else | ||
| 4335 | reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2); | ||
| 4336 | rdev->vm_manager.saved_table_addr[i] = RREG32(reg); | ||
| 4337 | } | ||
| 4338 | |||
| 4329 | /* Disable all tables */ | 4339 | /* Disable all tables */ |
| 4330 | WREG32(VM_CONTEXT0_CNTL, 0); | 4340 | WREG32(VM_CONTEXT0_CNTL, 0); |
| 4331 | WREG32(VM_CONTEXT1_CNTL, 0); | 4341 | WREG32(VM_CONTEXT1_CNTL, 0); |
| @@ -5028,7 +5038,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 5028 | 5038 | ||
| 5029 | /* flush hdp cache */ | 5039 | /* flush hdp cache */ |
| 5030 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5040 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
| 5031 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 5041 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | |
| 5032 | WRITE_DATA_DST_SEL(0))); | 5042 | WRITE_DATA_DST_SEL(0))); |
| 5033 | radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); | 5043 | radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); |
| 5034 | radeon_ring_write(ring, 0); | 5044 | radeon_ring_write(ring, 0); |
| @@ -5036,7 +5046,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 5036 | 5046 | ||
| 5037 | /* bits 0-15 are the VM contexts0-15 */ | 5047 | /* bits 0-15 are the VM contexts0-15 */ |
| 5038 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5048 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
| 5039 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 5049 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | |
| 5040 | WRITE_DATA_DST_SEL(0))); | 5050 | WRITE_DATA_DST_SEL(0))); |
| 5041 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 5051 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
| 5042 | radeon_ring_write(ring, 0); | 5052 | radeon_ring_write(ring, 0); |
| @@ -7178,6 +7188,9 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) | |||
| 7178 | int ret, i; | 7188 | int ret, i; |
| 7179 | u16 tmp16; | 7189 | u16 tmp16; |
| 7180 | 7190 | ||
| 7191 | if (pci_is_root_bus(rdev->pdev->bus)) | ||
| 7192 | return; | ||
| 7193 | |||
| 7181 | if (radeon_pcie_gen2 == 0) | 7194 | if (radeon_pcie_gen2 == 0) |
| 7182 | return; | 7195 | return; |
| 7183 | 7196 | ||
| @@ -7455,7 +7468,8 @@ static void si_program_aspm(struct radeon_device *rdev) | |||
| 7455 | if (orig != data) | 7468 | if (orig != data) |
| 7456 | WREG32_PIF_PHY1(PB1_PIF_CNTL, data); | 7469 | WREG32_PIF_PHY1(PB1_PIF_CNTL, data); |
| 7457 | 7470 | ||
| 7458 | if (!disable_clkreq) { | 7471 | if (!disable_clkreq && |
| 7472 | !pci_is_root_bus(rdev->pdev->bus)) { | ||
| 7459 | struct pci_dev *root = rdev->pdev->bus->self; | 7473 | struct pci_dev *root = rdev->pdev->bus->self; |
| 7460 | u32 lnkcap; | 7474 | u32 lnkcap; |
| 7461 | 7475 | ||
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index 716505129450..7c22baaf94db 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
| @@ -275,7 +275,7 @@ int si_copy_dma(struct radeon_device *rdev, | |||
| 275 | return r; | 275 | return r; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | radeon_ring_unlock_commit(rdev, ring); | 278 | radeon_ring_unlock_commit(rdev, ring, false); |
| 279 | radeon_semaphore_free(rdev, &sem, *fence); | 279 | radeon_semaphore_free(rdev, &sem, *fence); |
| 280 | 280 | ||
| 281 | return r; | 281 | return r; |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 32e50be9c4ac..57f780053b3e 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
| @@ -1874,16 +1874,22 @@ int trinity_dpm_init(struct radeon_device *rdev) | |||
| 1874 | for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) | 1874 | for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) |
| 1875 | pi->at[i] = TRINITY_AT_DFLT; | 1875 | pi->at[i] = TRINITY_AT_DFLT; |
| 1876 | 1876 | ||
| 1877 | /* There are stability issues reported on with | 1877 | if (radeon_bapm == -1) { |
| 1878 | * bapm enabled when switching between AC and battery | 1878 | /* There are stability issues reported on with |
| 1879 | * power. At the same time, some MSI boards hang | 1879 | * bapm enabled when switching between AC and battery |
| 1880 | * if it's not enabled and dpm is enabled. Just enable | 1880 | * power. At the same time, some MSI boards hang |
| 1881 | * it for MSI boards right now. | 1881 | * if it's not enabled and dpm is enabled. Just enable |
| 1882 | */ | 1882 | * it for MSI boards right now. |
| 1883 | if (rdev->pdev->subsystem_vendor == 0x1462) | 1883 | */ |
| 1884 | pi->enable_bapm = true; | 1884 | if (rdev->pdev->subsystem_vendor == 0x1462) |
| 1885 | else | 1885 | pi->enable_bapm = true; |
| 1886 | else | ||
| 1887 | pi->enable_bapm = false; | ||
| 1888 | } else if (radeon_bapm == 0) { | ||
| 1886 | pi->enable_bapm = false; | 1889 | pi->enable_bapm = false; |
| 1890 | } else { | ||
| 1891 | pi->enable_bapm = true; | ||
| 1892 | } | ||
| 1887 | pi->enable_nbps_policy = true; | 1893 | pi->enable_nbps_policy = true; |
| 1888 | pi->enable_sclk_ds = true; | 1894 | pi->enable_sclk_ds = true; |
| 1889 | pi->enable_gfx_power_gating = true; | 1895 | pi->enable_gfx_power_gating = true; |
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index be42c8125203..cda391347286 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c | |||
| @@ -124,7 +124,7 @@ int uvd_v1_0_init(struct radeon_device *rdev) | |||
| 124 | radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0)); | 124 | radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0)); |
| 125 | radeon_ring_write(ring, 3); | 125 | radeon_ring_write(ring, 3); |
| 126 | 126 | ||
| 127 | radeon_ring_unlock_commit(rdev, ring); | 127 | radeon_ring_unlock_commit(rdev, ring, false); |
| 128 | 128 | ||
| 129 | done: | 129 | done: |
| 130 | /* lower clocks again */ | 130 | /* lower clocks again */ |
| @@ -331,7 +331,7 @@ int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 331 | } | 331 | } |
| 332 | radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); | 332 | radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); |
| 333 | radeon_ring_write(ring, 0xDEADBEEF); | 333 | radeon_ring_write(ring, 0xDEADBEEF); |
| 334 | radeon_ring_unlock_commit(rdev, ring); | 334 | radeon_ring_unlock_commit(rdev, ring, false); |
| 335 | for (i = 0; i < rdev->usec_timeout; i++) { | 335 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 336 | tmp = RREG32(UVD_CONTEXT_ID); | 336 | tmp = RREG32(UVD_CONTEXT_ID); |
| 337 | if (tmp == 0xDEADBEEF) | 337 | if (tmp == 0xDEADBEEF) |
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig index 2d9d4252d598..ae8850f3e63b 100644 --- a/drivers/gpu/drm/sti/Kconfig +++ b/drivers/gpu/drm/sti/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config DRM_STI | 1 | config DRM_STI |
| 2 | tristate "DRM Support for STMicroelectronics SoC stiH41x Series" | 2 | tristate "DRM Support for STMicroelectronics SoC stiH41x Series" |
| 3 | depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM) | 3 | depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM) |
| 4 | select RESET_CONTROLLER | ||
| 4 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 5 | select DRM_GEM_CMA_HELPER | 6 | select DRM_GEM_CMA_HELPER |
| 6 | select DRM_KMS_CMA_HELPER | 7 | select DRM_KMS_CMA_HELPER |
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.c b/drivers/gpu/drm/sti/sti_drm_drv.c index a7cc24917a96..223d93c3a05d 100644 --- a/drivers/gpu/drm/sti/sti_drm_drv.c +++ b/drivers/gpu/drm/sti/sti_drm_drv.c | |||
| @@ -201,8 +201,8 @@ static int sti_drm_platform_probe(struct platform_device *pdev) | |||
| 201 | master = platform_device_register_resndata(dev, | 201 | master = platform_device_register_resndata(dev, |
| 202 | DRIVER_NAME "__master", -1, | 202 | DRIVER_NAME "__master", -1, |
| 203 | NULL, 0, NULL, 0); | 203 | NULL, 0, NULL, 0); |
| 204 | if (!master) | 204 | if (IS_ERR(master)) |
| 205 | return -EINVAL; | 205 | return PTR_ERR(master); |
| 206 | 206 | ||
| 207 | platform_set_drvdata(pdev, master); | 207 | platform_set_drvdata(pdev, master); |
| 208 | return 0; | 208 | return 0; |
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c index 72d957f81c05..2ae9a9b73666 100644 --- a/drivers/gpu/drm/sti/sti_hda.c +++ b/drivers/gpu/drm/sti/sti_hda.c | |||
| @@ -730,16 +730,16 @@ static int sti_hda_probe(struct platform_device *pdev) | |||
| 730 | return -ENOMEM; | 730 | return -ENOMEM; |
| 731 | } | 731 | } |
| 732 | hda->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); | 732 | hda->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); |
| 733 | if (IS_ERR(hda->regs)) | 733 | if (!hda->regs) |
| 734 | return PTR_ERR(hda->regs); | 734 | return -ENOMEM; |
| 735 | 735 | ||
| 736 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 736 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| 737 | "video-dacs-ctrl"); | 737 | "video-dacs-ctrl"); |
| 738 | if (res) { | 738 | if (res) { |
| 739 | hda->video_dacs_ctrl = devm_ioremap_nocache(dev, res->start, | 739 | hda->video_dacs_ctrl = devm_ioremap_nocache(dev, res->start, |
| 740 | resource_size(res)); | 740 | resource_size(res)); |
| 741 | if (IS_ERR(hda->video_dacs_ctrl)) | 741 | if (!hda->video_dacs_ctrl) |
| 742 | return PTR_ERR(hda->video_dacs_ctrl); | 742 | return -ENOMEM; |
| 743 | } else { | 743 | } else { |
| 744 | /* If no existing video-dacs-ctrl resource continue the probe */ | 744 | /* If no existing video-dacs-ctrl resource continue the probe */ |
| 745 | DRM_DEBUG_DRIVER("No video-dacs-ctrl resource\n"); | 745 | DRM_DEBUG_DRIVER("No video-dacs-ctrl resource\n"); |
| @@ -770,7 +770,7 @@ static int sti_hda_remove(struct platform_device *pdev) | |||
| 770 | return 0; | 770 | return 0; |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | static struct of_device_id hda_of_match[] = { | 773 | static const struct of_device_id hda_of_match[] = { |
| 774 | { .compatible = "st,stih416-hda", }, | 774 | { .compatible = "st,stih416-hda", }, |
| 775 | { .compatible = "st,stih407-hda", }, | 775 | { .compatible = "st,stih407-hda", }, |
| 776 | { /* end node */ } | 776 | { /* end node */ } |
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 284e541d970d..ef93156a69c6 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c | |||
| @@ -677,7 +677,7 @@ static const struct component_ops sti_hdmi_ops = { | |||
| 677 | .unbind = sti_hdmi_unbind, | 677 | .unbind = sti_hdmi_unbind, |
| 678 | }; | 678 | }; |
| 679 | 679 | ||
| 680 | static struct of_device_id hdmi_of_match[] = { | 680 | static const struct of_device_id hdmi_of_match[] = { |
| 681 | { | 681 | { |
| 682 | .compatible = "st,stih416-hdmi", | 682 | .compatible = "st,stih416-hdmi", |
| 683 | .data = &tx3g0c55phy_ops, | 683 | .data = &tx3g0c55phy_ops, |
| @@ -713,8 +713,8 @@ static int sti_hdmi_probe(struct platform_device *pdev) | |||
| 713 | return -ENOMEM; | 713 | return -ENOMEM; |
| 714 | } | 714 | } |
| 715 | hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); | 715 | hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); |
| 716 | if (IS_ERR(hdmi->regs)) | 716 | if (!hdmi->regs) |
| 717 | return PTR_ERR(hdmi->regs); | 717 | return -ENOMEM; |
| 718 | 718 | ||
| 719 | if (of_device_is_compatible(np, "st,stih416-hdmi")) { | 719 | if (of_device_is_compatible(np, "st,stih416-hdmi")) { |
| 720 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 720 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| @@ -725,8 +725,8 @@ static int sti_hdmi_probe(struct platform_device *pdev) | |||
| 725 | } | 725 | } |
| 726 | hdmi->syscfg = devm_ioremap_nocache(dev, res->start, | 726 | hdmi->syscfg = devm_ioremap_nocache(dev, res->start, |
| 727 | resource_size(res)); | 727 | resource_size(res)); |
| 728 | if (IS_ERR(hdmi->syscfg)) | 728 | if (!hdmi->syscfg) |
| 729 | return PTR_ERR(hdmi->syscfg); | 729 | return -ENOMEM; |
| 730 | 730 | ||
| 731 | } | 731 | } |
| 732 | 732 | ||
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c index b69e26fee76e..b8afe490356a 100644 --- a/drivers/gpu/drm/sti/sti_tvout.c +++ b/drivers/gpu/drm/sti/sti_tvout.c | |||
| @@ -591,8 +591,8 @@ static int sti_tvout_probe(struct platform_device *pdev) | |||
| 591 | return -ENOMEM; | 591 | return -ENOMEM; |
| 592 | } | 592 | } |
| 593 | tvout->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); | 593 | tvout->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); |
| 594 | if (IS_ERR(tvout->regs)) | 594 | if (!tvout->regs) |
| 595 | return PTR_ERR(tvout->regs); | 595 | return -ENOMEM; |
| 596 | 596 | ||
| 597 | /* get reset resources */ | 597 | /* get reset resources */ |
| 598 | tvout->reset = devm_reset_control_get(dev, "tvout"); | 598 | tvout->reset = devm_reset_control_get(dev, "tvout"); |
| @@ -624,7 +624,7 @@ static int sti_tvout_remove(struct platform_device *pdev) | |||
| 624 | return 0; | 624 | return 0; |
| 625 | } | 625 | } |
| 626 | 626 | ||
| 627 | static struct of_device_id tvout_of_match[] = { | 627 | static const struct of_device_id tvout_of_match[] = { |
| 628 | { .compatible = "st,stih416-tvout", }, | 628 | { .compatible = "st,stih416-tvout", }, |
| 629 | { .compatible = "st,stih407-tvout", }, | 629 | { .compatible = "st,stih407-tvout", }, |
| 630 | { /* end node */ } | 630 | { /* end node */ } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7bfdaa163a33..36b871686d3c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -450,11 +450,11 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, | |||
| 450 | res, | 450 | res, |
| 451 | id_loc - sw_context->buf_start); | 451 | id_loc - sw_context->buf_start); |
| 452 | if (unlikely(ret != 0)) | 452 | if (unlikely(ret != 0)) |
| 453 | goto out_err; | 453 | return ret; |
| 454 | 454 | ||
| 455 | ret = vmw_resource_val_add(sw_context, res, &node); | 455 | ret = vmw_resource_val_add(sw_context, res, &node); |
| 456 | if (unlikely(ret != 0)) | 456 | if (unlikely(ret != 0)) |
| 457 | goto out_err; | 457 | return ret; |
| 458 | 458 | ||
| 459 | if (res_type == vmw_res_context && dev_priv->has_mob && | 459 | if (res_type == vmw_res_context && dev_priv->has_mob && |
| 460 | node->first_usage) { | 460 | node->first_usage) { |
| @@ -468,13 +468,13 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, | |||
| 468 | 468 | ||
| 469 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); | 469 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); |
| 470 | if (unlikely(ret != 0)) | 470 | if (unlikely(ret != 0)) |
| 471 | goto out_err; | 471 | return ret; |
| 472 | node->staged_bindings = | 472 | node->staged_bindings = |
| 473 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); | 473 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); |
| 474 | if (node->staged_bindings == NULL) { | 474 | if (node->staged_bindings == NULL) { |
| 475 | DRM_ERROR("Failed to allocate context binding " | 475 | DRM_ERROR("Failed to allocate context binding " |
| 476 | "information.\n"); | 476 | "information.\n"); |
| 477 | goto out_err; | 477 | return -ENOMEM; |
| 478 | } | 478 | } |
| 479 | INIT_LIST_HEAD(&node->staged_bindings->list); | 479 | INIT_LIST_HEAD(&node->staged_bindings->list); |
| 480 | } | 480 | } |
| @@ -482,8 +482,7 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, | |||
| 482 | if (p_val) | 482 | if (p_val) |
| 483 | *p_val = node; | 483 | *p_val = node; |
| 484 | 484 | ||
| 485 | out_err: | 485 | return 0; |
| 486 | return ret; | ||
| 487 | } | 486 | } |
| 488 | 487 | ||
| 489 | 488 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 6ccd993e26bf..6eae14d2a3f7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
| @@ -180,8 +180,9 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 180 | 180 | ||
| 181 | mutex_lock(&dev_priv->hw_mutex); | 181 | mutex_lock(&dev_priv->hw_mutex); |
| 182 | 182 | ||
| 183 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); | ||
| 183 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) | 184 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) |
| 184 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); | 185 | ; |
| 185 | 186 | ||
| 186 | dev_priv->last_read_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); | 187 | dev_priv->last_read_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); |
| 187 | 188 | ||
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index 1bdcccc54a1d..f745d2c1325e 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 29 | unsigned int *rsize) | 29 | unsigned int *rsize) |
| 30 | { | 30 | { |
| 31 | if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | 31 | if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { |
| 32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); | 32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); |
| 33 | rdesc[11] = rdesc[16] = 0xff; | 33 | rdesc[11] = rdesc[16] = 0xff; |
| 34 | rdesc[12] = rdesc[17] = 0x03; | 34 | rdesc[12] = rdesc[17] = 0x03; |
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c index 60f44cd1b0ed..61b68ca27790 100644 --- a/drivers/hid/hid-huion.c +++ b/drivers/hid/hid-huion.c | |||
| @@ -84,6 +84,15 @@ static const __u8 huion_tablet_rdesc_template[] = { | |||
| 84 | 0xC0 /* End Collection */ | 84 | 0xC0 /* End Collection */ |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | /* Parameter indices */ | ||
| 88 | enum huion_prm { | ||
| 89 | HUION_PRM_X_LM = 1, | ||
| 90 | HUION_PRM_Y_LM = 2, | ||
| 91 | HUION_PRM_PRESSURE_LM = 4, | ||
| 92 | HUION_PRM_RESOLUTION = 5, | ||
| 93 | HUION_PRM_NUM | ||
| 94 | }; | ||
| 95 | |||
| 87 | /* Driver data */ | 96 | /* Driver data */ |
| 88 | struct huion_drvdata { | 97 | struct huion_drvdata { |
| 89 | __u8 *rdesc; | 98 | __u8 *rdesc; |
| @@ -115,7 +124,12 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 115 | int rc; | 124 | int rc; |
| 116 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | 125 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); |
| 117 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); | 126 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); |
| 118 | __le16 buf[6]; | 127 | __le16 *buf = NULL; |
| 128 | size_t len; | ||
| 129 | s32 params[HUION_PH_ID_NUM]; | ||
| 130 | s32 resolution; | ||
| 131 | __u8 *p; | ||
| 132 | s32 v; | ||
| 119 | 133 | ||
| 120 | /* | 134 | /* |
| 121 | * Read string descriptor containing tablet parameters. The specific | 135 | * Read string descriptor containing tablet parameters. The specific |
| @@ -123,65 +137,79 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 123 | * driver traffic. | 137 | * driver traffic. |
| 124 | * NOTE: This enables fully-functional tablet mode. | 138 | * NOTE: This enables fully-functional tablet mode. |
| 125 | */ | 139 | */ |
| 140 | len = HUION_PRM_NUM * sizeof(*buf); | ||
| 141 | buf = kmalloc(len, GFP_KERNEL); | ||
| 142 | if (buf == NULL) { | ||
| 143 | hid_err(hdev, "failed to allocate parameter buffer\n"); | ||
| 144 | rc = -ENOMEM; | ||
| 145 | goto cleanup; | ||
| 146 | } | ||
| 126 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 147 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
| 127 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 148 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
| 128 | (USB_DT_STRING << 8) + 0x64, | 149 | (USB_DT_STRING << 8) + 0x64, |
| 129 | 0x0409, buf, sizeof(buf), | 150 | 0x0409, buf, len, |
| 130 | USB_CTRL_GET_TIMEOUT); | 151 | USB_CTRL_GET_TIMEOUT); |
| 131 | if (rc == -EPIPE) | 152 | if (rc == -EPIPE) { |
| 132 | hid_warn(hdev, "device parameters not found\n"); | 153 | hid_err(hdev, "device parameters not found\n"); |
| 133 | else if (rc < 0) | 154 | rc = -ENODEV; |
| 134 | hid_warn(hdev, "failed to get device parameters: %d\n", rc); | 155 | goto cleanup; |
| 135 | else if (rc != sizeof(buf)) | 156 | } else if (rc < 0) { |
| 136 | hid_warn(hdev, "invalid device parameters\n"); | 157 | hid_err(hdev, "failed to get device parameters: %d\n", rc); |
| 137 | else { | 158 | rc = -ENODEV; |
| 138 | s32 params[HUION_PH_ID_NUM]; | 159 | goto cleanup; |
| 139 | s32 resolution; | 160 | } else if (rc != len) { |
| 140 | __u8 *p; | 161 | hid_err(hdev, "invalid device parameters\n"); |
| 141 | s32 v; | 162 | rc = -ENODEV; |
| 163 | goto cleanup; | ||
| 164 | } | ||
| 142 | 165 | ||
| 143 | /* Extract device parameters */ | 166 | /* Extract device parameters */ |
| 144 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); | 167 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]); |
| 145 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); | 168 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]); |
| 146 | params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); | 169 | params[HUION_PH_ID_PRESSURE_LM] = |
| 147 | resolution = le16_to_cpu(buf[5]); | 170 | le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]); |
| 148 | if (resolution == 0) { | 171 | resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]); |
| 149 | params[HUION_PH_ID_X_PM] = 0; | 172 | if (resolution == 0) { |
| 150 | params[HUION_PH_ID_Y_PM] = 0; | 173 | params[HUION_PH_ID_X_PM] = 0; |
| 151 | } else { | 174 | params[HUION_PH_ID_Y_PM] = 0; |
| 152 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * | 175 | } else { |
| 153 | 1000 / resolution; | 176 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * |
| 154 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * | 177 | 1000 / resolution; |
| 155 | 1000 / resolution; | 178 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * |
| 156 | } | 179 | 1000 / resolution; |
| 180 | } | ||
| 157 | 181 | ||
| 158 | /* Allocate fixed report descriptor */ | 182 | /* Allocate fixed report descriptor */ |
| 159 | drvdata->rdesc = devm_kmalloc(&hdev->dev, | 183 | drvdata->rdesc = devm_kmalloc(&hdev->dev, |
| 160 | sizeof(huion_tablet_rdesc_template), | 184 | sizeof(huion_tablet_rdesc_template), |
| 161 | GFP_KERNEL); | 185 | GFP_KERNEL); |
| 162 | if (drvdata->rdesc == NULL) { | 186 | if (drvdata->rdesc == NULL) { |
| 163 | hid_err(hdev, "failed to allocate fixed rdesc\n"); | 187 | hid_err(hdev, "failed to allocate fixed rdesc\n"); |
| 164 | return -ENOMEM; | 188 | rc = -ENOMEM; |
| 165 | } | 189 | goto cleanup; |
| 166 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | 190 | } |
| 191 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | ||
| 167 | 192 | ||
| 168 | /* Format fixed report descriptor */ | 193 | /* Format fixed report descriptor */ |
| 169 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, | 194 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, |
| 170 | drvdata->rsize); | 195 | drvdata->rsize); |
| 171 | for (p = drvdata->rdesc; | 196 | for (p = drvdata->rdesc; |
| 172 | p <= drvdata->rdesc + drvdata->rsize - 4;) { | 197 | p <= drvdata->rdesc + drvdata->rsize - 4;) { |
| 173 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && | 198 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && |
| 174 | p[3] < sizeof(params)) { | 199 | p[3] < sizeof(params)) { |
| 175 | v = params[p[3]]; | 200 | v = params[p[3]]; |
| 176 | put_unaligned(cpu_to_le32(v), (s32 *)p); | 201 | put_unaligned(cpu_to_le32(v), (s32 *)p); |
| 177 | p += 4; | 202 | p += 4; |
| 178 | } else { | 203 | } else { |
| 179 | p++; | 204 | p++; |
| 180 | } | ||
| 181 | } | 205 | } |
| 182 | } | 206 | } |
| 183 | 207 | ||
| 184 | return 0; | 208 | rc = 0; |
| 209 | |||
| 210 | cleanup: | ||
| 211 | kfree(buf); | ||
| 212 | return rc; | ||
| 185 | } | 213 | } |
| 186 | 214 | ||
| 187 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) | 215 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index e77696367591..b92bf01a1ae8 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
| @@ -300,7 +300,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 300 | * - change the button usage range to 4-7 for the extra | 300 | * - change the button usage range to 4-7 for the extra |
| 301 | * buttons | 301 | * buttons |
| 302 | */ | 302 | */ |
| 303 | if (*rsize >= 74 && | 303 | if (*rsize >= 75 && |
| 304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | 304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && |
| 305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | 305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && |
| 306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | 306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a976f48263f6..f91ff145db9a 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -345,14 +345,14 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 345 | struct usb_device_descriptor *udesc; | 345 | struct usb_device_descriptor *udesc; |
| 346 | __u16 bcdDevice, rev_maj, rev_min; | 346 | __u16 bcdDevice, rev_maj, rev_min; |
| 347 | 347 | ||
| 348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 && |
| 349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
| 350 | hid_info(hdev, | 350 | hid_info(hdev, |
| 351 | "fixing up Logitech keyboard report descriptor\n"); | 351 | "fixing up Logitech keyboard report descriptor\n"); |
| 352 | rdesc[84] = rdesc[89] = 0x4d; | 352 | rdesc[84] = rdesc[89] = 0x4d; |
| 353 | rdesc[85] = rdesc[90] = 0x10; | 353 | rdesc[85] = rdesc[90] = 0x10; |
| 354 | } | 354 | } |
| 355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && | 355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 && |
| 356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | 356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && |
| 357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | 357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { |
| 358 | hid_info(hdev, | 358 | hid_info(hdev, |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index cc2bd2022198..7835717bc020 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
| @@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
| 451 | drv_data = hid_get_drvdata(hid); | 451 | drv_data = hid_get_drvdata(hid); |
| 452 | if (!drv_data) { | 452 | if (!drv_data) { |
| 453 | hid_err(hid, "Private driver data not found!\n"); | 453 | hid_err(hid, "Private driver data not found!\n"); |
| 454 | return 0; | 454 | return -EINVAL; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | entry = drv_data->device_props; | 457 | entry = drv_data->device_props; |
| 458 | if (!entry) { | 458 | if (!entry) { |
| 459 | hid_err(hid, "Device properties not found!\n"); | 459 | hid_err(hid, "Device properties not found!\n"); |
| 460 | return 0; | 460 | return -EINVAL; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | if (range == 0) | 463 | if (range == 0) |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 486dbde2ba2d..9bf8637747a5 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
| @@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
| 238 | return; | 238 | return; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
| 242 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
| 243 | dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", | ||
| 244 | __func__, dj_report->device_index); | ||
| 245 | return; | ||
| 246 | } | ||
| 247 | |||
| 248 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | 241 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { |
| 249 | /* The device is already known. No need to reallocate it. */ | 242 | /* The device is already known. No need to reallocate it. */ |
| 250 | dbg_hid("%s: device is already known\n", __func__); | 243 | dbg_hid("%s: device is already known\n", __func__); |
| @@ -557,7 +550,7 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
| 557 | if (!out_buf) | 550 | if (!out_buf) |
| 558 | return -ENOMEM; | 551 | return -ENOMEM; |
| 559 | 552 | ||
| 560 | if (count < DJREPORT_SHORT_LENGTH - 2) | 553 | if (count > DJREPORT_SHORT_LENGTH - 2) |
| 561 | count = DJREPORT_SHORT_LENGTH - 2; | 554 | count = DJREPORT_SHORT_LENGTH - 2; |
| 562 | 555 | ||
| 563 | out_buf[0] = REPORT_ID_DJ_SHORT; | 556 | out_buf[0] = REPORT_ID_DJ_SHORT; |
| @@ -663,7 +656,6 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
| 663 | struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); | 656 | struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); |
| 664 | struct dj_report *dj_report = (struct dj_report *) data; | 657 | struct dj_report *dj_report = (struct dj_report *) data; |
| 665 | unsigned long flags; | 658 | unsigned long flags; |
| 666 | bool report_processed = false; | ||
| 667 | 659 | ||
| 668 | dbg_hid("%s, size:%d\n", __func__, size); | 660 | dbg_hid("%s, size:%d\n", __func__, size); |
| 669 | 661 | ||
| @@ -691,27 +683,41 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
| 691 | * anything else with it. | 683 | * anything else with it. |
| 692 | */ | 684 | */ |
| 693 | 685 | ||
| 686 | /* case 1) */ | ||
| 687 | if (data[0] != REPORT_ID_DJ_SHORT) | ||
| 688 | return false; | ||
| 689 | |||
| 690 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
| 691 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
| 692 | /* | ||
| 693 | * Device index is wrong, bail out. | ||
| 694 | * This driver can ignore safely the receiver notifications, | ||
| 695 | * so ignore those reports too. | ||
| 696 | */ | ||
| 697 | if (dj_report->device_index != DJ_RECEIVER_INDEX) | ||
| 698 | dev_err(&hdev->dev, "%s: invalid device index:%d\n", | ||
| 699 | __func__, dj_report->device_index); | ||
| 700 | return false; | ||
| 701 | } | ||
| 702 | |||
| 694 | spin_lock_irqsave(&djrcv_dev->lock, flags); | 703 | spin_lock_irqsave(&djrcv_dev->lock, flags); |
| 695 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { | 704 | switch (dj_report->report_type) { |
| 696 | switch (dj_report->report_type) { | 705 | case REPORT_TYPE_NOTIF_DEVICE_PAIRED: |
| 697 | case REPORT_TYPE_NOTIF_DEVICE_PAIRED: | 706 | case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: |
| 698 | case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: | 707 | logi_dj_recv_queue_notification(djrcv_dev, dj_report); |
| 699 | logi_dj_recv_queue_notification(djrcv_dev, dj_report); | 708 | break; |
| 700 | break; | 709 | case REPORT_TYPE_NOTIF_CONNECTION_STATUS: |
| 701 | case REPORT_TYPE_NOTIF_CONNECTION_STATUS: | 710 | if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == |
| 702 | if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == | 711 | STATUS_LINKLOSS) { |
| 703 | STATUS_LINKLOSS) { | 712 | logi_dj_recv_forward_null_report(djrcv_dev, dj_report); |
| 704 | logi_dj_recv_forward_null_report(djrcv_dev, dj_report); | ||
| 705 | } | ||
| 706 | break; | ||
| 707 | default: | ||
| 708 | logi_dj_recv_forward_report(djrcv_dev, dj_report); | ||
| 709 | } | 713 | } |
| 710 | report_processed = true; | 714 | break; |
| 715 | default: | ||
| 716 | logi_dj_recv_forward_report(djrcv_dev, dj_report); | ||
| 711 | } | 717 | } |
| 712 | spin_unlock_irqrestore(&djrcv_dev->lock, flags); | 718 | spin_unlock_irqrestore(&djrcv_dev->lock, flags); |
| 713 | 719 | ||
| 714 | return report_processed; | 720 | return true; |
| 715 | } | 721 | } |
| 716 | 722 | ||
| 717 | static int logi_dj_probe(struct hid_device *hdev, | 723 | static int logi_dj_probe(struct hid_device *hdev, |
diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h index 4a4000340ce1..daeb0aa4bee9 100644 --- a/drivers/hid/hid-logitech-dj.h +++ b/drivers/hid/hid-logitech-dj.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #define DJ_MAX_PAIRED_DEVICES 6 | 28 | #define DJ_MAX_PAIRED_DEVICES 6 |
| 29 | #define DJ_MAX_NUMBER_NOTIFICATIONS 8 | 29 | #define DJ_MAX_NUMBER_NOTIFICATIONS 8 |
| 30 | #define DJ_RECEIVER_INDEX 0 | ||
| 30 | #define DJ_DEVICE_INDEX_MIN 1 | 31 | #define DJ_DEVICE_INDEX_MIN 1 |
| 31 | #define DJ_DEVICE_INDEX_MAX 6 | 32 | #define DJ_DEVICE_INDEX_MAX 6 |
| 32 | 33 | ||
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index ecc2cbf300cc..29a74c1efcb8 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
| @@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, | |||
| 290 | if (size < 4 || ((size - 4) % 9) != 0) | 290 | if (size < 4 || ((size - 4) % 9) != 0) |
| 291 | return 0; | 291 | return 0; |
| 292 | npoints = (size - 4) / 9; | 292 | npoints = (size - 4) / 9; |
| 293 | if (npoints > 15) { | ||
| 294 | hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", | ||
| 295 | size); | ||
| 296 | return 0; | ||
| 297 | } | ||
| 293 | msc->ntouches = 0; | 298 | msc->ntouches = 0; |
| 294 | for (ii = 0; ii < npoints; ii++) | 299 | for (ii = 0; ii < npoints; ii++) |
| 295 | magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); | 300 | magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); |
| @@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, | |||
| 307 | if (size < 6 || ((size - 6) % 8) != 0) | 312 | if (size < 6 || ((size - 6) % 8) != 0) |
| 308 | return 0; | 313 | return 0; |
| 309 | npoints = (size - 6) / 8; | 314 | npoints = (size - 6) / 8; |
| 315 | if (npoints > 15) { | ||
| 316 | hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", | ||
| 317 | size); | ||
| 318 | return 0; | ||
| 319 | } | ||
| 310 | msc->ntouches = 0; | 320 | msc->ntouches = 0; |
| 311 | for (ii = 0; ii < npoints; ii++) | 321 | for (ii = 0; ii < npoints; ii++) |
| 312 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); | 322 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); |
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index 9e14c00eb1b6..25daf28b26bd 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
| 26 | { | 26 | { |
| 27 | if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | 27 | if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { |
| 28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); | 28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); |
| 29 | rdesc[30] = 0x0c; | 29 | rdesc[30] = 0x0c; |
| 30 | } | 30 | } |
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 736b2502df4f..6aca4f2554bf 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 26 | unsigned int *rsize) | 26 | unsigned int *rsize) |
| 27 | { | 27 | { |
| 28 | if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | 28 | if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && |
| 29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && | 29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && |
| 30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { | 30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { |
| 31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); | 31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); |
diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index acbb021065ec..020df3c2e8b4 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c | |||
| @@ -350,6 +350,12 @@ static int picolcd_raw_event(struct hid_device *hdev, | |||
| 350 | if (!data) | 350 | if (!data) |
| 351 | return 1; | 351 | return 1; |
| 352 | 352 | ||
| 353 | if (size > 64) { | ||
| 354 | hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n", | ||
| 355 | size); | ||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 353 | if (report->id == REPORT_KEY_STATE) { | 359 | if (report->id == REPORT_KEY_STATE) { |
| 354 | if (data->input_keys) | 360 | if (data->input_keys) |
| 355 | ret = picolcd_raw_keypad(data, report, raw_data+1, size-1); | 361 | ret = picolcd_raw_keypad(data, report, raw_data+1, size-1); |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 0dc25142f451..8389e8109218 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -909,10 +909,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 909 | return ret; | 909 | return ret; |
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | if (!test_bit(RMI_STARTED, &data->flags)) { | 912 | if (!test_bit(RMI_STARTED, &data->flags)) |
| 913 | hid_hw_stop(hdev); | 913 | /* |
| 914 | return -EIO; | 914 | * The device maybe in the bootloader if rmi_input_configured |
| 915 | } | 915 | * failed to find F11 in the PDT. Print an error, but don't |
| 916 | * return an error from rmi_probe so that hidraw will be | ||
| 917 | * accessible from userspace. That way a userspace tool | ||
| 918 | * can be used to reload working firmware on the touchpad. | ||
| 919 | */ | ||
| 920 | hid_err(hdev, "Device failed to be properly configured\n"); | ||
| 916 | 921 | ||
| 917 | return 0; | 922 | return 0; |
| 918 | } | 923 | } |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index e244e449cbba..2ac25760a9a9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -604,9 +604,9 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 604 | ret = -EINVAL; | 604 | ret = -EINVAL; |
| 605 | goto err_stop_hw; | 605 | goto err_stop_hw; |
| 606 | } | 606 | } |
| 607 | sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * | 607 | sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * |
| 608 | sizeof(struct mfd_cell), | 608 | sizeof(struct mfd_cell), |
| 609 | GFP_KERNEL); | 609 | GFP_KERNEL); |
| 610 | if (sd->hid_sensor_hub_client_devs == NULL) { | 610 | if (sd->hid_sensor_hub_client_devs == NULL) { |
| 611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); | 611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); |
| 612 | ret = -ENOMEM; | 612 | ret = -ENOMEM; |
| @@ -618,11 +618,12 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 618 | 618 | ||
| 619 | if (collection->type == HID_COLLECTION_PHYSICAL) { | 619 | if (collection->type == HID_COLLECTION_PHYSICAL) { |
| 620 | 620 | ||
| 621 | hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); | 621 | hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), |
| 622 | GFP_KERNEL); | ||
| 622 | if (!hsdev) { | 623 | if (!hsdev) { |
| 623 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); | 624 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); |
| 624 | ret = -ENOMEM; | 625 | ret = -ENOMEM; |
| 625 | goto err_no_mem; | 626 | goto err_stop_hw; |
| 626 | } | 627 | } |
| 627 | hsdev->hdev = hdev; | 628 | hsdev->hdev = hdev; |
| 628 | hsdev->vendor_id = hdev->vendor; | 629 | hsdev->vendor_id = hdev->vendor; |
| @@ -631,13 +632,13 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 631 | if (last_hsdev) | 632 | if (last_hsdev) |
| 632 | last_hsdev->end_collection_index = i; | 633 | last_hsdev->end_collection_index = i; |
| 633 | last_hsdev = hsdev; | 634 | last_hsdev = hsdev; |
| 634 | name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", | 635 | name = devm_kasprintf(&hdev->dev, GFP_KERNEL, |
| 635 | collection->usage); | 636 | "HID-SENSOR-%x", |
| 637 | collection->usage); | ||
| 636 | if (name == NULL) { | 638 | if (name == NULL) { |
| 637 | hid_err(hdev, "Failed MFD device name\n"); | 639 | hid_err(hdev, "Failed MFD device name\n"); |
| 638 | ret = -ENOMEM; | 640 | ret = -ENOMEM; |
| 639 | kfree(hsdev); | 641 | goto err_stop_hw; |
| 640 | goto err_no_mem; | ||
| 641 | } | 642 | } |
| 642 | sd->hid_sensor_hub_client_devs[ | 643 | sd->hid_sensor_hub_client_devs[ |
| 643 | sd->hid_sensor_client_cnt].id = | 644 | sd->hid_sensor_client_cnt].id = |
| @@ -661,16 +662,10 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 661 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, | 662 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, |
| 662 | sd->hid_sensor_client_cnt, NULL, 0, NULL); | 663 | sd->hid_sensor_client_cnt, NULL, 0, NULL); |
| 663 | if (ret < 0) | 664 | if (ret < 0) |
| 664 | goto err_no_mem; | 665 | goto err_stop_hw; |
| 665 | 666 | ||
| 666 | return ret; | 667 | return ret; |
| 667 | 668 | ||
| 668 | err_no_mem: | ||
| 669 | for (i = 0; i < sd->hid_sensor_client_cnt; ++i) { | ||
| 670 | kfree(sd->hid_sensor_hub_client_devs[i].name); | ||
| 671 | kfree(sd->hid_sensor_hub_client_devs[i].platform_data); | ||
| 672 | } | ||
| 673 | kfree(sd->hid_sensor_hub_client_devs); | ||
| 674 | err_stop_hw: | 669 | err_stop_hw: |
| 675 | hid_hw_stop(hdev); | 670 | hid_hw_stop(hdev); |
| 676 | 671 | ||
| @@ -681,7 +676,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 681 | { | 676 | { |
| 682 | struct sensor_hub_data *data = hid_get_drvdata(hdev); | 677 | struct sensor_hub_data *data = hid_get_drvdata(hdev); |
| 683 | unsigned long flags; | 678 | unsigned long flags; |
| 684 | int i; | ||
| 685 | 679 | ||
| 686 | hid_dbg(hdev, " hardware removed\n"); | 680 | hid_dbg(hdev, " hardware removed\n"); |
| 687 | hid_hw_close(hdev); | 681 | hid_hw_close(hdev); |
| @@ -691,11 +685,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 691 | complete(&data->pending.ready); | 685 | complete(&data->pending.ready); |
| 692 | spin_unlock_irqrestore(&data->lock, flags); | 686 | spin_unlock_irqrestore(&data->lock, flags); |
| 693 | mfd_remove_devices(&hdev->dev); | 687 | mfd_remove_devices(&hdev->dev); |
| 694 | for (i = 0; i < data->hid_sensor_client_cnt; ++i) { | ||
| 695 | kfree(data->hid_sensor_hub_client_devs[i].name); | ||
| 696 | kfree(data->hid_sensor_hub_client_devs[i].platform_data); | ||
| 697 | } | ||
| 698 | kfree(data->hid_sensor_hub_client_devs); | ||
| 699 | hid_set_drvdata(hdev, NULL); | 688 | hid_set_drvdata(hdev, NULL); |
| 700 | mutex_destroy(&data->mutex); | 689 | mutex_destroy(&data->mutex); |
| 701 | } | 690 | } |
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 87fc91e1c8de..91072fa54663 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
| 26 | { | 26 | { |
| 27 | if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | 27 | if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && |
| 28 | rdesc[106] == 0x03) { | 28 | rdesc[106] == 0x03) { |
| 29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); | 29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); |
| 30 | rdesc[105] = rdesc[110] = 0x03; | 30 | rdesc[105] = rdesc[110] = 0x03; |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index fc6f5d54e7f7..8890870309e4 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
| @@ -309,6 +309,7 @@ static ssize_t set_convrate(struct device *dev, struct device_attribute *da, | |||
| 309 | data->conf |= (resol << DS1621_REG_CONFIG_RESOL_SHIFT); | 309 | data->conf |= (resol << DS1621_REG_CONFIG_RESOL_SHIFT); |
| 310 | i2c_smbus_write_byte_data(client, DS1621_REG_CONF, data->conf); | 310 | i2c_smbus_write_byte_data(client, DS1621_REG_CONF, data->conf); |
| 311 | data->update_interval = ds1721_convrates[resol]; | 311 | data->update_interval = ds1721_convrates[resol]; |
| 312 | data->zbits = 7 - resol; | ||
| 312 | mutex_unlock(&data->update_lock); | 313 | mutex_unlock(&data->update_lock); |
| 313 | 314 | ||
| 314 | return count; | 315 | return count; |
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 3e3b680dc007..b51a402752c4 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig | |||
| @@ -23,17 +23,14 @@ config I2C | |||
| 23 | This I2C support can also be built as a module. If so, the module | 23 | This I2C support can also be built as a module. If so, the module |
| 24 | will be called i2c-core. | 24 | will be called i2c-core. |
| 25 | 25 | ||
| 26 | config I2C_ACPI | 26 | config ACPI_I2C_OPREGION |
| 27 | bool "I2C ACPI support" | 27 | bool "ACPI I2C Operation region support" |
| 28 | select I2C | 28 | depends on I2C=y && ACPI |
| 29 | depends on ACPI | ||
| 30 | default y | 29 | default y |
| 31 | help | 30 | help |
| 32 | Say Y here if you want to enable ACPI I2C support. This includes support | 31 | Say Y here if you want to enable ACPI I2C operation region support. |
| 33 | for automatic enumeration of I2C slave devices and support for ACPI I2C | 32 | Operation Regions allow firmware (BIOS) code to access I2C slave devices, |
| 34 | Operation Regions. Operation Regions allow firmware (BIOS) code to | 33 | such as smart batteries through an I2C host controller driver. |
| 35 | access I2C slave devices, such as smart batteries through an I2C host | ||
| 36 | controller driver. | ||
| 37 | 34 | ||
| 38 | if I2C | 35 | if I2C |
| 39 | 36 | ||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index a1f590cbb435..e0228b228256 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | i2ccore-y := i2c-core.o | 5 | i2ccore-y := i2c-core.o |
| 6 | i2ccore-$(CONFIG_I2C_ACPI) += i2c-acpi.o | 6 | i2ccore-$(CONFIG_ACPI) += i2c-acpi.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o | 8 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o |
| 9 | obj-$(CONFIG_I2C) += i2ccore.o | 9 | obj-$(CONFIG_I2C) += i2ccore.o |
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 79a68999a696..917d54588d95 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c | |||
| @@ -101,6 +101,7 @@ struct at91_twi_dev { | |||
| 101 | unsigned twi_cwgr_reg; | 101 | unsigned twi_cwgr_reg; |
| 102 | struct at91_twi_pdata *pdata; | 102 | struct at91_twi_pdata *pdata; |
| 103 | bool use_dma; | 103 | bool use_dma; |
| 104 | bool recv_len_abort; | ||
| 104 | struct at91_twi_dma dma; | 105 | struct at91_twi_dma dma; |
| 105 | }; | 106 | }; |
| 106 | 107 | ||
| @@ -267,12 +268,24 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev) | |||
| 267 | *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; | 268 | *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; |
| 268 | --dev->buf_len; | 269 | --dev->buf_len; |
| 269 | 270 | ||
| 271 | /* return if aborting, we only needed to read RHR to clear RXRDY*/ | ||
| 272 | if (dev->recv_len_abort) | ||
| 273 | return; | ||
| 274 | |||
| 270 | /* handle I2C_SMBUS_BLOCK_DATA */ | 275 | /* handle I2C_SMBUS_BLOCK_DATA */ |
| 271 | if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { | 276 | if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { |
| 272 | dev->msg->flags &= ~I2C_M_RECV_LEN; | 277 | /* ensure length byte is a valid value */ |
| 273 | dev->buf_len += *dev->buf; | 278 | if (*dev->buf <= I2C_SMBUS_BLOCK_MAX && *dev->buf > 0) { |
| 274 | dev->msg->len = dev->buf_len + 1; | 279 | dev->msg->flags &= ~I2C_M_RECV_LEN; |
| 275 | dev_dbg(dev->dev, "received block length %d\n", dev->buf_len); | 280 | dev->buf_len += *dev->buf; |
| 281 | dev->msg->len = dev->buf_len + 1; | ||
| 282 | dev_dbg(dev->dev, "received block length %d\n", | ||
| 283 | dev->buf_len); | ||
| 284 | } else { | ||
| 285 | /* abort and send the stop by reading one more byte */ | ||
| 286 | dev->recv_len_abort = true; | ||
| 287 | dev->buf_len = 1; | ||
| 288 | } | ||
| 276 | } | 289 | } |
| 277 | 290 | ||
| 278 | /* send stop if second but last byte has been read */ | 291 | /* send stop if second but last byte has been read */ |
| @@ -421,8 +434,8 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) | |||
| 421 | } | 434 | } |
| 422 | } | 435 | } |
| 423 | 436 | ||
| 424 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 437 | ret = wait_for_completion_io_timeout(&dev->cmd_complete, |
| 425 | dev->adapter.timeout); | 438 | dev->adapter.timeout); |
| 426 | if (ret == 0) { | 439 | if (ret == 0) { |
| 427 | dev_err(dev->dev, "controller timed out\n"); | 440 | dev_err(dev->dev, "controller timed out\n"); |
| 428 | at91_init_twi_bus(dev); | 441 | at91_init_twi_bus(dev); |
| @@ -444,6 +457,12 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) | |||
| 444 | ret = -EIO; | 457 | ret = -EIO; |
| 445 | goto error; | 458 | goto error; |
| 446 | } | 459 | } |
| 460 | if (dev->recv_len_abort) { | ||
| 461 | dev_err(dev->dev, "invalid smbus block length recvd\n"); | ||
| 462 | ret = -EPROTO; | ||
| 463 | goto error; | ||
| 464 | } | ||
| 465 | |||
| 447 | dev_dbg(dev->dev, "transfer complete\n"); | 466 | dev_dbg(dev->dev, "transfer complete\n"); |
| 448 | 467 | ||
| 449 | return 0; | 468 | return 0; |
| @@ -500,6 +519,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) | |||
| 500 | dev->buf_len = m_start->len; | 519 | dev->buf_len = m_start->len; |
| 501 | dev->buf = m_start->buf; | 520 | dev->buf = m_start->buf; |
| 502 | dev->msg = m_start; | 521 | dev->msg = m_start; |
| 522 | dev->recv_len_abort = false; | ||
| 503 | 523 | ||
| 504 | ret = at91_do_twi_transfer(dev); | 524 | ret = at91_do_twi_transfer(dev); |
| 505 | 525 | ||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 2994690b26e9..10467a327749 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -164,6 +164,7 @@ | |||
| 164 | 164 | ||
| 165 | /* Older devices have their ID defined in <linux/pci_ids.h> */ | 165 | /* Older devices have their ID defined in <linux/pci_ids.h> */ |
| 166 | #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 | 166 | #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 |
| 167 | #define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 | ||
| 167 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 | 168 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 |
| 168 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 | 169 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 |
| 169 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ | 170 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ |
| @@ -828,6 +829,7 @@ static const struct pci_device_id i801_ids[] = { | |||
| 828 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, | 829 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, |
| 829 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, | 830 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, |
| 830 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, | 831 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, |
| 832 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, | ||
| 831 | { 0, } | 833 | { 0, } |
| 832 | }; | 834 | }; |
| 833 | 835 | ||
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 6dc5ded86f62..2f64273d3f2b 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
| @@ -746,8 +746,7 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, | |||
| 746 | } | 746 | } |
| 747 | tclk = clk_get_rate(drv_data->clk); | 747 | tclk = clk_get_rate(drv_data->clk); |
| 748 | 748 | ||
| 749 | rc = of_property_read_u32(np, "clock-frequency", &bus_freq); | 749 | if (of_property_read_u32(np, "clock-frequency", &bus_freq)) |
| 750 | if (rc) | ||
| 751 | bus_freq = 100000; /* 100kHz by default */ | 750 | bus_freq = 100000; /* 100kHz by default */ |
| 752 | 751 | ||
| 753 | if (!mv64xxx_find_baud_factors(bus_freq, tclk, | 752 | if (!mv64xxx_find_baud_factors(bus_freq, tclk, |
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index f3c7139dfa25..1cc146cfc1f3 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 35 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/spinlock.h> | ||
| 37 | 38 | ||
| 38 | /* register offsets */ | 39 | /* register offsets */ |
| 39 | #define ICSCR 0x00 /* slave ctrl */ | 40 | #define ICSCR 0x00 /* slave ctrl */ |
| @@ -95,6 +96,7 @@ struct rcar_i2c_priv { | |||
| 95 | struct i2c_msg *msg; | 96 | struct i2c_msg *msg; |
| 96 | struct clk *clk; | 97 | struct clk *clk; |
| 97 | 98 | ||
| 99 | spinlock_t lock; | ||
| 98 | wait_queue_head_t wait; | 100 | wait_queue_head_t wait; |
| 99 | 101 | ||
| 100 | int pos; | 102 | int pos; |
| @@ -365,20 +367,20 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) | |||
| 365 | struct rcar_i2c_priv *priv = ptr; | 367 | struct rcar_i2c_priv *priv = ptr; |
| 366 | u32 msr; | 368 | u32 msr; |
| 367 | 369 | ||
| 370 | /*-------------- spin lock -----------------*/ | ||
| 371 | spin_lock(&priv->lock); | ||
| 372 | |||
| 368 | msr = rcar_i2c_read(priv, ICMSR); | 373 | msr = rcar_i2c_read(priv, ICMSR); |
| 369 | 374 | ||
| 375 | /* Only handle interrupts that are currently enabled */ | ||
| 376 | msr &= rcar_i2c_read(priv, ICMIER); | ||
| 377 | |||
| 370 | /* Arbitration lost */ | 378 | /* Arbitration lost */ |
| 371 | if (msr & MAL) { | 379 | if (msr & MAL) { |
| 372 | rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); | 380 | rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); |
| 373 | goto out; | 381 | goto out; |
| 374 | } | 382 | } |
| 375 | 383 | ||
| 376 | /* Stop */ | ||
| 377 | if (msr & MST) { | ||
| 378 | rcar_i2c_flags_set(priv, ID_DONE); | ||
| 379 | goto out; | ||
| 380 | } | ||
| 381 | |||
| 382 | /* Nack */ | 384 | /* Nack */ |
| 383 | if (msr & MNR) { | 385 | if (msr & MNR) { |
| 384 | /* go to stop phase */ | 386 | /* go to stop phase */ |
| @@ -388,6 +390,12 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) | |||
| 388 | goto out; | 390 | goto out; |
| 389 | } | 391 | } |
| 390 | 392 | ||
| 393 | /* Stop */ | ||
| 394 | if (msr & MST) { | ||
| 395 | rcar_i2c_flags_set(priv, ID_DONE); | ||
| 396 | goto out; | ||
| 397 | } | ||
| 398 | |||
| 391 | if (rcar_i2c_is_recv(priv)) | 399 | if (rcar_i2c_is_recv(priv)) |
| 392 | rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); | 400 | rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); |
| 393 | else | 401 | else |
| @@ -400,6 +408,9 @@ out: | |||
| 400 | wake_up(&priv->wait); | 408 | wake_up(&priv->wait); |
| 401 | } | 409 | } |
| 402 | 410 | ||
| 411 | spin_unlock(&priv->lock); | ||
| 412 | /*-------------- spin unlock -----------------*/ | ||
| 413 | |||
| 403 | return IRQ_HANDLED; | 414 | return IRQ_HANDLED; |
| 404 | } | 415 | } |
| 405 | 416 | ||
| @@ -409,14 +420,21 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, | |||
| 409 | { | 420 | { |
| 410 | struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); | 421 | struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); |
| 411 | struct device *dev = rcar_i2c_priv_to_dev(priv); | 422 | struct device *dev = rcar_i2c_priv_to_dev(priv); |
| 423 | unsigned long flags; | ||
| 412 | int i, ret, timeout; | 424 | int i, ret, timeout; |
| 413 | 425 | ||
| 414 | pm_runtime_get_sync(dev); | 426 | pm_runtime_get_sync(dev); |
| 415 | 427 | ||
| 428 | /*-------------- spin lock -----------------*/ | ||
| 429 | spin_lock_irqsave(&priv->lock, flags); | ||
| 430 | |||
| 416 | rcar_i2c_init(priv); | 431 | rcar_i2c_init(priv); |
| 417 | /* start clock */ | 432 | /* start clock */ |
| 418 | rcar_i2c_write(priv, ICCCR, priv->icccr); | 433 | rcar_i2c_write(priv, ICCCR, priv->icccr); |
| 419 | 434 | ||
| 435 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 436 | /*-------------- spin unlock -----------------*/ | ||
| 437 | |||
| 420 | ret = rcar_i2c_bus_barrier(priv); | 438 | ret = rcar_i2c_bus_barrier(priv); |
| 421 | if (ret < 0) | 439 | if (ret < 0) |
| 422 | goto out; | 440 | goto out; |
| @@ -428,6 +446,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, | |||
| 428 | break; | 446 | break; |
| 429 | } | 447 | } |
| 430 | 448 | ||
| 449 | /*-------------- spin lock -----------------*/ | ||
| 450 | spin_lock_irqsave(&priv->lock, flags); | ||
| 451 | |||
| 431 | /* init each data */ | 452 | /* init each data */ |
| 432 | priv->msg = &msgs[i]; | 453 | priv->msg = &msgs[i]; |
| 433 | priv->pos = 0; | 454 | priv->pos = 0; |
| @@ -437,6 +458,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, | |||
| 437 | 458 | ||
| 438 | ret = rcar_i2c_prepare_msg(priv); | 459 | ret = rcar_i2c_prepare_msg(priv); |
| 439 | 460 | ||
| 461 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 462 | /*-------------- spin unlock -----------------*/ | ||
| 463 | |||
| 440 | if (ret < 0) | 464 | if (ret < 0) |
| 441 | break; | 465 | break; |
| 442 | 466 | ||
| @@ -540,6 +564,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) | |||
| 540 | 564 | ||
| 541 | irq = platform_get_irq(pdev, 0); | 565 | irq = platform_get_irq(pdev, 0); |
| 542 | init_waitqueue_head(&priv->wait); | 566 | init_waitqueue_head(&priv->wait); |
| 567 | spin_lock_init(&priv->lock); | ||
| 543 | 568 | ||
| 544 | adap = &priv->adap; | 569 | adap = &priv->adap; |
| 545 | adap->nr = pdev->id; | 570 | adap->nr = pdev->id; |
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index 69e11853e8bf..e637c32ae517 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c | |||
| @@ -323,6 +323,10 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) | |||
| 323 | /* ack interrupt */ | 323 | /* ack interrupt */ |
| 324 | i2c_writel(i2c, REG_INT_MBRF, REG_IPD); | 324 | i2c_writel(i2c, REG_INT_MBRF, REG_IPD); |
| 325 | 325 | ||
| 326 | /* Can only handle a maximum of 32 bytes at a time */ | ||
| 327 | if (len > 32) | ||
| 328 | len = 32; | ||
| 329 | |||
| 326 | /* read the data from receive buffer */ | 330 | /* read the data from receive buffer */ |
| 327 | for (i = 0; i < len; ++i) { | 331 | for (i = 0; i < len; ++i) { |
| 328 | if (i % 4 == 0) | 332 | if (i % 4 == 0) |
diff --git a/drivers/i2c/i2c-acpi.c b/drivers/i2c/i2c-acpi.c index e8b61967334b..0dbc18c15c43 100644 --- a/drivers/i2c/i2c-acpi.c +++ b/drivers/i2c/i2c-acpi.c | |||
| @@ -126,6 +126,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adap) | |||
| 126 | dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); | 126 | dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | #ifdef CONFIG_ACPI_I2C_OPREGION | ||
| 129 | static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, | 130 | static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, |
| 130 | u8 cmd, u8 *data, u8 data_len) | 131 | u8 cmd, u8 *data, u8 data_len) |
| 131 | { | 132 | { |
| @@ -360,3 +361,4 @@ void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter) | |||
| 360 | 361 | ||
| 361 | acpi_bus_detach_private_data(handle); | 362 | acpi_bus_detach_private_data(handle); |
| 362 | } | 363 | } |
| 364 | #endif | ||
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index e1e558a3d692..af8256353c7d 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -1089,6 +1089,30 @@ static int __mlx4_ib_destroy_flow(struct mlx4_dev *dev, u64 reg_id) | |||
| 1089 | return err; | 1089 | return err; |
| 1090 | } | 1090 | } |
| 1091 | 1091 | ||
| 1092 | static int mlx4_ib_tunnel_steer_add(struct ib_qp *qp, struct ib_flow_attr *flow_attr, | ||
| 1093 | u64 *reg_id) | ||
| 1094 | { | ||
| 1095 | void *ib_flow; | ||
| 1096 | union ib_flow_spec *ib_spec; | ||
| 1097 | struct mlx4_dev *dev = to_mdev(qp->device)->dev; | ||
| 1098 | int err = 0; | ||
| 1099 | |||
| 1100 | if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) | ||
| 1101 | return 0; /* do nothing */ | ||
| 1102 | |||
| 1103 | ib_flow = flow_attr + 1; | ||
| 1104 | ib_spec = (union ib_flow_spec *)ib_flow; | ||
| 1105 | |||
| 1106 | if (ib_spec->type != IB_FLOW_SPEC_ETH || flow_attr->num_of_specs != 1) | ||
| 1107 | return 0; /* do nothing */ | ||
| 1108 | |||
| 1109 | err = mlx4_tunnel_steer_add(to_mdev(qp->device)->dev, ib_spec->eth.val.dst_mac, | ||
| 1110 | flow_attr->port, qp->qp_num, | ||
| 1111 | MLX4_DOMAIN_UVERBS | (flow_attr->priority & 0xff), | ||
| 1112 | reg_id); | ||
| 1113 | return err; | ||
| 1114 | } | ||
| 1115 | |||
| 1092 | static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, | 1116 | static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, |
| 1093 | struct ib_flow_attr *flow_attr, | 1117 | struct ib_flow_attr *flow_attr, |
| 1094 | int domain) | 1118 | int domain) |
| @@ -1136,6 +1160,12 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, | |||
| 1136 | i++; | 1160 | i++; |
| 1137 | } | 1161 | } |
| 1138 | 1162 | ||
| 1163 | if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) { | ||
| 1164 | err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]); | ||
| 1165 | if (err) | ||
| 1166 | goto err_free; | ||
| 1167 | } | ||
| 1168 | |||
| 1139 | return &mflow->ibflow; | 1169 | return &mflow->ibflow; |
| 1140 | 1170 | ||
| 1141 | err_free: | 1171 | err_free: |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 67780452f0cf..efb9eff8906c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -1677,9 +1677,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1677 | } | 1677 | } |
| 1678 | } | 1678 | } |
| 1679 | 1679 | ||
| 1680 | if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) | 1680 | if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) { |
| 1681 | context->pri_path.ackto = (context->pri_path.ackto & 0xf8) | | 1681 | context->pri_path.ackto = (context->pri_path.ackto & 0xf8) | |
| 1682 | MLX4_IB_LINK_TYPE_ETH; | 1682 | MLX4_IB_LINK_TYPE_ETH; |
| 1683 | if (dev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) { | ||
| 1684 | /* set QP to receive both tunneled & non-tunneled packets */ | ||
| 1685 | if (!(context->flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET))) | ||
| 1686 | context->srqn = cpu_to_be32(7 << 28); | ||
| 1687 | } | ||
| 1688 | } | ||
| 1683 | 1689 | ||
| 1684 | if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) { | 1690 | if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) { |
| 1685 | int is_eth = rdma_port_get_link_layer( | 1691 | int is_eth = rdma_port_get_link_layer( |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c30204f2fa30..fbe29fcb15c5 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
| @@ -236,6 +236,18 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | |||
| 236 | } | 236 | } |
| 237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | 237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); |
| 238 | 238 | ||
| 239 | static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt) | ||
| 240 | { | ||
| 241 | int i; | ||
| 242 | |||
| 243 | for (i = 0; i < mt->num_slots; i++) { | ||
| 244 | if (!input_mt_is_used(mt, &mt->slots[i])) { | ||
| 245 | input_mt_slot(dev, i); | ||
| 246 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
| 247 | } | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 239 | /** | 251 | /** |
| 240 | * input_mt_drop_unused() - Inactivate slots not seen in this frame | 252 | * input_mt_drop_unused() - Inactivate slots not seen in this frame |
| 241 | * @dev: input device with allocated MT slots | 253 | * @dev: input device with allocated MT slots |
| @@ -245,19 +257,11 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation); | |||
| 245 | void input_mt_drop_unused(struct input_dev *dev) | 257 | void input_mt_drop_unused(struct input_dev *dev) |
| 246 | { | 258 | { |
| 247 | struct input_mt *mt = dev->mt; | 259 | struct input_mt *mt = dev->mt; |
| 248 | int i; | ||
| 249 | 260 | ||
| 250 | if (!mt) | 261 | if (mt) { |
| 251 | return; | 262 | __input_mt_drop_unused(dev, mt); |
| 252 | 263 | mt->frame++; | |
| 253 | for (i = 0; i < mt->num_slots; i++) { | ||
| 254 | if (!input_mt_is_used(mt, &mt->slots[i])) { | ||
| 255 | input_mt_slot(dev, i); | ||
| 256 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
| 257 | } | ||
| 258 | } | 264 | } |
| 259 | |||
| 260 | mt->frame++; | ||
| 261 | } | 265 | } |
| 262 | EXPORT_SYMBOL(input_mt_drop_unused); | 266 | EXPORT_SYMBOL(input_mt_drop_unused); |
| 263 | 267 | ||
| @@ -278,12 +282,14 @@ void input_mt_sync_frame(struct input_dev *dev) | |||
| 278 | return; | 282 | return; |
| 279 | 283 | ||
| 280 | if (mt->flags & INPUT_MT_DROP_UNUSED) | 284 | if (mt->flags & INPUT_MT_DROP_UNUSED) |
| 281 | input_mt_drop_unused(dev); | 285 | __input_mt_drop_unused(dev, mt); |
| 282 | 286 | ||
| 283 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) | 287 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) |
| 284 | use_count = true; | 288 | use_count = true; |
| 285 | 289 | ||
| 286 | input_mt_report_pointer_emulation(dev, use_count); | 290 | input_mt_report_pointer_emulation(dev, use_count); |
| 291 | |||
| 292 | mt->frame++; | ||
| 287 | } | 293 | } |
| 288 | EXPORT_SYMBOL(input_mt_sync_frame); | 294 | EXPORT_SYMBOL(input_mt_sync_frame); |
| 289 | 295 | ||
diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c index 180b184ab90f..d70b65a14ced 100644 --- a/drivers/input/keyboard/cap1106.c +++ b/drivers/input/keyboard/cap1106.c | |||
| @@ -33,8 +33,8 @@ | |||
| 33 | #define CAP1106_REG_SENSOR_CONFIG 0x22 | 33 | #define CAP1106_REG_SENSOR_CONFIG 0x22 |
| 34 | #define CAP1106_REG_SENSOR_CONFIG2 0x23 | 34 | #define CAP1106_REG_SENSOR_CONFIG2 0x23 |
| 35 | #define CAP1106_REG_SAMPLING_CONFIG 0x24 | 35 | #define CAP1106_REG_SAMPLING_CONFIG 0x24 |
| 36 | #define CAP1106_REG_CALIBRATION 0x25 | 36 | #define CAP1106_REG_CALIBRATION 0x26 |
| 37 | #define CAP1106_REG_INT_ENABLE 0x26 | 37 | #define CAP1106_REG_INT_ENABLE 0x27 |
| 38 | #define CAP1106_REG_REPEAT_RATE 0x28 | 38 | #define CAP1106_REG_REPEAT_RATE 0x28 |
| 39 | #define CAP1106_REG_MT_CONFIG 0x2a | 39 | #define CAP1106_REG_MT_CONFIG 0x2a |
| 40 | #define CAP1106_REG_MT_PATTERN_CONFIG 0x2b | 40 | #define CAP1106_REG_MT_PATTERN_CONFIG 0x2b |
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 8d2e19e81e1e..e651fa692afe 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
| @@ -332,23 +332,24 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, | |||
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | if (pdata->clustered_irq > 0) { | 334 | if (pdata->clustered_irq > 0) { |
| 335 | err = request_irq(pdata->clustered_irq, | 335 | err = request_any_context_irq(pdata->clustered_irq, |
| 336 | matrix_keypad_interrupt, | 336 | matrix_keypad_interrupt, |
| 337 | pdata->clustered_irq_flags, | 337 | pdata->clustered_irq_flags, |
| 338 | "matrix-keypad", keypad); | 338 | "matrix-keypad", keypad); |
| 339 | if (err) { | 339 | if (err < 0) { |
| 340 | dev_err(&pdev->dev, | 340 | dev_err(&pdev->dev, |
| 341 | "Unable to acquire clustered interrupt\n"); | 341 | "Unable to acquire clustered interrupt\n"); |
| 342 | goto err_free_rows; | 342 | goto err_free_rows; |
| 343 | } | 343 | } |
| 344 | } else { | 344 | } else { |
| 345 | for (i = 0; i < pdata->num_row_gpios; i++) { | 345 | for (i = 0; i < pdata->num_row_gpios; i++) { |
| 346 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | 346 | err = request_any_context_irq( |
| 347 | gpio_to_irq(pdata->row_gpios[i]), | ||
| 347 | matrix_keypad_interrupt, | 348 | matrix_keypad_interrupt, |
| 348 | IRQF_TRIGGER_RISING | | 349 | IRQF_TRIGGER_RISING | |
| 349 | IRQF_TRIGGER_FALLING, | 350 | IRQF_TRIGGER_FALLING, |
| 350 | "matrix-keypad", keypad); | 351 | "matrix-keypad", keypad); |
| 351 | if (err) { | 352 | if (err < 0) { |
| 352 | dev_err(&pdev->dev, | 353 | dev_err(&pdev->dev, |
| 353 | "Unable to acquire interrupt for GPIO line %i\n", | 354 | "Unable to acquire interrupt for GPIO line %i\n", |
| 354 | pdata->row_gpios[i]); | 355 | pdata->row_gpios[i]); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a59a1a64b674..35a49bf57227 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -2234,8 +2234,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
| 2234 | return 0; | 2234 | return 0; |
| 2235 | } | 2235 | } |
| 2236 | 2236 | ||
| 2237 | psmouse_info(psmouse, | 2237 | psmouse_dbg(psmouse, |
| 2238 | "Unknown ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); | 2238 | "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); |
| 2239 | 2239 | ||
| 2240 | return -EINVAL; | 2240 | return -EINVAL; |
| 2241 | } | 2241 | } |
| @@ -2373,6 +2373,10 @@ int alps_init(struct psmouse *psmouse) | |||
| 2373 | dev2->keybit[BIT_WORD(BTN_LEFT)] = | 2373 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
| 2374 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 2374 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
| 2375 | 2375 | ||
| 2376 | __set_bit(INPUT_PROP_POINTER, dev2->propbit); | ||
| 2377 | if (priv->flags & ALPS_DUALPOINT) | ||
| 2378 | __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); | ||
| 2379 | |||
| 2376 | if (input_register_device(priv->dev2)) | 2380 | if (input_register_device(priv->dev2)) |
| 2377 | goto init_fail; | 2381 | goto init_fail; |
| 2378 | 2382 | ||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ee2a04d90d20..06fc6e76ffbe 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/input/mt.h> | 18 | #include <linux/input/mt.h> |
| 19 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
| 20 | #include <linux/libps2.h> | 20 | #include <linux/libps2.h> |
| 21 | #include <asm/unaligned.h> | ||
| 21 | #include "psmouse.h" | 22 | #include "psmouse.h" |
| 22 | #include "elantech.h" | 23 | #include "elantech.h" |
| 23 | 24 | ||
| @@ -403,6 +404,68 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
| 403 | input_sync(dev); | 404 | input_sync(dev); |
| 404 | } | 405 | } |
| 405 | 406 | ||
| 407 | static void elantech_report_trackpoint(struct psmouse *psmouse, | ||
| 408 | int packet_type) | ||
| 409 | { | ||
| 410 | /* | ||
| 411 | * byte 0: 0 0 sx sy 0 M R L | ||
| 412 | * byte 1:~sx 0 0 0 0 0 0 0 | ||
| 413 | * byte 2:~sy 0 0 0 0 0 0 0 | ||
| 414 | * byte 3: 0 0 ~sy ~sx 0 1 1 0 | ||
| 415 | * byte 4: x7 x6 x5 x4 x3 x2 x1 x0 | ||
| 416 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
| 417 | * | ||
| 418 | * x and y are written in two's complement spread | ||
| 419 | * over 9 bits with sx/sy the relative top bit and | ||
| 420 | * x7..x0 and y7..y0 the lower bits. | ||
| 421 | * The sign of y is opposite to what the input driver | ||
| 422 | * expects for a relative movement | ||
| 423 | */ | ||
| 424 | |||
| 425 | struct elantech_data *etd = psmouse->private; | ||
| 426 | struct input_dev *tp_dev = etd->tp_dev; | ||
| 427 | unsigned char *packet = psmouse->packet; | ||
| 428 | int x, y; | ||
| 429 | u32 t; | ||
| 430 | |||
| 431 | if (dev_WARN_ONCE(&psmouse->ps2dev.serio->dev, | ||
| 432 | !tp_dev, | ||
| 433 | psmouse_fmt("Unexpected trackpoint message\n"))) { | ||
| 434 | if (etd->debug == 1) | ||
| 435 | elantech_packet_dump(psmouse); | ||
| 436 | return; | ||
| 437 | } | ||
| 438 | |||
| 439 | t = get_unaligned_le32(&packet[0]); | ||
| 440 | |||
| 441 | switch (t & ~7U) { | ||
| 442 | case 0x06000030U: | ||
| 443 | case 0x16008020U: | ||
| 444 | case 0x26800010U: | ||
| 445 | case 0x36808000U: | ||
| 446 | x = packet[4] - (int)((packet[1]^0x80) << 1); | ||
| 447 | y = (int)((packet[2]^0x80) << 1) - packet[5]; | ||
| 448 | |||
| 449 | input_report_key(tp_dev, BTN_LEFT, packet[0] & 0x01); | ||
| 450 | input_report_key(tp_dev, BTN_RIGHT, packet[0] & 0x02); | ||
| 451 | input_report_key(tp_dev, BTN_MIDDLE, packet[0] & 0x04); | ||
| 452 | |||
| 453 | input_report_rel(tp_dev, REL_X, x); | ||
| 454 | input_report_rel(tp_dev, REL_Y, y); | ||
| 455 | |||
| 456 | input_sync(tp_dev); | ||
| 457 | |||
| 458 | break; | ||
| 459 | |||
| 460 | default: | ||
| 461 | /* Dump unexpected packet sequences if debug=1 (default) */ | ||
| 462 | if (etd->debug == 1) | ||
| 463 | elantech_packet_dump(psmouse); | ||
| 464 | |||
| 465 | break; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 406 | /* | 469 | /* |
| 407 | * Interpret complete data packets and report absolute mode input events for | 470 | * Interpret complete data packets and report absolute mode input events for |
| 408 | * hardware version 3. (12 byte packets for two fingers) | 471 | * hardware version 3. (12 byte packets for two fingers) |
| @@ -715,6 +778,8 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) | |||
| 715 | 778 | ||
| 716 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) | 779 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) |
| 717 | return PACKET_V3_TAIL; | 780 | return PACKET_V3_TAIL; |
| 781 | if ((packet[3] & 0x0f) == 0x06) | ||
| 782 | return PACKET_TRACKPOINT; | ||
| 718 | } | 783 | } |
| 719 | 784 | ||
| 720 | return PACKET_UNKNOWN; | 785 | return PACKET_UNKNOWN; |
| @@ -791,14 +856,23 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
| 791 | 856 | ||
| 792 | case 3: | 857 | case 3: |
| 793 | packet_type = elantech_packet_check_v3(psmouse); | 858 | packet_type = elantech_packet_check_v3(psmouse); |
| 794 | /* ignore debounce */ | 859 | switch (packet_type) { |
| 795 | if (packet_type == PACKET_DEBOUNCE) | 860 | case PACKET_UNKNOWN: |
| 796 | return PSMOUSE_FULL_PACKET; | ||
| 797 | |||
| 798 | if (packet_type == PACKET_UNKNOWN) | ||
| 799 | return PSMOUSE_BAD_DATA; | 861 | return PSMOUSE_BAD_DATA; |
| 800 | 862 | ||
| 801 | elantech_report_absolute_v3(psmouse, packet_type); | 863 | case PACKET_DEBOUNCE: |
| 864 | /* ignore debounce */ | ||
| 865 | break; | ||
| 866 | |||
| 867 | case PACKET_TRACKPOINT: | ||
| 868 | elantech_report_trackpoint(psmouse, packet_type); | ||
| 869 | break; | ||
| 870 | |||
| 871 | default: | ||
| 872 | elantech_report_absolute_v3(psmouse, packet_type); | ||
| 873 | break; | ||
| 874 | } | ||
| 875 | |||
| 802 | break; | 876 | break; |
| 803 | 877 | ||
| 804 | case 4: | 878 | case 4: |
| @@ -1018,8 +1092,10 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, | |||
| 1018 | * Asus UX31 0x361f00 20, 15, 0e clickpad | 1092 | * Asus UX31 0x361f00 20, 15, 0e clickpad |
| 1019 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad | 1093 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad |
| 1020 | * Avatar AVIU-145A2 0x361f00 ? clickpad | 1094 | * Avatar AVIU-145A2 0x361f00 ? clickpad |
| 1095 | * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) | ||
| 1021 | * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons | 1096 | * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons |
| 1022 | * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) | 1097 | * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) |
| 1098 | * Lenovo L530 0x350f02 b9, 15, 0c 2 hw buttons (*) | ||
| 1023 | * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons | 1099 | * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons |
| 1024 | * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad | 1100 | * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad |
| 1025 | * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad | 1101 | * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad |
| @@ -1029,6 +1105,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, | |||
| 1029 | * Samsung RF710 0x450f00 ? 2 hw buttons | 1105 | * Samsung RF710 0x450f00 ? 2 hw buttons |
| 1030 | * System76 Pangolin 0x250f01 ? 2 hw buttons | 1106 | * System76 Pangolin 0x250f01 ? 2 hw buttons |
| 1031 | * (*) + 3 trackpoint buttons | 1107 | * (*) + 3 trackpoint buttons |
| 1108 | * (**) + 0 trackpoint buttons | ||
| 1109 | * Note: Lenovo L430 and Lenovo L430 have the same fw_version/caps | ||
| 1032 | */ | 1110 | */ |
| 1033 | static void elantech_set_buttonpad_prop(struct psmouse *psmouse) | 1111 | static void elantech_set_buttonpad_prop(struct psmouse *psmouse) |
| 1034 | { | 1112 | { |
| @@ -1253,6 +1331,13 @@ static bool elantech_is_signature_valid(const unsigned char *param) | |||
| 1253 | if (param[1] == 0) | 1331 | if (param[1] == 0) |
| 1254 | return true; | 1332 | return true; |
| 1255 | 1333 | ||
| 1334 | /* | ||
| 1335 | * Some models have a revision higher then 20. Meaning param[2] may | ||
| 1336 | * be 10 or 20, skip the rates check for these. | ||
| 1337 | */ | ||
| 1338 | if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) | ||
| 1339 | return true; | ||
| 1340 | |||
| 1256 | for (i = 0; i < ARRAY_SIZE(rates); i++) | 1341 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
| 1257 | if (param[2] == rates[i]) | 1342 | if (param[2] == rates[i]) |
| 1258 | return false; | 1343 | return false; |
| @@ -1324,6 +1409,10 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
| 1324 | */ | 1409 | */ |
| 1325 | static void elantech_disconnect(struct psmouse *psmouse) | 1410 | static void elantech_disconnect(struct psmouse *psmouse) |
| 1326 | { | 1411 | { |
| 1412 | struct elantech_data *etd = psmouse->private; | ||
| 1413 | |||
| 1414 | if (etd->tp_dev) | ||
| 1415 | input_unregister_device(etd->tp_dev); | ||
| 1327 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, | 1416 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, |
| 1328 | &elantech_attr_group); | 1417 | &elantech_attr_group); |
| 1329 | kfree(psmouse->private); | 1418 | kfree(psmouse->private); |
| @@ -1438,8 +1527,10 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
| 1438 | int elantech_init(struct psmouse *psmouse) | 1527 | int elantech_init(struct psmouse *psmouse) |
| 1439 | { | 1528 | { |
| 1440 | struct elantech_data *etd; | 1529 | struct elantech_data *etd; |
| 1441 | int i, error; | 1530 | int i; |
| 1531 | int error = -EINVAL; | ||
| 1442 | unsigned char param[3]; | 1532 | unsigned char param[3]; |
| 1533 | struct input_dev *tp_dev; | ||
| 1443 | 1534 | ||
| 1444 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 1535 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); |
| 1445 | if (!etd) | 1536 | if (!etd) |
| @@ -1498,14 +1589,53 @@ int elantech_init(struct psmouse *psmouse) | |||
| 1498 | goto init_fail; | 1589 | goto init_fail; |
| 1499 | } | 1590 | } |
| 1500 | 1591 | ||
| 1592 | /* The MSB indicates the presence of the trackpoint */ | ||
| 1593 | if ((etd->capabilities[0] & 0x80) == 0x80) { | ||
| 1594 | tp_dev = input_allocate_device(); | ||
| 1595 | |||
| 1596 | if (!tp_dev) { | ||
| 1597 | error = -ENOMEM; | ||
| 1598 | goto init_fail_tp_alloc; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | etd->tp_dev = tp_dev; | ||
| 1602 | snprintf(etd->tp_phys, sizeof(etd->tp_phys), "%s/input1", | ||
| 1603 | psmouse->ps2dev.serio->phys); | ||
| 1604 | tp_dev->phys = etd->tp_phys; | ||
| 1605 | tp_dev->name = "Elantech PS/2 TrackPoint"; | ||
| 1606 | tp_dev->id.bustype = BUS_I8042; | ||
| 1607 | tp_dev->id.vendor = 0x0002; | ||
| 1608 | tp_dev->id.product = PSMOUSE_ELANTECH; | ||
| 1609 | tp_dev->id.version = 0x0000; | ||
| 1610 | tp_dev->dev.parent = &psmouse->ps2dev.serio->dev; | ||
| 1611 | tp_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | ||
| 1612 | tp_dev->relbit[BIT_WORD(REL_X)] = | ||
| 1613 | BIT_MASK(REL_X) | BIT_MASK(REL_Y); | ||
| 1614 | tp_dev->keybit[BIT_WORD(BTN_LEFT)] = | ||
| 1615 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | | ||
| 1616 | BIT_MASK(BTN_RIGHT); | ||
| 1617 | |||
| 1618 | __set_bit(INPUT_PROP_POINTER, tp_dev->propbit); | ||
| 1619 | __set_bit(INPUT_PROP_POINTING_STICK, tp_dev->propbit); | ||
| 1620 | |||
| 1621 | error = input_register_device(etd->tp_dev); | ||
| 1622 | if (error < 0) | ||
| 1623 | goto init_fail_tp_reg; | ||
| 1624 | } | ||
| 1625 | |||
| 1501 | psmouse->protocol_handler = elantech_process_byte; | 1626 | psmouse->protocol_handler = elantech_process_byte; |
| 1502 | psmouse->disconnect = elantech_disconnect; | 1627 | psmouse->disconnect = elantech_disconnect; |
| 1503 | psmouse->reconnect = elantech_reconnect; | 1628 | psmouse->reconnect = elantech_reconnect; |
| 1504 | psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; | 1629 | psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; |
| 1505 | 1630 | ||
| 1506 | return 0; | 1631 | return 0; |
| 1507 | 1632 | init_fail_tp_reg: | |
| 1633 | input_free_device(tp_dev); | ||
| 1634 | init_fail_tp_alloc: | ||
| 1635 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, | ||
| 1636 | &elantech_attr_group); | ||
| 1508 | init_fail: | 1637 | init_fail: |
| 1638 | psmouse_reset(psmouse); | ||
| 1509 | kfree(etd); | 1639 | kfree(etd); |
| 1510 | return -1; | 1640 | return error; |
| 1511 | } | 1641 | } |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 9e0e2a1f340d..6f3afec02f03 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
| @@ -94,6 +94,7 @@ | |||
| 94 | #define PACKET_V4_HEAD 0x05 | 94 | #define PACKET_V4_HEAD 0x05 |
| 95 | #define PACKET_V4_MOTION 0x06 | 95 | #define PACKET_V4_MOTION 0x06 |
| 96 | #define PACKET_V4_STATUS 0x07 | 96 | #define PACKET_V4_STATUS 0x07 |
| 97 | #define PACKET_TRACKPOINT 0x08 | ||
| 97 | 98 | ||
| 98 | /* | 99 | /* |
| 99 | * track up to 5 fingers for v4 hardware | 100 | * track up to 5 fingers for v4 hardware |
| @@ -114,6 +115,8 @@ struct finger_pos { | |||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | struct elantech_data { | 117 | struct elantech_data { |
| 118 | struct input_dev *tp_dev; /* Relative device for trackpoint */ | ||
| 119 | char tp_phys[32]; | ||
| 117 | unsigned char reg_07; | 120 | unsigned char reg_07; |
| 118 | unsigned char reg_10; | 121 | unsigned char reg_10; |
| 119 | unsigned char reg_11; | 122 | unsigned char reg_11; |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cff065f6261c..b4e1f014ddc2 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -670,6 +670,8 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) | |||
| 670 | __set_bit(REL_X, input_dev->relbit); | 670 | __set_bit(REL_X, input_dev->relbit); |
| 671 | __set_bit(REL_Y, input_dev->relbit); | 671 | __set_bit(REL_Y, input_dev->relbit); |
| 672 | 672 | ||
| 673 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
| 674 | |||
| 673 | psmouse->set_rate = psmouse_set_rate; | 675 | psmouse->set_rate = psmouse_set_rate; |
| 674 | psmouse->set_resolution = psmouse_set_resolution; | 676 | psmouse->set_resolution = psmouse_set_resolution; |
| 675 | psmouse->poll = psmouse_poll; | 677 | psmouse->poll = psmouse_poll; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e8573c68f77e..fd23181c1fb7 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -629,10 +629,61 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 629 | ((buf[0] & 0x04) >> 1) | | 629 | ((buf[0] & 0x04) >> 1) | |
| 630 | ((buf[3] & 0x04) >> 2)); | 630 | ((buf[3] & 0x04) >> 2)); |
| 631 | 631 | ||
| 632 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | ||
| 633 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && | ||
| 634 | hw->w == 2) { | ||
| 635 | synaptics_parse_agm(buf, priv, hw); | ||
| 636 | return 1; | ||
| 637 | } | ||
| 638 | |||
| 639 | hw->x = (((buf[3] & 0x10) << 8) | | ||
| 640 | ((buf[1] & 0x0f) << 8) | | ||
| 641 | buf[4]); | ||
| 642 | hw->y = (((buf[3] & 0x20) << 7) | | ||
| 643 | ((buf[1] & 0xf0) << 4) | | ||
| 644 | buf[5]); | ||
| 645 | hw->z = buf[2]; | ||
| 646 | |||
| 632 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 647 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
| 633 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 648 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
| 634 | 649 | ||
| 635 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 650 | if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) { |
| 651 | /* | ||
| 652 | * ForcePads, like Clickpads, use middle button | ||
| 653 | * bits to report primary button clicks. | ||
| 654 | * Unfortunately they report primary button not | ||
| 655 | * only when user presses on the pad above certain | ||
| 656 | * threshold, but also when there are more than one | ||
| 657 | * finger on the touchpad, which interferes with | ||
| 658 | * out multi-finger gestures. | ||
| 659 | */ | ||
| 660 | if (hw->z == 0) { | ||
| 661 | /* No contacts */ | ||
| 662 | priv->press = priv->report_press = false; | ||
| 663 | } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) { | ||
| 664 | /* | ||
| 665 | * Single-finger touch with pressure above | ||
| 666 | * the threshold. If pressure stays long | ||
| 667 | * enough, we'll start reporting primary | ||
| 668 | * button. We rely on the device continuing | ||
| 669 | * sending data even if finger does not | ||
| 670 | * move. | ||
| 671 | */ | ||
| 672 | if (!priv->press) { | ||
| 673 | priv->press_start = jiffies; | ||
| 674 | priv->press = true; | ||
| 675 | } else if (time_after(jiffies, | ||
| 676 | priv->press_start + | ||
| 677 | msecs_to_jiffies(50))) { | ||
| 678 | priv->report_press = true; | ||
| 679 | } | ||
| 680 | } else { | ||
| 681 | priv->press = false; | ||
| 682 | } | ||
| 683 | |||
| 684 | hw->left = priv->report_press; | ||
| 685 | |||
| 686 | } else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
| 636 | /* | 687 | /* |
| 637 | * Clickpad's button is transmitted as middle button, | 688 | * Clickpad's button is transmitted as middle button, |
| 638 | * however, since it is primary button, we will report | 689 | * however, since it is primary button, we will report |
| @@ -651,21 +702,6 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 651 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 702 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
| 652 | } | 703 | } |
| 653 | 704 | ||
| 654 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | ||
| 655 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && | ||
| 656 | hw->w == 2) { | ||
| 657 | synaptics_parse_agm(buf, priv, hw); | ||
| 658 | return 1; | ||
| 659 | } | ||
| 660 | |||
| 661 | hw->x = (((buf[3] & 0x10) << 8) | | ||
| 662 | ((buf[1] & 0x0f) << 8) | | ||
| 663 | buf[4]); | ||
| 664 | hw->y = (((buf[3] & 0x20) << 7) | | ||
| 665 | ((buf[1] & 0xf0) << 4) | | ||
| 666 | buf[5]); | ||
| 667 | hw->z = buf[2]; | ||
| 668 | |||
| 669 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | 705 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && |
| 670 | ((buf[0] ^ buf[3]) & 0x02)) { | 706 | ((buf[0] ^ buf[3]) & 0x02)) { |
| 671 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | 707 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index e594af0b264b..fb2e076738ae 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
| @@ -78,6 +78,11 @@ | |||
| 78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only | 78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only |
| 79 | * reports 2. | 79 | * reports 2. |
| 80 | * 2 0x20 report min query 0x0f gives min coord reported | 80 | * 2 0x20 report min query 0x0f gives min coord reported |
| 81 | * 2 0x80 forcepad forcepad is a variant of clickpad that | ||
| 82 | * does not have physical buttons but rather | ||
| 83 | * uses pressure above certain threshold to | ||
| 84 | * report primary clicks. Forcepads also have | ||
| 85 | * clickpad bit set. | ||
| 81 | */ | 86 | */ |
| 82 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 87 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
| 83 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | 88 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ |
| @@ -86,6 +91,7 @@ | |||
| 86 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 91 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
| 87 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | 92 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
| 88 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) | 93 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) |
| 94 | #define SYN_CAP_FORCEPAD(ex0c) ((ex0c) & 0x008000) | ||
| 89 | 95 | ||
| 90 | /* synaptics modes query bits */ | 96 | /* synaptics modes query bits */ |
| 91 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 97 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
| @@ -177,6 +183,11 @@ struct synaptics_data { | |||
| 177 | */ | 183 | */ |
| 178 | struct synaptics_hw_state agm; | 184 | struct synaptics_hw_state agm; |
| 179 | bool agm_pending; /* new AGM packet received */ | 185 | bool agm_pending; /* new AGM packet received */ |
| 186 | |||
| 187 | /* ForcePad handling */ | ||
| 188 | unsigned long press_start; | ||
| 189 | bool press; | ||
| 190 | bool report_press; | ||
| 180 | }; | 191 | }; |
| 181 | 192 | ||
| 182 | void synaptics_module_init(void); | 193 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index e122bda16aab..6bcc0189c1c9 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c | |||
| @@ -387,6 +387,7 @@ static int synusb_probe(struct usb_interface *intf, | |||
| 387 | __set_bit(EV_REL, input_dev->evbit); | 387 | __set_bit(EV_REL, input_dev->evbit); |
| 388 | __set_bit(REL_X, input_dev->relbit); | 388 | __set_bit(REL_X, input_dev->relbit); |
| 389 | __set_bit(REL_Y, input_dev->relbit); | 389 | __set_bit(REL_Y, input_dev->relbit); |
| 390 | __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit); | ||
| 390 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); | 391 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); |
| 391 | } else { | 392 | } else { |
| 392 | input_set_abs_params(input_dev, ABS_X, | 393 | input_set_abs_params(input_dev, ABS_X, |
| @@ -401,6 +402,11 @@ static int synusb_probe(struct usb_interface *intf, | |||
| 401 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 402 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
| 402 | } | 403 | } |
| 403 | 404 | ||
| 405 | if (synusb->flags & SYNUSB_TOUCHSCREEN) | ||
| 406 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
| 407 | else | ||
| 408 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
| 409 | |||
| 404 | __set_bit(BTN_LEFT, input_dev->keybit); | 410 | __set_bit(BTN_LEFT, input_dev->keybit); |
| 405 | __set_bit(BTN_RIGHT, input_dev->keybit); | 411 | __set_bit(BTN_RIGHT, input_dev->keybit); |
| 406 | __set_bit(BTN_MIDDLE, input_dev->keybit); | 412 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index ca843b6cf6bd..30c8b6998808 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
| @@ -393,6 +393,9 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
| 393 | if ((button_info & 0x0f) >= 3) | 393 | if ((button_info & 0x0f) >= 3) |
| 394 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 394 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 395 | 395 | ||
| 396 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); | ||
| 397 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); | ||
| 398 | |||
| 396 | trackpoint_defaults(psmouse->private); | 399 | trackpoint_defaults(psmouse->private); |
| 397 | 400 | ||
| 398 | error = trackpoint_power_on_reset(&psmouse->ps2dev); | 401 | error = trackpoint_power_on_reset(&psmouse->ps2dev); |
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index d6aa4c67dbb6..93cb7912703c 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h | |||
| @@ -17,7 +17,6 @@ static int i8042_aux_irq = -1; | |||
| 17 | #define I8042_MUX_PHYS_DESC "sparcps2/serio%d" | 17 | #define I8042_MUX_PHYS_DESC "sparcps2/serio%d" |
| 18 | 18 | ||
| 19 | static void __iomem *kbd_iobase; | 19 | static void __iomem *kbd_iobase; |
| 20 | static struct resource *kbd_res; | ||
| 21 | 20 | ||
| 22 | #define I8042_COMMAND_REG (kbd_iobase + 0x64UL) | 21 | #define I8042_COMMAND_REG (kbd_iobase + 0x64UL) |
| 23 | #define I8042_DATA_REG (kbd_iobase + 0x60UL) | 22 | #define I8042_DATA_REG (kbd_iobase + 0x60UL) |
| @@ -44,6 +43,8 @@ static inline void i8042_write_command(int val) | |||
| 44 | 43 | ||
| 45 | #ifdef CONFIG_PCI | 44 | #ifdef CONFIG_PCI |
| 46 | 45 | ||
| 46 | static struct resource *kbd_res; | ||
| 47 | |||
| 47 | #define OBP_PS2KBD_NAME1 "kb_ps2" | 48 | #define OBP_PS2KBD_NAME1 "kb_ps2" |
| 48 | #define OBP_PS2KBD_NAME2 "keyboard" | 49 | #define OBP_PS2KBD_NAME2 "keyboard" |
| 49 | #define OBP_PS2MS_NAME1 "kdmouse" | 50 | #define OBP_PS2MS_NAME1 "kdmouse" |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 0cb7ef59071b..69175b825346 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/serio.h> | 22 | #include <linux/serio.h> |
| 23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
| 24 | #include <linux/compat.h> | ||
| 24 | 25 | ||
| 25 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 26 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
| 26 | MODULE_DESCRIPTION("Input device TTY line discipline"); | 27 | MODULE_DESCRIPTION("Input device TTY line discipline"); |
| @@ -198,28 +199,55 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
| 198 | return 0; | 199 | return 0; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 202 | static void serport_set_type(struct tty_struct *tty, unsigned long type) | ||
| 203 | { | ||
| 204 | struct serport *serport = tty->disc_data; | ||
| 205 | |||
| 206 | serport->id.proto = type & 0x000000ff; | ||
| 207 | serport->id.id = (type & 0x0000ff00) >> 8; | ||
| 208 | serport->id.extra = (type & 0x00ff0000) >> 16; | ||
| 209 | } | ||
| 210 | |||
| 201 | /* | 211 | /* |
| 202 | * serport_ldisc_ioctl() allows to set the port protocol, and device ID | 212 | * serport_ldisc_ioctl() allows to set the port protocol, and device ID |
| 203 | */ | 213 | */ |
| 204 | 214 | ||
| 205 | static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) | 215 | static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file, |
| 216 | unsigned int cmd, unsigned long arg) | ||
| 206 | { | 217 | { |
| 207 | struct serport *serport = (struct serport*) tty->disc_data; | ||
| 208 | unsigned long type; | ||
| 209 | |||
| 210 | if (cmd == SPIOCSTYPE) { | 218 | if (cmd == SPIOCSTYPE) { |
| 219 | unsigned long type; | ||
| 220 | |||
| 211 | if (get_user(type, (unsigned long __user *) arg)) | 221 | if (get_user(type, (unsigned long __user *) arg)) |
| 212 | return -EFAULT; | 222 | return -EFAULT; |
| 213 | 223 | ||
| 214 | serport->id.proto = type & 0x000000ff; | 224 | serport_set_type(tty, type); |
| 215 | serport->id.id = (type & 0x0000ff00) >> 8; | 225 | return 0; |
| 216 | serport->id.extra = (type & 0x00ff0000) >> 16; | 226 | } |
| 227 | |||
| 228 | return -EINVAL; | ||
| 229 | } | ||
| 230 | |||
| 231 | #ifdef CONFIG_COMPAT | ||
| 232 | #define COMPAT_SPIOCSTYPE _IOW('q', 0x01, compat_ulong_t) | ||
| 233 | static long serport_ldisc_compat_ioctl(struct tty_struct *tty, | ||
| 234 | struct file *file, | ||
| 235 | unsigned int cmd, unsigned long arg) | ||
| 236 | { | ||
| 237 | if (cmd == COMPAT_SPIOCSTYPE) { | ||
| 238 | void __user *uarg = compat_ptr(arg); | ||
| 239 | compat_ulong_t compat_type; | ||
| 240 | |||
| 241 | if (get_user(compat_type, (compat_ulong_t __user *)uarg)) | ||
| 242 | return -EFAULT; | ||
| 217 | 243 | ||
| 244 | serport_set_type(tty, compat_type); | ||
| 218 | return 0; | 245 | return 0; |
| 219 | } | 246 | } |
| 220 | 247 | ||
| 221 | return -EINVAL; | 248 | return -EINVAL; |
| 222 | } | 249 | } |
| 250 | #endif | ||
| 223 | 251 | ||
| 224 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) | 252 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) |
| 225 | { | 253 | { |
| @@ -243,6 +271,9 @@ static struct tty_ldisc_ops serport_ldisc = { | |||
| 243 | .close = serport_ldisc_close, | 271 | .close = serport_ldisc_close, |
| 244 | .read = serport_ldisc_read, | 272 | .read = serport_ldisc_read, |
| 245 | .ioctl = serport_ldisc_ioctl, | 273 | .ioctl = serport_ldisc_ioctl, |
| 274 | #ifdef CONFIG_COMPAT | ||
| 275 | .compat_ioctl = serport_ldisc_compat_ioctl, | ||
| 276 | #endif | ||
| 246 | .receive_buf = serport_ldisc_receive, | 277 | .receive_buf = serport_ldisc_receive, |
| 247 | .write_wakeup = serport_ldisc_write_wakeup | 278 | .write_wakeup = serport_ldisc_write_wakeup |
| 248 | }; | 279 | }; |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index db178ed2b47e..aaacf8bfa61f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -837,7 +837,12 @@ static irqreturn_t mxt_process_messages_t44(struct mxt_data *data) | |||
| 837 | count = data->msg_buf[0]; | 837 | count = data->msg_buf[0]; |
| 838 | 838 | ||
| 839 | if (count == 0) { | 839 | if (count == 0) { |
| 840 | dev_warn(dev, "Interrupt triggered but zero messages\n"); | 840 | /* |
| 841 | * This condition is caused by the CHG line being configured | ||
| 842 | * in Mode 0. It results in unnecessary I2C operations but it | ||
| 843 | * is benign. | ||
| 844 | */ | ||
| 845 | dev_dbg(dev, "Interrupt triggered but zero messages\n"); | ||
| 841 | return IRQ_NONE; | 846 | return IRQ_NONE; |
| 842 | } else if (count > data->max_reportid) { | 847 | } else if (count > data->max_reportid) { |
| 843 | dev_err(dev, "T44 count %d exceeded max report id\n", count); | 848 | dev_err(dev, "T44 count %d exceeded max report id\n", count); |
| @@ -1374,11 +1379,16 @@ static int mxt_get_info(struct mxt_data *data) | |||
| 1374 | return 0; | 1379 | return 0; |
| 1375 | } | 1380 | } |
| 1376 | 1381 | ||
| 1377 | static void mxt_free_object_table(struct mxt_data *data) | 1382 | static void mxt_free_input_device(struct mxt_data *data) |
| 1378 | { | 1383 | { |
| 1379 | input_unregister_device(data->input_dev); | 1384 | if (data->input_dev) { |
| 1380 | data->input_dev = NULL; | 1385 | input_unregister_device(data->input_dev); |
| 1386 | data->input_dev = NULL; | ||
| 1387 | } | ||
| 1388 | } | ||
| 1381 | 1389 | ||
| 1390 | static void mxt_free_object_table(struct mxt_data *data) | ||
| 1391 | { | ||
| 1382 | kfree(data->object_table); | 1392 | kfree(data->object_table); |
| 1383 | data->object_table = NULL; | 1393 | data->object_table = NULL; |
| 1384 | kfree(data->msg_buf); | 1394 | kfree(data->msg_buf); |
| @@ -1957,11 +1967,13 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
| 1957 | ret = mxt_lookup_bootloader_address(data, 0); | 1967 | ret = mxt_lookup_bootloader_address(data, 0); |
| 1958 | if (ret) | 1968 | if (ret) |
| 1959 | goto release_firmware; | 1969 | goto release_firmware; |
| 1970 | |||
| 1971 | mxt_free_input_device(data); | ||
| 1972 | mxt_free_object_table(data); | ||
| 1960 | } else { | 1973 | } else { |
| 1961 | enable_irq(data->irq); | 1974 | enable_irq(data->irq); |
| 1962 | } | 1975 | } |
| 1963 | 1976 | ||
| 1964 | mxt_free_object_table(data); | ||
| 1965 | reinit_completion(&data->bl_completion); | 1977 | reinit_completion(&data->bl_completion); |
| 1966 | 1978 | ||
| 1967 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); | 1979 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); |
| @@ -2210,6 +2222,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 2210 | return 0; | 2222 | return 0; |
| 2211 | 2223 | ||
| 2212 | err_free_object: | 2224 | err_free_object: |
| 2225 | mxt_free_input_device(data); | ||
| 2213 | mxt_free_object_table(data); | 2226 | mxt_free_object_table(data); |
| 2214 | err_free_irq: | 2227 | err_free_irq: |
| 2215 | free_irq(client->irq, data); | 2228 | free_irq(client->irq, data); |
| @@ -2224,7 +2237,7 @@ static int mxt_remove(struct i2c_client *client) | |||
| 2224 | 2237 | ||
| 2225 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); | 2238 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); |
| 2226 | free_irq(data->irq, data); | 2239 | free_irq(data->irq, data); |
| 2227 | input_unregister_device(data->input_dev); | 2240 | mxt_free_input_device(data); |
| 2228 | mxt_free_object_table(data); | 2241 | mxt_free_object_table(data); |
| 2229 | kfree(data); | 2242 | kfree(data); |
| 2230 | 2243 | ||
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 16b52115c27f..705ffa1e064a 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | */ | 41 | */ |
| 42 | static int rpu = 8; | 42 | static int rpu = 8; |
| 43 | module_param(rpu, int, 0); | 43 | module_param(rpu, int, 0); |
| 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); | 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect."); |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * Set current used for pressure measurement. | 47 | * Set current used for pressure measurement. |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 7405353199d7..572a5a64face 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | */ | 41 | */ |
| 42 | static int rpu = 8; | 42 | static int rpu = 8; |
| 43 | module_param(rpu, int, 0); | 43 | module_param(rpu, int, 0); |
| 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); | 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect."); |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * Set current used for pressure measurement. | 47 | * Set current used for pressure measurement. |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 18405314168b..ecb0109a5360 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -3149,14 +3149,16 @@ free_domains: | |||
| 3149 | 3149 | ||
| 3150 | static void cleanup_domain(struct protection_domain *domain) | 3150 | static void cleanup_domain(struct protection_domain *domain) |
| 3151 | { | 3151 | { |
| 3152 | struct iommu_dev_data *dev_data, *next; | 3152 | struct iommu_dev_data *entry; |
| 3153 | unsigned long flags; | 3153 | unsigned long flags; |
| 3154 | 3154 | ||
| 3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
| 3156 | 3156 | ||
| 3157 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { | 3157 | while (!list_empty(&domain->dev_list)) { |
| 3158 | __detach_device(dev_data); | 3158 | entry = list_first_entry(&domain->dev_list, |
| 3159 | atomic_set(&dev_data->bind, 0); | 3159 | struct iommu_dev_data, list); |
| 3160 | __detach_device(entry); | ||
| 3161 | atomic_set(&entry->bind, 0); | ||
| 3160 | } | 3162 | } |
| 3161 | 3163 | ||
| 3162 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 3164 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index ca18d6d42a9b..a83cc2a2a2ca 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
| @@ -146,6 +146,8 @@ | |||
| 146 | #define ID0_CTTW (1 << 14) | 146 | #define ID0_CTTW (1 << 14) |
| 147 | #define ID0_NUMIRPT_SHIFT 16 | 147 | #define ID0_NUMIRPT_SHIFT 16 |
| 148 | #define ID0_NUMIRPT_MASK 0xff | 148 | #define ID0_NUMIRPT_MASK 0xff |
| 149 | #define ID0_NUMSIDB_SHIFT 9 | ||
| 150 | #define ID0_NUMSIDB_MASK 0xf | ||
| 149 | #define ID0_NUMSMRG_SHIFT 0 | 151 | #define ID0_NUMSMRG_SHIFT 0 |
| 150 | #define ID0_NUMSMRG_MASK 0xff | 152 | #define ID0_NUMSMRG_MASK 0xff |
| 151 | 153 | ||
| @@ -524,9 +526,18 @@ static int register_smmu_master(struct arm_smmu_device *smmu, | |||
| 524 | master->of_node = masterspec->np; | 526 | master->of_node = masterspec->np; |
| 525 | master->cfg.num_streamids = masterspec->args_count; | 527 | master->cfg.num_streamids = masterspec->args_count; |
| 526 | 528 | ||
| 527 | for (i = 0; i < master->cfg.num_streamids; ++i) | 529 | for (i = 0; i < master->cfg.num_streamids; ++i) { |
| 528 | master->cfg.streamids[i] = masterspec->args[i]; | 530 | u16 streamid = masterspec->args[i]; |
| 529 | 531 | ||
| 532 | if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) && | ||
| 533 | (streamid >= smmu->num_mapping_groups)) { | ||
| 534 | dev_err(dev, | ||
| 535 | "stream ID for master device %s greater than maximum allowed (%d)\n", | ||
| 536 | masterspec->np->name, smmu->num_mapping_groups); | ||
| 537 | return -ERANGE; | ||
| 538 | } | ||
| 539 | master->cfg.streamids[i] = streamid; | ||
| 540 | } | ||
| 530 | return insert_smmu_master(smmu, master); | 541 | return insert_smmu_master(smmu, master); |
| 531 | } | 542 | } |
| 532 | 543 | ||
| @@ -623,7 +634,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
| 623 | 634 | ||
| 624 | if (fsr & FSR_IGN) | 635 | if (fsr & FSR_IGN) |
| 625 | dev_err_ratelimited(smmu->dev, | 636 | dev_err_ratelimited(smmu->dev, |
| 626 | "Unexpected context fault (fsr 0x%u)\n", | 637 | "Unexpected context fault (fsr 0x%x)\n", |
| 627 | fsr); | 638 | fsr); |
| 628 | 639 | ||
| 629 | fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0); | 640 | fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0); |
| @@ -752,6 +763,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 752 | reg = (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT); | 763 | reg = (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT); |
| 753 | break; | 764 | break; |
| 754 | case 39: | 765 | case 39: |
| 766 | case 40: | ||
| 755 | reg = (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT); | 767 | reg = (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT); |
| 756 | break; | 768 | break; |
| 757 | case 42: | 769 | case 42: |
| @@ -773,6 +785,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 773 | reg |= (TTBCR2_ADDR_36 << TTBCR2_PASIZE_SHIFT); | 785 | reg |= (TTBCR2_ADDR_36 << TTBCR2_PASIZE_SHIFT); |
| 774 | break; | 786 | break; |
| 775 | case 39: | 787 | case 39: |
| 788 | case 40: | ||
| 776 | reg |= (TTBCR2_ADDR_40 << TTBCR2_PASIZE_SHIFT); | 789 | reg |= (TTBCR2_ADDR_40 << TTBCR2_PASIZE_SHIFT); |
| 777 | break; | 790 | break; |
| 778 | case 42: | 791 | case 42: |
| @@ -843,8 +856,11 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 843 | reg |= TTBCR_EAE | | 856 | reg |= TTBCR_EAE | |
| 844 | (TTBCR_SH_IS << TTBCR_SH0_SHIFT) | | 857 | (TTBCR_SH_IS << TTBCR_SH0_SHIFT) | |
| 845 | (TTBCR_RGN_WBWA << TTBCR_ORGN0_SHIFT) | | 858 | (TTBCR_RGN_WBWA << TTBCR_ORGN0_SHIFT) | |
| 846 | (TTBCR_RGN_WBWA << TTBCR_IRGN0_SHIFT) | | 859 | (TTBCR_RGN_WBWA << TTBCR_IRGN0_SHIFT); |
| 847 | (TTBCR_SL0_LVL_1 << TTBCR_SL0_SHIFT); | 860 | |
| 861 | if (!stage1) | ||
| 862 | reg |= (TTBCR_SL0_LVL_1 << TTBCR_SL0_SHIFT); | ||
| 863 | |||
| 848 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); | 864 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); |
| 849 | 865 | ||
| 850 | /* MAIR0 (stage-1 only) */ | 866 | /* MAIR0 (stage-1 only) */ |
| @@ -868,10 +884,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 868 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, | 884 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, |
| 869 | struct arm_smmu_device *smmu) | 885 | struct arm_smmu_device *smmu) |
| 870 | { | 886 | { |
| 871 | int irq, ret, start; | 887 | int irq, start, ret = 0; |
| 888 | unsigned long flags; | ||
| 872 | struct arm_smmu_domain *smmu_domain = domain->priv; | 889 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 873 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 890 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 874 | 891 | ||
| 892 | spin_lock_irqsave(&smmu_domain->lock, flags); | ||
| 893 | if (smmu_domain->smmu) | ||
| 894 | goto out_unlock; | ||
| 895 | |||
| 875 | if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { | 896 | if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { |
| 876 | /* | 897 | /* |
| 877 | * We will likely want to change this if/when KVM gets | 898 | * We will likely want to change this if/when KVM gets |
| @@ -890,7 +911,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
| 890 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, | 911 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, |
| 891 | smmu->num_context_banks); | 912 | smmu->num_context_banks); |
| 892 | if (IS_ERR_VALUE(ret)) | 913 | if (IS_ERR_VALUE(ret)) |
| 893 | return ret; | 914 | goto out_unlock; |
| 894 | 915 | ||
| 895 | cfg->cbndx = ret; | 916 | cfg->cbndx = ret; |
| 896 | if (smmu->version == 1) { | 917 | if (smmu->version == 1) { |
| @@ -900,6 +921,10 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
| 900 | cfg->irptndx = cfg->cbndx; | 921 | cfg->irptndx = cfg->cbndx; |
| 901 | } | 922 | } |
| 902 | 923 | ||
| 924 | ACCESS_ONCE(smmu_domain->smmu) = smmu; | ||
| 925 | arm_smmu_init_context_bank(smmu_domain); | ||
| 926 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | ||
| 927 | |||
| 903 | irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; | 928 | irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; |
| 904 | ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED, | 929 | ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED, |
| 905 | "arm-smmu-context-fault", domain); | 930 | "arm-smmu-context-fault", domain); |
| @@ -907,15 +932,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
| 907 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", | 932 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", |
| 908 | cfg->irptndx, irq); | 933 | cfg->irptndx, irq); |
| 909 | cfg->irptndx = INVALID_IRPTNDX; | 934 | cfg->irptndx = INVALID_IRPTNDX; |
| 910 | goto out_free_context; | ||
| 911 | } | 935 | } |
| 912 | 936 | ||
| 913 | smmu_domain->smmu = smmu; | ||
| 914 | arm_smmu_init_context_bank(smmu_domain); | ||
| 915 | return 0; | 937 | return 0; |
| 916 | 938 | ||
| 917 | out_free_context: | 939 | out_unlock: |
| 918 | __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); | 940 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
| 919 | return ret; | 941 | return ret; |
| 920 | } | 942 | } |
| 921 | 943 | ||
| @@ -975,7 +997,6 @@ static void arm_smmu_free_ptes(pmd_t *pmd) | |||
| 975 | { | 997 | { |
| 976 | pgtable_t table = pmd_pgtable(*pmd); | 998 | pgtable_t table = pmd_pgtable(*pmd); |
| 977 | 999 | ||
| 978 | pgtable_page_dtor(table); | ||
| 979 | __free_page(table); | 1000 | __free_page(table); |
| 980 | } | 1001 | } |
| 981 | 1002 | ||
| @@ -1108,6 +1129,9 @@ static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, | |||
| 1108 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1129 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
| 1109 | struct arm_smmu_smr *smrs = cfg->smrs; | 1130 | struct arm_smmu_smr *smrs = cfg->smrs; |
| 1110 | 1131 | ||
| 1132 | if (!smrs) | ||
| 1133 | return; | ||
| 1134 | |||
| 1111 | /* Invalidate the SMRs before freeing back to the allocator */ | 1135 | /* Invalidate the SMRs before freeing back to the allocator */ |
| 1112 | for (i = 0; i < cfg->num_streamids; ++i) { | 1136 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1113 | u8 idx = smrs[i].idx; | 1137 | u8 idx = smrs[i].idx; |
| @@ -1120,20 +1144,6 @@ static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, | |||
| 1120 | kfree(smrs); | 1144 | kfree(smrs); |
| 1121 | } | 1145 | } |
| 1122 | 1146 | ||
| 1123 | static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu, | ||
| 1124 | struct arm_smmu_master_cfg *cfg) | ||
| 1125 | { | ||
| 1126 | int i; | ||
| 1127 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | ||
| 1128 | |||
| 1129 | for (i = 0; i < cfg->num_streamids; ++i) { | ||
| 1130 | u16 sid = cfg->streamids[i]; | ||
| 1131 | |||
| 1132 | writel_relaxed(S2CR_TYPE_BYPASS, | ||
| 1133 | gr0_base + ARM_SMMU_GR0_S2CR(sid)); | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | 1147 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, |
| 1138 | struct arm_smmu_master_cfg *cfg) | 1148 | struct arm_smmu_master_cfg *cfg) |
| 1139 | { | 1149 | { |
| @@ -1160,23 +1170,30 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | |||
| 1160 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | 1170 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, |
| 1161 | struct arm_smmu_master_cfg *cfg) | 1171 | struct arm_smmu_master_cfg *cfg) |
| 1162 | { | 1172 | { |
| 1173 | int i; | ||
| 1163 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 1174 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 1175 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | ||
| 1164 | 1176 | ||
| 1165 | /* | 1177 | /* |
| 1166 | * We *must* clear the S2CR first, because freeing the SMR means | 1178 | * We *must* clear the S2CR first, because freeing the SMR means |
| 1167 | * that it can be re-allocated immediately. | 1179 | * that it can be re-allocated immediately. |
| 1168 | */ | 1180 | */ |
| 1169 | arm_smmu_bypass_stream_mapping(smmu, cfg); | 1181 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1182 | u32 idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; | ||
| 1183 | |||
| 1184 | writel_relaxed(S2CR_TYPE_BYPASS, | ||
| 1185 | gr0_base + ARM_SMMU_GR0_S2CR(idx)); | ||
| 1186 | } | ||
| 1187 | |||
| 1170 | arm_smmu_master_free_smrs(smmu, cfg); | 1188 | arm_smmu_master_free_smrs(smmu, cfg); |
| 1171 | } | 1189 | } |
| 1172 | 1190 | ||
| 1173 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 1191 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
| 1174 | { | 1192 | { |
| 1175 | int ret = -EINVAL; | 1193 | int ret; |
| 1176 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1194 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1177 | struct arm_smmu_device *smmu; | 1195 | struct arm_smmu_device *smmu, *dom_smmu; |
| 1178 | struct arm_smmu_master_cfg *cfg; | 1196 | struct arm_smmu_master_cfg *cfg; |
| 1179 | unsigned long flags; | ||
| 1180 | 1197 | ||
| 1181 | smmu = dev_get_master_dev(dev)->archdata.iommu; | 1198 | smmu = dev_get_master_dev(dev)->archdata.iommu; |
| 1182 | if (!smmu) { | 1199 | if (!smmu) { |
| @@ -1188,20 +1205,22 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
| 1188 | * Sanity check the domain. We don't support domains across | 1205 | * Sanity check the domain. We don't support domains across |
| 1189 | * different SMMUs. | 1206 | * different SMMUs. |
| 1190 | */ | 1207 | */ |
| 1191 | spin_lock_irqsave(&smmu_domain->lock, flags); | 1208 | dom_smmu = ACCESS_ONCE(smmu_domain->smmu); |
| 1192 | if (!smmu_domain->smmu) { | 1209 | if (!dom_smmu) { |
| 1193 | /* Now that we have a master, we can finalise the domain */ | 1210 | /* Now that we have a master, we can finalise the domain */ |
| 1194 | ret = arm_smmu_init_domain_context(domain, smmu); | 1211 | ret = arm_smmu_init_domain_context(domain, smmu); |
| 1195 | if (IS_ERR_VALUE(ret)) | 1212 | if (IS_ERR_VALUE(ret)) |
| 1196 | goto err_unlock; | 1213 | return ret; |
| 1197 | } else if (smmu_domain->smmu != smmu) { | 1214 | |
| 1215 | dom_smmu = smmu_domain->smmu; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | if (dom_smmu != smmu) { | ||
| 1198 | dev_err(dev, | 1219 | dev_err(dev, |
| 1199 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", | 1220 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", |
| 1200 | dev_name(smmu_domain->smmu->dev), | 1221 | dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev)); |
| 1201 | dev_name(smmu->dev)); | 1222 | return -EINVAL; |
| 1202 | goto err_unlock; | ||
| 1203 | } | 1223 | } |
| 1204 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | ||
| 1205 | 1224 | ||
| 1206 | /* Looks ok, so add the device to the domain */ | 1225 | /* Looks ok, so add the device to the domain */ |
| 1207 | cfg = find_smmu_master_cfg(smmu_domain->smmu, dev); | 1226 | cfg = find_smmu_master_cfg(smmu_domain->smmu, dev); |
| @@ -1209,10 +1228,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
| 1209 | return -ENODEV; | 1228 | return -ENODEV; |
| 1210 | 1229 | ||
| 1211 | return arm_smmu_domain_add_master(smmu_domain, cfg); | 1230 | return arm_smmu_domain_add_master(smmu_domain, cfg); |
| 1212 | |||
| 1213 | err_unlock: | ||
| 1214 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | ||
| 1215 | return ret; | ||
| 1216 | } | 1231 | } |
| 1217 | 1232 | ||
| 1218 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | 1233 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) |
| @@ -1247,10 +1262,6 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
| 1247 | return -ENOMEM; | 1262 | return -ENOMEM; |
| 1248 | 1263 | ||
| 1249 | arm_smmu_flush_pgtable(smmu, page_address(table), PAGE_SIZE); | 1264 | arm_smmu_flush_pgtable(smmu, page_address(table), PAGE_SIZE); |
| 1250 | if (!pgtable_page_ctor(table)) { | ||
| 1251 | __free_page(table); | ||
| 1252 | return -ENOMEM; | ||
| 1253 | } | ||
| 1254 | pmd_populate(NULL, pmd, table); | 1265 | pmd_populate(NULL, pmd, table); |
| 1255 | arm_smmu_flush_pgtable(smmu, pmd, sizeof(*pmd)); | 1266 | arm_smmu_flush_pgtable(smmu, pmd, sizeof(*pmd)); |
| 1256 | } | 1267 | } |
| @@ -1626,7 +1637,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
| 1626 | 1637 | ||
| 1627 | /* Mark all SMRn as invalid and all S2CRn as bypass */ | 1638 | /* Mark all SMRn as invalid and all S2CRn as bypass */ |
| 1628 | for (i = 0; i < smmu->num_mapping_groups; ++i) { | 1639 | for (i = 0; i < smmu->num_mapping_groups; ++i) { |
| 1629 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i)); | 1640 | writel_relaxed(0, gr0_base + ARM_SMMU_GR0_SMR(i)); |
| 1630 | writel_relaxed(S2CR_TYPE_BYPASS, | 1641 | writel_relaxed(S2CR_TYPE_BYPASS, |
| 1631 | gr0_base + ARM_SMMU_GR0_S2CR(i)); | 1642 | gr0_base + ARM_SMMU_GR0_S2CR(i)); |
| 1632 | } | 1643 | } |
| @@ -1761,6 +1772,9 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
| 1761 | dev_notice(smmu->dev, | 1772 | dev_notice(smmu->dev, |
| 1762 | "\tstream matching with %u register groups, mask 0x%x", | 1773 | "\tstream matching with %u register groups, mask 0x%x", |
| 1763 | smmu->num_mapping_groups, mask); | 1774 | smmu->num_mapping_groups, mask); |
| 1775 | } else { | ||
| 1776 | smmu->num_mapping_groups = (id >> ID0_NUMSIDB_SHIFT) & | ||
| 1777 | ID0_NUMSIDB_MASK; | ||
| 1764 | } | 1778 | } |
| 1765 | 1779 | ||
| 1766 | /* ID1 */ | 1780 | /* ID1 */ |
| @@ -1794,11 +1808,16 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
| 1794 | * Stage-1 output limited by stage-2 input size due to pgd | 1808 | * Stage-1 output limited by stage-2 input size due to pgd |
| 1795 | * allocation (PTRS_PER_PGD). | 1809 | * allocation (PTRS_PER_PGD). |
| 1796 | */ | 1810 | */ |
| 1811 | if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { | ||
| 1797 | #ifdef CONFIG_64BIT | 1812 | #ifdef CONFIG_64BIT |
| 1798 | smmu->s1_output_size = min_t(unsigned long, VA_BITS, size); | 1813 | smmu->s1_output_size = min_t(unsigned long, VA_BITS, size); |
| 1799 | #else | 1814 | #else |
| 1800 | smmu->s1_output_size = min(32UL, size); | 1815 | smmu->s1_output_size = min(32UL, size); |
| 1801 | #endif | 1816 | #endif |
| 1817 | } else { | ||
| 1818 | smmu->s1_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, | ||
| 1819 | size); | ||
| 1820 | } | ||
| 1802 | 1821 | ||
| 1803 | /* The stage-2 output mask is also applied for bypass */ | 1822 | /* The stage-2 output mask is also applied for bypass */ |
| 1804 | size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); | 1823 | size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); |
| @@ -1889,6 +1908,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1889 | smmu->irqs[i] = irq; | 1908 | smmu->irqs[i] = irq; |
| 1890 | } | 1909 | } |
| 1891 | 1910 | ||
| 1911 | err = arm_smmu_device_cfg_probe(smmu); | ||
| 1912 | if (err) | ||
| 1913 | return err; | ||
| 1914 | |||
| 1892 | i = 0; | 1915 | i = 0; |
| 1893 | smmu->masters = RB_ROOT; | 1916 | smmu->masters = RB_ROOT; |
| 1894 | while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters", | 1917 | while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters", |
| @@ -1905,10 +1928,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1905 | } | 1928 | } |
| 1906 | dev_notice(dev, "registered %d master devices\n", i); | 1929 | dev_notice(dev, "registered %d master devices\n", i); |
| 1907 | 1930 | ||
| 1908 | err = arm_smmu_device_cfg_probe(smmu); | ||
| 1909 | if (err) | ||
| 1910 | goto out_put_masters; | ||
| 1911 | |||
| 1912 | parse_driver_options(smmu); | 1931 | parse_driver_options(smmu); |
| 1913 | 1932 | ||
| 1914 | if (smmu->version > 1 && | 1933 | if (smmu->version > 1 && |
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 60ab474bfff3..06d268abe951 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c | |||
| @@ -678,8 +678,7 @@ static int __init dmar_acpi_dev_scope_init(void) | |||
| 678 | andd->device_name); | 678 | andd->device_name); |
| 679 | continue; | 679 | continue; |
| 680 | } | 680 | } |
| 681 | acpi_bus_get_device(h, &adev); | 681 | if (acpi_bus_get_device(h, &adev)) { |
| 682 | if (!adev) { | ||
| 683 | pr_err("Failed to get device for ACPI object %s\n", | 682 | pr_err("Failed to get device for ACPI object %s\n", |
| 684 | andd->device_name); | 683 | andd->device_name); |
| 685 | continue; | 684 | continue; |
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c index 61d1dafa242d..56feed7cec15 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c | |||
| @@ -984,7 +984,7 @@ static int fsl_pamu_add_device(struct device *dev) | |||
| 984 | struct iommu_group *group = ERR_PTR(-ENODEV); | 984 | struct iommu_group *group = ERR_PTR(-ENODEV); |
| 985 | struct pci_dev *pdev; | 985 | struct pci_dev *pdev; |
| 986 | const u32 *prop; | 986 | const u32 *prop; |
| 987 | int ret, len; | 987 | int ret = 0, len; |
| 988 | 988 | ||
| 989 | /* | 989 | /* |
| 990 | * For platform devices we allocate a separate group for | 990 | * For platform devices we allocate a separate group for |
| @@ -1007,7 +1007,13 @@ static int fsl_pamu_add_device(struct device *dev) | |||
| 1007 | if (IS_ERR(group)) | 1007 | if (IS_ERR(group)) |
| 1008 | return PTR_ERR(group); | 1008 | return PTR_ERR(group); |
| 1009 | 1009 | ||
| 1010 | ret = iommu_group_add_device(group, dev); | 1010 | /* |
| 1011 | * Check if device has already been added to an iommu group. | ||
| 1012 | * Group could have already been created for a PCI device in | ||
| 1013 | * the iommu_group_get_for_dev path. | ||
| 1014 | */ | ||
| 1015 | if (!dev->iommu_group) | ||
| 1016 | ret = iommu_group_add_device(group, dev); | ||
| 1011 | 1017 | ||
| 1012 | iommu_group_put(group); | 1018 | iommu_group_put(group); |
| 1013 | return ret; | 1019 | return ret; |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d1f5caad04f9..5619f264862d 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -3869,6 +3869,14 @@ static int device_notifier(struct notifier_block *nb, | |||
| 3869 | action != BUS_NOTIFY_DEL_DEVICE) | 3869 | action != BUS_NOTIFY_DEL_DEVICE) |
| 3870 | return 0; | 3870 | return 0; |
| 3871 | 3871 | ||
| 3872 | /* | ||
| 3873 | * If the device is still attached to a device driver we can't | ||
| 3874 | * tear down the domain yet as DMA mappings may still be in use. | ||
| 3875 | * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. | ||
| 3876 | */ | ||
| 3877 | if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) | ||
| 3878 | return 0; | ||
| 3879 | |||
| 3872 | domain = find_domain(dev); | 3880 | domain = find_domain(dev); |
| 3873 | if (!domain) | 3881 | if (!domain) |
| 3874 | return 0; | 3882 | return 0; |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 169836020208..0639b9274b11 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
| @@ -678,15 +678,17 @@ static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev) | |||
| 678 | */ | 678 | */ |
| 679 | struct iommu_group *iommu_group_get_for_dev(struct device *dev) | 679 | struct iommu_group *iommu_group_get_for_dev(struct device *dev) |
| 680 | { | 680 | { |
| 681 | struct iommu_group *group = ERR_PTR(-EIO); | 681 | struct iommu_group *group; |
| 682 | int ret; | 682 | int ret; |
| 683 | 683 | ||
| 684 | group = iommu_group_get(dev); | 684 | group = iommu_group_get(dev); |
| 685 | if (group) | 685 | if (group) |
| 686 | return group; | 686 | return group; |
| 687 | 687 | ||
| 688 | if (dev_is_pci(dev)) | 688 | if (!dev_is_pci(dev)) |
| 689 | group = iommu_group_get_for_pci_dev(to_pci_dev(dev)); | 689 | return ERR_PTR(-EINVAL); |
| 690 | |||
| 691 | group = iommu_group_get_for_pci_dev(to_pci_dev(dev)); | ||
| 690 | 692 | ||
| 691 | if (IS_ERR(group)) | 693 | if (IS_ERR(group)) |
| 692 | return group; | 694 | return group; |
| @@ -995,7 +997,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
| 995 | size_t orig_size = size; | 997 | size_t orig_size = size; |
| 996 | int ret = 0; | 998 | int ret = 0; |
| 997 | 999 | ||
| 998 | if (unlikely(domain->ops->unmap == NULL || | 1000 | if (unlikely(domain->ops->map == NULL || |
| 999 | domain->ops->pgsize_bitmap == 0UL)) | 1001 | domain->ops->pgsize_bitmap == 0UL)) |
| 1000 | return -ENODEV; | 1002 | return -ENODEV; |
| 1001 | 1003 | ||
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index f8636a650cf6..5945223b73fa 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
| 17 | #include <linux/irqchip/chained_irq.h> | 17 | #include <linux/irqchip/chained_irq.h> |
| 18 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
| 19 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
| 20 | 21 | ||
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 85c2985d8bcb..bbbaf5de65d2 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c | |||
| @@ -220,7 +220,7 @@ static int __init crossbar_of_init(struct device_node *node) | |||
| 220 | of_property_read_u32_index(node, | 220 | of_property_read_u32_index(node, |
| 221 | "ti,irqs-reserved", | 221 | "ti,irqs-reserved", |
| 222 | i, &entry); | 222 | i, &entry); |
| 223 | if (entry > max) { | 223 | if (entry >= max) { |
| 224 | pr_err("Invalid reserved entry\n"); | 224 | pr_err("Invalid reserved entry\n"); |
| 225 | ret = -EINVAL; | 225 | ret = -EINVAL; |
| 226 | goto err_irq_map; | 226 | goto err_irq_map; |
| @@ -238,7 +238,7 @@ static int __init crossbar_of_init(struct device_node *node) | |||
| 238 | of_property_read_u32_index(node, | 238 | of_property_read_u32_index(node, |
| 239 | "ti,irqs-skip", | 239 | "ti,irqs-skip", |
| 240 | i, &entry); | 240 | i, &entry); |
| 241 | if (entry > max) { | 241 | if (entry >= max) { |
| 242 | pr_err("Invalid skip entry\n"); | 242 | pr_err("Invalid skip entry\n"); |
| 243 | ret = -EINVAL; | 243 | ret = -EINVAL; |
| 244 | goto err_irq_map; | 244 | goto err_irq_map; |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 57eaa5a0b1e3..a0698b4f0303 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | struct gic_chip_data { | 36 | struct gic_chip_data { |
| 37 | void __iomem *dist_base; | 37 | void __iomem *dist_base; |
| 38 | void __iomem **redist_base; | 38 | void __iomem **redist_base; |
| 39 | void __percpu __iomem **rdist; | 39 | void __iomem * __percpu *rdist; |
| 40 | struct irq_domain *domain; | 40 | struct irq_domain *domain; |
| 41 | u64 redist_stride; | 41 | u64 redist_stride; |
| 42 | u32 redist_regions; | 42 | u32 redist_regions; |
| @@ -104,7 +104,7 @@ static void gic_redist_wait_for_rwp(void) | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | /* Low level accessors */ | 106 | /* Low level accessors */ |
| 107 | static u64 gic_read_iar(void) | 107 | static u64 __maybe_unused gic_read_iar(void) |
| 108 | { | 108 | { |
| 109 | u64 irqstat; | 109 | u64 irqstat; |
| 110 | 110 | ||
| @@ -112,24 +112,24 @@ static u64 gic_read_iar(void) | |||
| 112 | return irqstat; | 112 | return irqstat; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static void gic_write_pmr(u64 val) | 115 | static void __maybe_unused gic_write_pmr(u64 val) |
| 116 | { | 116 | { |
| 117 | asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); | 117 | asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static void gic_write_ctlr(u64 val) | 120 | static void __maybe_unused gic_write_ctlr(u64 val) |
| 121 | { | 121 | { |
| 122 | asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); | 122 | asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); |
| 123 | isb(); | 123 | isb(); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | static void gic_write_grpen1(u64 val) | 126 | static void __maybe_unused gic_write_grpen1(u64 val) |
| 127 | { | 127 | { |
| 128 | asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); | 128 | asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); |
| 129 | isb(); | 129 | isb(); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static void gic_write_sgi1r(u64 val) | 132 | static void __maybe_unused gic_write_sgi1r(u64 val) |
| 133 | { | 133 | { |
| 134 | asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); | 134 | asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); |
| 135 | } | 135 | } |
| @@ -200,19 +200,6 @@ static void gic_poke_irq(struct irq_data *d, u32 offset) | |||
| 200 | rwp_wait(); | 200 | rwp_wait(); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static int gic_peek_irq(struct irq_data *d, u32 offset) | ||
| 204 | { | ||
| 205 | u32 mask = 1 << (gic_irq(d) % 32); | ||
| 206 | void __iomem *base; | ||
| 207 | |||
| 208 | if (gic_irq_in_rdist(d)) | ||
| 209 | base = gic_data_rdist_sgi_base(); | ||
| 210 | else | ||
| 211 | base = gic_data.dist_base; | ||
| 212 | |||
| 213 | return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void gic_mask_irq(struct irq_data *d) | 203 | static void gic_mask_irq(struct irq_data *d) |
| 217 | { | 204 | { |
| 218 | gic_poke_irq(d, GICD_ICENABLER); | 205 | gic_poke_irq(d, GICD_ICENABLER); |
| @@ -401,6 +388,19 @@ static void gic_cpu_init(void) | |||
| 401 | } | 388 | } |
| 402 | 389 | ||
| 403 | #ifdef CONFIG_SMP | 390 | #ifdef CONFIG_SMP |
| 391 | static int gic_peek_irq(struct irq_data *d, u32 offset) | ||
| 392 | { | ||
| 393 | u32 mask = 1 << (gic_irq(d) % 32); | ||
| 394 | void __iomem *base; | ||
| 395 | |||
| 396 | if (gic_irq_in_rdist(d)) | ||
| 397 | base = gic_data_rdist_sgi_base(); | ||
| 398 | else | ||
| 399 | base = gic_data.dist_base; | ||
| 400 | |||
| 401 | return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); | ||
| 402 | } | ||
| 403 | |||
| 404 | static int gic_secondary_init(struct notifier_block *nfb, | 404 | static int gic_secondary_init(struct notifier_block *nfb, |
| 405 | unsigned long action, void *hcpu) | 405 | unsigned long action, void *hcpu) |
| 406 | { | 406 | { |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4b959e606fe8..dda6dbc23565 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
| @@ -867,7 +867,7 @@ static int gic_routable_irq_domain_xlate(struct irq_domain *d, | |||
| 867 | return 0; | 867 | return 0; |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | const struct irq_domain_ops gic_default_routable_irq_domain_ops = { | 870 | static const struct irq_domain_ops gic_default_routable_irq_domain_ops = { |
| 871 | .map = gic_routable_irq_domain_map, | 871 | .map = gic_routable_irq_domain_map, |
| 872 | .unmap = gic_routable_irq_domain_unmap, | 872 | .unmap = gic_routable_irq_domain_unmap, |
| 873 | .xlate = gic_routable_irq_domain_xlate, | 873 | .xlate = gic_routable_irq_domain_xlate, |
diff --git a/drivers/isdn/hardware/eicon/xdi_msg.h b/drivers/isdn/hardware/eicon/xdi_msg.h index 58368f7b5cba..2498c349a32e 100644 --- a/drivers/isdn/hardware/eicon/xdi_msg.h +++ b/drivers/isdn/hardware/eicon/xdi_msg.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */ | 1 | /* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */ |
| 2 | 2 | ||
| 3 | #ifndef __DIVA_XDI_UM_CFG_MESSSGE_H__ | 3 | #ifndef __DIVA_XDI_UM_CFG_MESSAGE_H__ |
| 4 | #define __DIVA_XDI_UM_CFG_MESSAGE_H__ | 4 | #define __DIVA_XDI_UM_CFG_MESSAGE_H__ |
| 5 | 5 | ||
| 6 | /* | 6 | /* |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 129729d35478..aa29198fca3e 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
| @@ -15,10 +15,10 @@ | |||
| 15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
| 16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
| 17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
| 18 | #include <linux/timer.h> | ||
| 18 | #include <linux/err.h> | 19 | #include <linux/err.h> |
| 19 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
| 20 | #include <linux/leds.h> | 21 | #include <linux/leds.h> |
| 21 | #include <linux/workqueue.h> | ||
| 22 | #include "leds.h" | 22 | #include "leds.h" |
| 23 | 23 | ||
| 24 | static struct class *leds_class; | 24 | static struct class *leds_class; |
| @@ -97,10 +97,9 @@ static const struct attribute_group *led_groups[] = { | |||
| 97 | NULL, | 97 | NULL, |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | static void led_work_function(struct work_struct *ws) | 100 | static void led_timer_function(unsigned long data) |
| 101 | { | 101 | { |
| 102 | struct led_classdev *led_cdev = | 102 | struct led_classdev *led_cdev = (void *)data; |
| 103 | container_of(ws, struct led_classdev, blink_work.work); | ||
| 104 | unsigned long brightness; | 103 | unsigned long brightness; |
| 105 | unsigned long delay; | 104 | unsigned long delay; |
| 106 | 105 | ||
| @@ -144,8 +143,7 @@ static void led_work_function(struct work_struct *ws) | |||
| 144 | } | 143 | } |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | queue_delayed_work(system_wq, &led_cdev->blink_work, | 146 | mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); |
| 148 | msecs_to_jiffies(delay)); | ||
| 149 | } | 147 | } |
| 150 | 148 | ||
| 151 | static void set_brightness_delayed(struct work_struct *ws) | 149 | static void set_brightness_delayed(struct work_struct *ws) |
| @@ -233,7 +231,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
| 233 | 231 | ||
| 234 | INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); | 232 | INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); |
| 235 | 233 | ||
| 236 | INIT_DELAYED_WORK(&led_cdev->blink_work, led_work_function); | 234 | init_timer(&led_cdev->blink_timer); |
| 235 | led_cdev->blink_timer.function = led_timer_function; | ||
| 236 | led_cdev->blink_timer.data = (unsigned long)led_cdev; | ||
| 237 | 237 | ||
| 238 | #ifdef CONFIG_LEDS_TRIGGERS | 238 | #ifdef CONFIG_LEDS_TRIGGERS |
| 239 | led_trigger_set_default(led_cdev); | 239 | led_trigger_set_default(led_cdev); |
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 4bb116867b88..71b40d3bf776 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/rwsem.h> | 17 | #include <linux/rwsem.h> |
| 18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
| 19 | #include <linux/workqueue.h> | ||
| 20 | #include "leds.h" | 19 | #include "leds.h" |
| 21 | 20 | ||
| 22 | DECLARE_RWSEM(leds_list_lock); | 21 | DECLARE_RWSEM(leds_list_lock); |
| @@ -52,7 +51,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev, | |||
| 52 | return; | 51 | return; |
| 53 | } | 52 | } |
| 54 | 53 | ||
| 55 | queue_delayed_work(system_wq, &led_cdev->blink_work, 1); | 54 | mod_timer(&led_cdev->blink_timer, jiffies + 1); |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | 57 | ||
| @@ -76,7 +75,7 @@ void led_blink_set(struct led_classdev *led_cdev, | |||
| 76 | unsigned long *delay_on, | 75 | unsigned long *delay_on, |
| 77 | unsigned long *delay_off) | 76 | unsigned long *delay_off) |
| 78 | { | 77 | { |
| 79 | cancel_delayed_work_sync(&led_cdev->blink_work); | 78 | del_timer_sync(&led_cdev->blink_timer); |
| 80 | 79 | ||
| 81 | led_cdev->flags &= ~LED_BLINK_ONESHOT; | 80 | led_cdev->flags &= ~LED_BLINK_ONESHOT; |
| 82 | led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; | 81 | led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; |
| @@ -91,7 +90,7 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev, | |||
| 91 | int invert) | 90 | int invert) |
| 92 | { | 91 | { |
| 93 | if ((led_cdev->flags & LED_BLINK_ONESHOT) && | 92 | if ((led_cdev->flags & LED_BLINK_ONESHOT) && |
| 94 | delayed_work_pending(&led_cdev->blink_work)) | 93 | timer_pending(&led_cdev->blink_timer)) |
| 95 | return; | 94 | return; |
| 96 | 95 | ||
| 97 | led_cdev->flags |= LED_BLINK_ONESHOT; | 96 | led_cdev->flags |= LED_BLINK_ONESHOT; |
| @@ -108,7 +107,7 @@ EXPORT_SYMBOL(led_blink_set_oneshot); | |||
| 108 | 107 | ||
| 109 | void led_stop_software_blink(struct led_classdev *led_cdev) | 108 | void led_stop_software_blink(struct led_classdev *led_cdev) |
| 110 | { | 109 | { |
| 111 | cancel_delayed_work_sync(&led_cdev->blink_work); | 110 | del_timer_sync(&led_cdev->blink_timer); |
| 112 | led_cdev->blink_delay_on = 0; | 111 | led_cdev->blink_delay_on = 0; |
| 113 | led_cdev->blink_delay_off = 0; | 112 | led_cdev->blink_delay_off = 0; |
| 114 | } | 113 | } |
| @@ -117,7 +116,7 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink); | |||
| 117 | void led_set_brightness(struct led_classdev *led_cdev, | 116 | void led_set_brightness(struct led_classdev *led_cdev, |
| 118 | enum led_brightness brightness) | 117 | enum led_brightness brightness) |
| 119 | { | 118 | { |
| 120 | /* delay brightness setting if need to stop soft-blink work */ | 119 | /* delay brightness setting if need to stop soft-blink timer */ |
| 121 | if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { | 120 | if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { |
| 122 | led_cdev->delayed_set_value = brightness; | 121 | led_cdev->delayed_set_value = brightness; |
| 123 | schedule_work(&led_cdev->set_brightness_work); | 122 | schedule_work(&led_cdev->set_brightness_work); |
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1af40ee209e2..7130505c2425 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
| @@ -895,8 +895,8 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) | |||
| 895 | struct cache *cache = mg->cache; | 895 | struct cache *cache = mg->cache; |
| 896 | 896 | ||
| 897 | if (mg->writeback) { | 897 | if (mg->writeback) { |
| 898 | cell_defer(cache, mg->old_ocell, false); | ||
| 899 | clear_dirty(cache, mg->old_oblock, mg->cblock); | 898 | clear_dirty(cache, mg->old_oblock, mg->cblock); |
| 899 | cell_defer(cache, mg->old_ocell, false); | ||
| 900 | cleanup_migration(mg); | 900 | cleanup_migration(mg); |
| 901 | return; | 901 | return; |
| 902 | 902 | ||
| @@ -951,13 +951,13 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) | |||
| 951 | } | 951 | } |
| 952 | 952 | ||
| 953 | } else { | 953 | } else { |
| 954 | clear_dirty(cache, mg->new_oblock, mg->cblock); | ||
| 954 | if (mg->requeue_holder) | 955 | if (mg->requeue_holder) |
| 955 | cell_defer(cache, mg->new_ocell, true); | 956 | cell_defer(cache, mg->new_ocell, true); |
| 956 | else { | 957 | else { |
| 957 | bio_endio(mg->new_ocell->holder, 0); | 958 | bio_endio(mg->new_ocell->holder, 0); |
| 958 | cell_defer(cache, mg->new_ocell, false); | 959 | cell_defer(cache, mg->new_ocell, false); |
| 959 | } | 960 | } |
| 960 | clear_dirty(cache, mg->new_oblock, mg->cblock); | ||
| 961 | cleanup_migration(mg); | 961 | cleanup_migration(mg); |
| 962 | } | 962 | } |
| 963 | } | 963 | } |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 2785007e0e46..cd15e0801228 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -1688,6 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 1688 | unsigned int key_size, opt_params; | 1688 | unsigned int key_size, opt_params; |
| 1689 | unsigned long long tmpll; | 1689 | unsigned long long tmpll; |
| 1690 | int ret; | 1690 | int ret; |
| 1691 | size_t iv_size_padding; | ||
| 1691 | struct dm_arg_set as; | 1692 | struct dm_arg_set as; |
| 1692 | const char *opt_string; | 1693 | const char *opt_string; |
| 1693 | char dummy; | 1694 | char dummy; |
| @@ -1724,20 +1725,32 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 1724 | 1725 | ||
| 1725 | cc->dmreq_start = sizeof(struct ablkcipher_request); | 1726 | cc->dmreq_start = sizeof(struct ablkcipher_request); |
| 1726 | cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc)); | 1727 | cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc)); |
| 1727 | cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment()); | 1728 | cc->dmreq_start = ALIGN(cc->dmreq_start, __alignof__(struct dm_crypt_request)); |
| 1728 | cc->dmreq_start += crypto_ablkcipher_alignmask(any_tfm(cc)) & | 1729 | |
| 1729 | ~(crypto_tfm_ctx_alignment() - 1); | 1730 | if (crypto_ablkcipher_alignmask(any_tfm(cc)) < CRYPTO_MINALIGN) { |
| 1731 | /* Allocate the padding exactly */ | ||
| 1732 | iv_size_padding = -(cc->dmreq_start + sizeof(struct dm_crypt_request)) | ||
| 1733 | & crypto_ablkcipher_alignmask(any_tfm(cc)); | ||
| 1734 | } else { | ||
| 1735 | /* | ||
| 1736 | * If the cipher requires greater alignment than kmalloc | ||
| 1737 | * alignment, we don't know the exact position of the | ||
| 1738 | * initialization vector. We must assume worst case. | ||
| 1739 | */ | ||
| 1740 | iv_size_padding = crypto_ablkcipher_alignmask(any_tfm(cc)); | ||
| 1741 | } | ||
| 1730 | 1742 | ||
| 1731 | cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start + | 1743 | cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start + |
| 1732 | sizeof(struct dm_crypt_request) + cc->iv_size); | 1744 | sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size); |
| 1733 | if (!cc->req_pool) { | 1745 | if (!cc->req_pool) { |
| 1734 | ti->error = "Cannot allocate crypt request mempool"; | 1746 | ti->error = "Cannot allocate crypt request mempool"; |
| 1735 | goto bad; | 1747 | goto bad; |
| 1736 | } | 1748 | } |
| 1737 | 1749 | ||
| 1738 | cc->per_bio_data_size = ti->per_bio_data_size = | 1750 | cc->per_bio_data_size = ti->per_bio_data_size = |
| 1739 | sizeof(struct dm_crypt_io) + cc->dmreq_start + | 1751 | ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + |
| 1740 | sizeof(struct dm_crypt_request) + cc->iv_size; | 1752 | sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size, |
| 1753 | ARCH_KMALLOC_MINALIGN); | ||
| 1741 | 1754 | ||
| 1742 | cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); | 1755 | cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); |
| 1743 | if (!cc->page_pool) { | 1756 | if (!cc->page_pool) { |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b08c18871323..6703751d87d7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 2953 | */ | 2953 | */ |
| 2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { | 2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { |
| 2955 | end_reshape(conf); | 2955 | end_reshape(conf); |
| 2956 | close_sync(conf); | ||
| 2956 | return 0; | 2957 | return 0; |
| 2957 | } | 2958 | } |
| 2958 | 2959 | ||
| @@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 3081 | } | 3082 | } |
| 3082 | 3083 | ||
| 3083 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3084 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 3085 | r10_bio->state = 0; | ||
| 3084 | raise_barrier(conf, rb2 != NULL); | 3086 | raise_barrier(conf, rb2 != NULL); |
| 3085 | atomic_set(&r10_bio->remaining, 0); | 3087 | atomic_set(&r10_bio->remaining, 0); |
| 3086 | 3088 | ||
| @@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 3269 | if (sync_blocks < max_sync) | 3271 | if (sync_blocks < max_sync) |
| 3270 | max_sync = sync_blocks; | 3272 | max_sync = sync_blocks; |
| 3271 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3273 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 3274 | r10_bio->state = 0; | ||
| 3272 | 3275 | ||
| 3273 | r10_bio->mddev = mddev; | 3276 | r10_bio->mddev = mddev; |
| 3274 | atomic_set(&r10_bio->remaining, 0); | 3277 | atomic_set(&r10_bio->remaining, 0); |
| @@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, | |||
| 4384 | read_more: | 4387 | read_more: |
| 4385 | /* Now schedule reads for blocks from sector_nr to last */ | 4388 | /* Now schedule reads for blocks from sector_nr to last */ |
| 4386 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 4389 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
| 4390 | r10_bio->state = 0; | ||
| 4387 | raise_barrier(conf, sectors_done != 0); | 4391 | raise_barrier(conf, sectors_done != 0); |
| 4388 | atomic_set(&r10_bio->remaining, 0); | 4392 | atomic_set(&r10_bio->remaining, 0); |
| 4389 | r10_bio->mddev = mddev; | 4393 | r10_bio->mddev = mddev; |
| @@ -4398,6 +4402,7 @@ read_more: | |||
| 4398 | * on all the target devices. | 4402 | * on all the target devices. |
| 4399 | */ | 4403 | */ |
| 4400 | // FIXME | 4404 | // FIXME |
| 4405 | mempool_free(r10_bio, conf->r10buf_pool); | ||
| 4401 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4406 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 4402 | return sectors_done; | 4407 | return sectors_done; |
| 4403 | } | 4408 | } |
| @@ -4410,7 +4415,7 @@ read_more: | |||
| 4410 | read_bio->bi_private = r10_bio; | 4415 | read_bio->bi_private = r10_bio; |
| 4411 | read_bio->bi_end_io = end_sync_read; | 4416 | read_bio->bi_end_io = end_sync_read; |
| 4412 | read_bio->bi_rw = READ; | 4417 | read_bio->bi_rw = READ; |
| 4413 | read_bio->bi_flags &= ~(BIO_POOL_MASK - 1); | 4418 | read_bio->bi_flags &= (~0UL << BIO_RESET_BITS); |
| 4414 | read_bio->bi_flags |= 1 << BIO_UPTODATE; | 4419 | read_bio->bi_flags |= 1 << BIO_UPTODATE; |
| 4415 | read_bio->bi_vcnt = 0; | 4420 | read_bio->bi_vcnt = 0; |
| 4416 | read_bio->bi_iter.bi_size = 0; | 4421 | read_bio->bi_iter.bi_size = 0; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 6234b2e84587..183588b11fc1 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, | |||
| 2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && | 2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && |
| 2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || | 2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || |
| 2924 | (sh->raid_conf->level == 6 && s->failed && s->to_write && | 2924 | (sh->raid_conf->level == 6 && s->failed && s->to_write && |
| 2925 | s->to_write < sh->raid_conf->raid_disks - 2 && | 2925 | s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 && |
| 2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { | 2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { |
| 2927 | /* we would like to get this block, possibly by computing it, | 2927 | /* we would like to get this block, possibly by computing it, |
| 2928 | * otherwise read it if the backing disk is insync | 2928 | * otherwise read it if the backing disk is insync |
| @@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh) | |||
| 3817 | set_bit(R5_Wantwrite, &dev->flags); | 3817 | set_bit(R5_Wantwrite, &dev->flags); |
| 3818 | if (prexor) | 3818 | if (prexor) |
| 3819 | continue; | 3819 | continue; |
| 3820 | if (s.failed > 1) | ||
| 3821 | continue; | ||
| 3820 | if (!test_bit(R5_Insync, &dev->flags) || | 3822 | if (!test_bit(R5_Insync, &dev->flags) || |
| 3821 | ((i == sh->pd_idx || i == sh->qd_idx) && | 3823 | ((i == sh->pd_idx || i == sh->qd_idx) && |
| 3822 | s.failed == 0)) | 3824 | s.failed == 0)) |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index ce48aa72bb42..bde2fc072410 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
| @@ -1754,7 +1754,7 @@ static int ab8500_probe(struct platform_device *pdev) | |||
| 1754 | if (ret) | 1754 | if (ret) |
| 1755 | return ret; | 1755 | return ret; |
| 1756 | 1756 | ||
| 1757 | #if CONFIG_DEBUG_FS | 1757 | #ifdef CONFIG_DEBUG_FS |
| 1758 | /* Pass to debugfs */ | 1758 | /* Pass to debugfs */ |
| 1759 | ab8500_debug_resources[0].start = ab8500->irq; | 1759 | ab8500_debug_resources[0].start = ab8500->irq; |
| 1760 | ab8500_debug_resources[0].end = ab8500->irq; | 1760 | ab8500_debug_resources[0].end = ab8500->irq; |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index b44f0203983b..6bdb78c2ac77 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
| @@ -404,7 +404,7 @@ static int htcpld_register_chip_i2c( | |||
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | i2c_set_clientdata(client, chip); | 406 | i2c_set_clientdata(client, chip); |
| 407 | snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr); | 407 | snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr); |
| 408 | chip->client = client; | 408 | chip->client = client; |
| 409 | 409 | ||
| 410 | /* Reset the chip */ | 410 | /* Reset the chip */ |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 33a9234b701c..83dab2f0a50e 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
| @@ -647,7 +647,7 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
| 647 | default: | 647 | default: |
| 648 | omap->nports = OMAP3_HS_USB_PORTS; | 648 | omap->nports = OMAP3_HS_USB_PORTS; |
| 649 | dev_dbg(dev, | 649 | dev_dbg(dev, |
| 650 | "USB HOST Rev:0x%d not recognized, assuming %d ports\n", | 650 | "USB HOST Rev:0x%x not recognized, assuming %d ports\n", |
| 651 | omap->usbhs_rev, omap->nports); | 651 | omap->usbhs_rev, omap->nports); |
| 652 | break; | 652 | break; |
| 653 | } | 653 | } |
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 3bc969a5916b..4d3ff3771491 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c | |||
| @@ -724,24 +724,24 @@ static struct twl4030_script *omap3_idle_scripts[] = { | |||
| 724 | * above. | 724 | * above. |
| 725 | */ | 725 | */ |
| 726 | static struct twl4030_resconfig omap3_idle_rconfig[] = { | 726 | static struct twl4030_resconfig omap3_idle_rconfig[] = { |
| 727 | TWL_REMAP_SLEEP(RES_VAUX1, DEV_GRP_NULL, 0, 0), | 727 | TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 728 | TWL_REMAP_SLEEP(RES_VAUX2, DEV_GRP_NULL, 0, 0), | 728 | TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 729 | TWL_REMAP_SLEEP(RES_VAUX3, DEV_GRP_NULL, 0, 0), | 729 | TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 730 | TWL_REMAP_SLEEP(RES_VAUX4, DEV_GRP_NULL, 0, 0), | 730 | TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 731 | TWL_REMAP_SLEEP(RES_VMMC1, DEV_GRP_NULL, 0, 0), | 731 | TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 732 | TWL_REMAP_SLEEP(RES_VMMC2, DEV_GRP_NULL, 0, 0), | 732 | TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 733 | TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), | 733 | TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), |
| 734 | TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), | 734 | TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), |
| 735 | TWL_REMAP_SLEEP(RES_VSIM, DEV_GRP_NULL, 0, 0), | 735 | TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 736 | TWL_REMAP_SLEEP(RES_VDAC, DEV_GRP_NULL, 0, 0), | 736 | TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 737 | TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), | 737 | TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), |
| 738 | TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), | 738 | TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), |
| 739 | TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), | 739 | TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), |
| 740 | TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), | 740 | TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), |
| 741 | TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), | 741 | TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), |
| 742 | TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), | 742 | TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), |
| 743 | TWL_REMAP_SLEEP(RES_VUSB_1V5, DEV_GRP_NULL, 0, 0), | 743 | TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 744 | TWL_REMAP_SLEEP(RES_VUSB_1V8, DEV_GRP_NULL, 0, 0), | 744 | TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0), |
| 745 | TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), | 745 | TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), |
| 746 | /* Resource #20 USB charge pump skipped */ | 746 | /* Resource #20 USB charge pump skipped */ |
| 747 | TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), | 747 | TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), |
diff --git a/drivers/misc/lattice-ecp3-config.c b/drivers/misc/lattice-ecp3-config.c index 7ffdb589841e..7e1efd5f58f0 100644 --- a/drivers/misc/lattice-ecp3-config.c +++ b/drivers/misc/lattice-ecp3-config.c | |||
| @@ -79,6 +79,11 @@ static void firmware_load(const struct firmware *fw, void *context) | |||
| 79 | u32 jedec_id; | 79 | u32 jedec_id; |
| 80 | u32 status; | 80 | u32 status; |
| 81 | 81 | ||
| 82 | if (fw == NULL) { | ||
| 83 | dev_err(&spi->dev, "Cannot load firmware, aborting\n"); | ||
| 84 | return; | ||
| 85 | } | ||
| 86 | |||
| 82 | if (fw->size == 0) { | 87 | if (fw->size == 0) { |
| 83 | dev_err(&spi->dev, "Error: Firmware size is 0!\n"); | 88 | dev_err(&spi->dev, "Error: Firmware size is 0!\n"); |
| 84 | return; | 89 | return; |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 324e1de93687..2da05c0e113d 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
| @@ -601,6 +601,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) | |||
| 601 | cl->timer_count = MEI_CONNECT_TIMEOUT; | 601 | cl->timer_count = MEI_CONNECT_TIMEOUT; |
| 602 | list_add_tail(&cb->list, &dev->ctrl_rd_list.list); | 602 | list_add_tail(&cb->list, &dev->ctrl_rd_list.list); |
| 603 | } else { | 603 | } else { |
| 604 | cl->state = MEI_FILE_INITIALIZING; | ||
| 604 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | 605 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); |
| 605 | } | 606 | } |
| 606 | 607 | ||
diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 3095fc514a65..5ccc23bc7690 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c | |||
| @@ -342,9 +342,10 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) | |||
| 342 | ndev = (struct mei_nfc_dev *) cldev->priv_data; | 342 | ndev = (struct mei_nfc_dev *) cldev->priv_data; |
| 343 | dev = ndev->cl->dev; | 343 | dev = ndev->cl->dev; |
| 344 | 344 | ||
| 345 | err = -ENOMEM; | ||
| 345 | mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); | 346 | mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); |
| 346 | if (!mei_buf) | 347 | if (!mei_buf) |
| 347 | return -ENOMEM; | 348 | goto out; |
| 348 | 349 | ||
| 349 | hdr = (struct mei_nfc_hci_hdr *) mei_buf; | 350 | hdr = (struct mei_nfc_hci_hdr *) mei_buf; |
| 350 | hdr->cmd = MEI_NFC_CMD_HCI_SEND; | 351 | hdr->cmd = MEI_NFC_CMD_HCI_SEND; |
| @@ -354,12 +355,9 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) | |||
| 354 | hdr->data_size = length; | 355 | hdr->data_size = length; |
| 355 | 356 | ||
| 356 | memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); | 357 | memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); |
| 357 | |||
| 358 | err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); | 358 | err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); |
| 359 | if (err < 0) | 359 | if (err < 0) |
| 360 | return err; | 360 | goto out; |
| 361 | |||
| 362 | kfree(mei_buf); | ||
| 363 | 361 | ||
| 364 | if (!wait_event_interruptible_timeout(ndev->send_wq, | 362 | if (!wait_event_interruptible_timeout(ndev->send_wq, |
| 365 | ndev->recv_req_id == ndev->req_id, HZ)) { | 363 | ndev->recv_req_id == ndev->req_id, HZ)) { |
| @@ -368,7 +366,8 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) | |||
| 368 | } else { | 366 | } else { |
| 369 | ndev->req_id++; | 367 | ndev->req_id++; |
| 370 | } | 368 | } |
| 371 | 369 | out: | |
| 370 | kfree(mei_buf); | ||
| 372 | return err; | 371 | return err; |
| 373 | } | 372 | } |
| 374 | 373 | ||
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5a4bfe33112a..46c4643b7a07 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
| @@ -1434,6 +1434,10 @@ static int cfi_amdstd_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 1434 | 1434 | ||
| 1435 | mutex_lock(&chip->mutex); | 1435 | mutex_lock(&chip->mutex); |
| 1436 | ret = get_chip(map, chip, base, FL_LOCKING); | 1436 | ret = get_chip(map, chip, base, FL_LOCKING); |
| 1437 | if (ret) { | ||
| 1438 | mutex_unlock(&chip->mutex); | ||
| 1439 | return ret; | ||
| 1440 | } | ||
| 1437 | 1441 | ||
| 1438 | /* Enter lock register command */ | 1442 | /* Enter lock register command */ |
| 1439 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, | 1443 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f0ed92e210a1..5967b385141b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -931,7 +931,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
| 931 | u32 val; | 931 | u32 val; |
| 932 | 932 | ||
| 933 | val = readl(info->reg.gpmc_ecc_config); | 933 | val = readl(info->reg.gpmc_ecc_config); |
| 934 | if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) | 934 | if (((val >> ECC_CONFIG_CS_SHIFT) & CS_MASK) != info->gpmc_cs) |
| 935 | return -EINVAL; | 935 | return -EINVAL; |
| 936 | 936 | ||
| 937 | /* read ecc result */ | 937 | /* read ecc result */ |
| @@ -1794,9 +1794,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1794 | } | 1794 | } |
| 1795 | 1795 | ||
| 1796 | /* populate MTD interface based on ECC scheme */ | 1796 | /* populate MTD interface based on ECC scheme */ |
| 1797 | nand_chip->ecc.layout = &omap_oobinfo; | ||
| 1798 | ecclayout = &omap_oobinfo; | 1797 | ecclayout = &omap_oobinfo; |
| 1799 | switch (info->ecc_opt) { | 1798 | switch (info->ecc_opt) { |
| 1799 | case OMAP_ECC_HAM1_CODE_SW: | ||
| 1800 | nand_chip->ecc.mode = NAND_ECC_SOFT; | ||
| 1801 | break; | ||
| 1802 | |||
| 1800 | case OMAP_ECC_HAM1_CODE_HW: | 1803 | case OMAP_ECC_HAM1_CODE_HW: |
| 1801 | pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n"); | 1804 | pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n"); |
| 1802 | nand_chip->ecc.mode = NAND_ECC_HW; | 1805 | nand_chip->ecc.mode = NAND_ECC_HW; |
| @@ -1848,7 +1851,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1848 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1851 | nand_chip->ecc.priv = nand_bch_init(mtd, |
| 1849 | nand_chip->ecc.size, | 1852 | nand_chip->ecc.size, |
| 1850 | nand_chip->ecc.bytes, | 1853 | nand_chip->ecc.bytes, |
| 1851 | &nand_chip->ecc.layout); | 1854 | &ecclayout); |
| 1852 | if (!nand_chip->ecc.priv) { | 1855 | if (!nand_chip->ecc.priv) { |
| 1853 | pr_err("nand: error: unable to use s/w BCH library\n"); | 1856 | pr_err("nand: error: unable to use s/w BCH library\n"); |
| 1854 | err = -EINVAL; | 1857 | err = -EINVAL; |
| @@ -1923,7 +1926,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1923 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1926 | nand_chip->ecc.priv = nand_bch_init(mtd, |
| 1924 | nand_chip->ecc.size, | 1927 | nand_chip->ecc.size, |
| 1925 | nand_chip->ecc.bytes, | 1928 | nand_chip->ecc.bytes, |
| 1926 | &nand_chip->ecc.layout); | 1929 | &ecclayout); |
| 1927 | if (!nand_chip->ecc.priv) { | 1930 | if (!nand_chip->ecc.priv) { |
| 1928 | pr_err("nand: error: unable to use s/w BCH library\n"); | 1931 | pr_err("nand: error: unable to use s/w BCH library\n"); |
| 1929 | err = -EINVAL; | 1932 | err = -EINVAL; |
| @@ -2012,6 +2015,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 2012 | goto return_error; | 2015 | goto return_error; |
| 2013 | } | 2016 | } |
| 2014 | 2017 | ||
| 2018 | if (info->ecc_opt == OMAP_ECC_HAM1_CODE_SW) | ||
| 2019 | goto scan_tail; | ||
| 2020 | |||
| 2015 | /* all OOB bytes from oobfree->offset till end off OOB are free */ | 2021 | /* all OOB bytes from oobfree->offset till end off OOB are free */ |
| 2016 | ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; | 2022 | ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; |
| 2017 | /* check if NAND device's OOB is enough to store ECC signatures */ | 2023 | /* check if NAND device's OOB is enough to store ECC signatures */ |
| @@ -2021,7 +2027,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 2021 | err = -EINVAL; | 2027 | err = -EINVAL; |
| 2022 | goto return_error; | 2028 | goto return_error; |
| 2023 | } | 2029 | } |
| 2030 | nand_chip->ecc.layout = ecclayout; | ||
| 2024 | 2031 | ||
| 2032 | scan_tail: | ||
| 2025 | /* second phase scan */ | 2033 | /* second phase scan */ |
| 2026 | if (nand_scan_tail(mtd)) { | 2034 | if (nand_scan_tail(mtd)) { |
| 2027 | err = -ENXIO; | 2035 | err = -ENXIO; |
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 5dede6e64376..109cb44291f5 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
| @@ -280,7 +280,7 @@ static int c_can_plat_probe(struct platform_device *pdev) | |||
| 280 | 280 | ||
| 281 | priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, | 281 | priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, |
| 282 | resource_size(res)); | 282 | resource_size(res)); |
| 283 | if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) | 283 | if (!priv->raminit_ctrlreg || priv->instance < 0) |
| 284 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); | 284 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); |
| 285 | else | 285 | else |
| 286 | priv->raminit = c_can_hw_raminit_ti; | 286 | priv->raminit = c_can_hw_raminit_ti; |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index f425ec2c7839..944aa5d3af6e 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -549,6 +549,13 @@ static void do_state(struct net_device *dev, | |||
| 549 | 549 | ||
| 550 | /* process state changes depending on the new state */ | 550 | /* process state changes depending on the new state */ |
| 551 | switch (new_state) { | 551 | switch (new_state) { |
| 552 | case CAN_STATE_ERROR_WARNING: | ||
| 553 | netdev_dbg(dev, "Error Warning\n"); | ||
| 554 | cf->can_id |= CAN_ERR_CRTL; | ||
| 555 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
| 556 | CAN_ERR_CRTL_TX_WARNING : | ||
| 557 | CAN_ERR_CRTL_RX_WARNING; | ||
| 558 | break; | ||
| 552 | case CAN_STATE_ERROR_ACTIVE: | 559 | case CAN_STATE_ERROR_ACTIVE: |
| 553 | netdev_dbg(dev, "Error Active\n"); | 560 | netdev_dbg(dev, "Error Active\n"); |
| 554 | cf->can_id |= CAN_ERR_PROT; | 561 | cf->can_id |= CAN_ERR_PROT; |
| @@ -852,6 +859,8 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 852 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || | 859 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || |
| 853 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 860 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
| 854 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; | 861 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; |
| 862 | else | ||
| 863 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK; | ||
| 855 | 864 | ||
| 856 | /* save for later use */ | 865 | /* save for later use */ |
| 857 | priv->reg_ctrl_default = reg_ctrl; | 866 | priv->reg_ctrl_default = reg_ctrl; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index d1692154ed1b..b27ac6074afb 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
| @@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev) | |||
| 172 | netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); | 172 | netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | /* | ||
| 176 | * initialize SJA1000 chip: | ||
| 177 | * - reset chip | ||
| 178 | * - set output mode | ||
| 179 | * - set baudrate | ||
| 180 | * - enable interrupts | ||
| 181 | * - start operating mode | ||
| 182 | */ | ||
| 183 | static void chipset_init(struct net_device *dev) | ||
| 184 | { | ||
| 185 | struct sja1000_priv *priv = netdev_priv(dev); | ||
| 186 | |||
| 187 | /* set clock divider and output control register */ | ||
| 188 | priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); | ||
| 189 | |||
| 190 | /* set acceptance filter (accept all) */ | ||
| 191 | priv->write_reg(priv, SJA1000_ACCC0, 0x00); | ||
| 192 | priv->write_reg(priv, SJA1000_ACCC1, 0x00); | ||
| 193 | priv->write_reg(priv, SJA1000_ACCC2, 0x00); | ||
| 194 | priv->write_reg(priv, SJA1000_ACCC3, 0x00); | ||
| 195 | |||
| 196 | priv->write_reg(priv, SJA1000_ACCM0, 0xFF); | ||
| 197 | priv->write_reg(priv, SJA1000_ACCM1, 0xFF); | ||
| 198 | priv->write_reg(priv, SJA1000_ACCM2, 0xFF); | ||
| 199 | priv->write_reg(priv, SJA1000_ACCM3, 0xFF); | ||
| 200 | |||
| 201 | priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); | ||
| 202 | } | ||
| 203 | |||
| 175 | static void sja1000_start(struct net_device *dev) | 204 | static void sja1000_start(struct net_device *dev) |
| 176 | { | 205 | { |
| 177 | struct sja1000_priv *priv = netdev_priv(dev); | 206 | struct sja1000_priv *priv = netdev_priv(dev); |
| @@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev) | |||
| 180 | if (priv->can.state != CAN_STATE_STOPPED) | 209 | if (priv->can.state != CAN_STATE_STOPPED) |
| 181 | set_reset_mode(dev); | 210 | set_reset_mode(dev); |
| 182 | 211 | ||
| 212 | /* Initialize chip if uninitialized at this stage */ | ||
| 213 | if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN)) | ||
| 214 | chipset_init(dev); | ||
| 215 | |||
| 183 | /* Clear error counters and error code capture */ | 216 | /* Clear error counters and error code capture */ |
| 184 | priv->write_reg(priv, SJA1000_TXERR, 0x0); | 217 | priv->write_reg(priv, SJA1000_TXERR, 0x0); |
| 185 | priv->write_reg(priv, SJA1000_RXERR, 0x0); | 218 | priv->write_reg(priv, SJA1000_RXERR, 0x0); |
| @@ -237,35 +270,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev, | |||
| 237 | } | 270 | } |
| 238 | 271 | ||
| 239 | /* | 272 | /* |
| 240 | * initialize SJA1000 chip: | ||
| 241 | * - reset chip | ||
| 242 | * - set output mode | ||
| 243 | * - set baudrate | ||
| 244 | * - enable interrupts | ||
| 245 | * - start operating mode | ||
| 246 | */ | ||
| 247 | static void chipset_init(struct net_device *dev) | ||
| 248 | { | ||
| 249 | struct sja1000_priv *priv = netdev_priv(dev); | ||
| 250 | |||
| 251 | /* set clock divider and output control register */ | ||
| 252 | priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); | ||
| 253 | |||
| 254 | /* set acceptance filter (accept all) */ | ||
| 255 | priv->write_reg(priv, SJA1000_ACCC0, 0x00); | ||
| 256 | priv->write_reg(priv, SJA1000_ACCC1, 0x00); | ||
| 257 | priv->write_reg(priv, SJA1000_ACCC2, 0x00); | ||
| 258 | priv->write_reg(priv, SJA1000_ACCC3, 0x00); | ||
| 259 | |||
| 260 | priv->write_reg(priv, SJA1000_ACCM0, 0xFF); | ||
| 261 | priv->write_reg(priv, SJA1000_ACCM1, 0xFF); | ||
| 262 | priv->write_reg(priv, SJA1000_ACCM2, 0xFF); | ||
| 263 | priv->write_reg(priv, SJA1000_ACCM3, 0xFF); | ||
| 264 | |||
| 265 | priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); | ||
| 266 | } | ||
| 267 | |||
| 268 | /* | ||
| 269 | * transmit a CAN message | 273 | * transmit a CAN message |
| 270 | * message layout in the sk_buff should be like this: | 274 | * message layout in the sk_buff should be like this: |
| 271 | * xx xx xx xx ff ll 00 11 22 33 44 55 66 77 | 275 | * xx xx xx xx ff ll 00 11 22 33 44 55 66 77 |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 059c7414e303..3fe45c705933 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
| @@ -2177,10 +2177,10 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 2177 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 2177 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
| 2178 | 2178 | ||
| 2179 | vp->tx_ring[entry].frag[i+1].addr = | 2179 | vp->tx_ring[entry].frag[i+1].addr = |
| 2180 | cpu_to_le32(pci_map_single( | 2180 | cpu_to_le32(skb_frag_dma_map( |
| 2181 | VORTEX_PCI(vp), | 2181 | &VORTEX_PCI(vp)->dev, |
| 2182 | (void *)skb_frag_address(frag), | 2182 | frag, |
| 2183 | skb_frag_size(frag), PCI_DMA_TODEVICE)); | 2183 | frag->page_offset, frag->size, DMA_TO_DEVICE)); |
| 2184 | 2184 | ||
| 2185 | if (i == skb_shinfo(skb)->nr_frags-1) | 2185 | if (i == skb_shinfo(skb)->nr_frags-1) |
| 2186 | vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG); | 2186 | vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG); |
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 23578dfee249..3005155e412b 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c | |||
| @@ -123,6 +123,12 @@ static inline void greth_enable_tx(struct greth_private *greth) | |||
| 123 | GRETH_REGORIN(greth->regs->control, GRETH_TXEN); | 123 | GRETH_REGORIN(greth->regs->control, GRETH_TXEN); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | static inline void greth_enable_tx_and_irq(struct greth_private *greth) | ||
| 127 | { | ||
| 128 | wmb(); /* BDs must been written to memory before enabling TX */ | ||
| 129 | GRETH_REGORIN(greth->regs->control, GRETH_TXEN | GRETH_TXI); | ||
| 130 | } | ||
| 131 | |||
| 126 | static inline void greth_disable_tx(struct greth_private *greth) | 132 | static inline void greth_disable_tx(struct greth_private *greth) |
| 127 | { | 133 | { |
| 128 | GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN); | 134 | GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN); |
| @@ -447,29 +453,30 @@ out: | |||
| 447 | return err; | 453 | return err; |
| 448 | } | 454 | } |
| 449 | 455 | ||
| 456 | static inline u16 greth_num_free_bds(u16 tx_last, u16 tx_next) | ||
| 457 | { | ||
| 458 | if (tx_next < tx_last) | ||
| 459 | return (tx_last - tx_next) - 1; | ||
| 460 | else | ||
| 461 | return GRETH_TXBD_NUM - (tx_next - tx_last) - 1; | ||
| 462 | } | ||
| 450 | 463 | ||
| 451 | static netdev_tx_t | 464 | static netdev_tx_t |
| 452 | greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | 465 | greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) |
| 453 | { | 466 | { |
| 454 | struct greth_private *greth = netdev_priv(dev); | 467 | struct greth_private *greth = netdev_priv(dev); |
| 455 | struct greth_bd *bdp; | 468 | struct greth_bd *bdp; |
| 456 | u32 status = 0, dma_addr, ctrl; | 469 | u32 status, dma_addr; |
| 457 | int curr_tx, nr_frags, i, err = NETDEV_TX_OK; | 470 | int curr_tx, nr_frags, i, err = NETDEV_TX_OK; |
| 458 | unsigned long flags; | 471 | unsigned long flags; |
| 472 | u16 tx_last; | ||
| 459 | 473 | ||
| 460 | nr_frags = skb_shinfo(skb)->nr_frags; | 474 | nr_frags = skb_shinfo(skb)->nr_frags; |
| 475 | tx_last = greth->tx_last; | ||
| 476 | rmb(); /* tx_last is updated by the poll task */ | ||
| 461 | 477 | ||
| 462 | /* Clean TX Ring */ | 478 | if (greth_num_free_bds(tx_last, greth->tx_next) < nr_frags + 1) { |
| 463 | greth_clean_tx_gbit(dev); | ||
| 464 | |||
| 465 | if (greth->tx_free < nr_frags + 1) { | ||
| 466 | spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ | ||
| 467 | ctrl = GRETH_REGLOAD(greth->regs->control); | ||
| 468 | /* Enable TX IRQ only if not already in poll() routine */ | ||
| 469 | if (ctrl & GRETH_RXI) | ||
| 470 | GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); | ||
| 471 | netif_stop_queue(dev); | 479 | netif_stop_queue(dev); |
| 472 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 473 | err = NETDEV_TX_BUSY; | 480 | err = NETDEV_TX_BUSY; |
| 474 | goto out; | 481 | goto out; |
| 475 | } | 482 | } |
| @@ -488,6 +495,8 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 488 | /* Linear buf */ | 495 | /* Linear buf */ |
| 489 | if (nr_frags != 0) | 496 | if (nr_frags != 0) |
| 490 | status = GRETH_TXBD_MORE; | 497 | status = GRETH_TXBD_MORE; |
| 498 | else | ||
| 499 | status = GRETH_BD_IE; | ||
| 491 | 500 | ||
| 492 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 501 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 493 | status |= GRETH_TXBD_CSALL; | 502 | status |= GRETH_TXBD_CSALL; |
| @@ -545,14 +554,12 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 545 | 554 | ||
| 546 | /* Enable the descriptor chain by enabling the first descriptor */ | 555 | /* Enable the descriptor chain by enabling the first descriptor */ |
| 547 | bdp = greth->tx_bd_base + greth->tx_next; | 556 | bdp = greth->tx_bd_base + greth->tx_next; |
| 548 | greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN); | 557 | greth_write_bd(&bdp->stat, |
| 549 | greth->tx_next = curr_tx; | 558 | greth_read_bd(&bdp->stat) | GRETH_BD_EN); |
| 550 | greth->tx_free -= nr_frags + 1; | ||
| 551 | |||
| 552 | wmb(); | ||
| 553 | 559 | ||
| 554 | spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ | 560 | spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ |
| 555 | greth_enable_tx(greth); | 561 | greth->tx_next = curr_tx; |
| 562 | greth_enable_tx_and_irq(greth); | ||
| 556 | spin_unlock_irqrestore(&greth->devlock, flags); | 563 | spin_unlock_irqrestore(&greth->devlock, flags); |
| 557 | 564 | ||
| 558 | return NETDEV_TX_OK; | 565 | return NETDEV_TX_OK; |
| @@ -648,7 +655,6 @@ static void greth_clean_tx(struct net_device *dev) | |||
| 648 | if (greth->tx_free > 0) { | 655 | if (greth->tx_free > 0) { |
| 649 | netif_wake_queue(dev); | 656 | netif_wake_queue(dev); |
| 650 | } | 657 | } |
| 651 | |||
| 652 | } | 658 | } |
| 653 | 659 | ||
| 654 | static inline void greth_update_tx_stats(struct net_device *dev, u32 stat) | 660 | static inline void greth_update_tx_stats(struct net_device *dev, u32 stat) |
| @@ -670,20 +676,22 @@ static void greth_clean_tx_gbit(struct net_device *dev) | |||
| 670 | { | 676 | { |
| 671 | struct greth_private *greth; | 677 | struct greth_private *greth; |
| 672 | struct greth_bd *bdp, *bdp_last_frag; | 678 | struct greth_bd *bdp, *bdp_last_frag; |
| 673 | struct sk_buff *skb; | 679 | struct sk_buff *skb = NULL; |
| 674 | u32 stat; | 680 | u32 stat; |
| 675 | int nr_frags, i; | 681 | int nr_frags, i; |
| 682 | u16 tx_last; | ||
| 676 | 683 | ||
| 677 | greth = netdev_priv(dev); | 684 | greth = netdev_priv(dev); |
| 685 | tx_last = greth->tx_last; | ||
| 678 | 686 | ||
| 679 | while (greth->tx_free < GRETH_TXBD_NUM) { | 687 | while (tx_last != greth->tx_next) { |
| 680 | 688 | ||
| 681 | skb = greth->tx_skbuff[greth->tx_last]; | 689 | skb = greth->tx_skbuff[tx_last]; |
| 682 | 690 | ||
| 683 | nr_frags = skb_shinfo(skb)->nr_frags; | 691 | nr_frags = skb_shinfo(skb)->nr_frags; |
| 684 | 692 | ||
| 685 | /* We only clean fully completed SKBs */ | 693 | /* We only clean fully completed SKBs */ |
| 686 | bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags); | 694 | bdp_last_frag = greth->tx_bd_base + SKIP_TX(tx_last, nr_frags); |
| 687 | 695 | ||
| 688 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); | 696 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); |
| 689 | mb(); | 697 | mb(); |
| @@ -692,14 +700,14 @@ static void greth_clean_tx_gbit(struct net_device *dev) | |||
| 692 | if (stat & GRETH_BD_EN) | 700 | if (stat & GRETH_BD_EN) |
| 693 | break; | 701 | break; |
| 694 | 702 | ||
| 695 | greth->tx_skbuff[greth->tx_last] = NULL; | 703 | greth->tx_skbuff[tx_last] = NULL; |
| 696 | 704 | ||
| 697 | greth_update_tx_stats(dev, stat); | 705 | greth_update_tx_stats(dev, stat); |
| 698 | dev->stats.tx_bytes += skb->len; | 706 | dev->stats.tx_bytes += skb->len; |
| 699 | 707 | ||
| 700 | bdp = greth->tx_bd_base + greth->tx_last; | 708 | bdp = greth->tx_bd_base + tx_last; |
| 701 | 709 | ||
| 702 | greth->tx_last = NEXT_TX(greth->tx_last); | 710 | tx_last = NEXT_TX(tx_last); |
| 703 | 711 | ||
| 704 | dma_unmap_single(greth->dev, | 712 | dma_unmap_single(greth->dev, |
| 705 | greth_read_bd(&bdp->addr), | 713 | greth_read_bd(&bdp->addr), |
| @@ -708,21 +716,26 @@ static void greth_clean_tx_gbit(struct net_device *dev) | |||
| 708 | 716 | ||
| 709 | for (i = 0; i < nr_frags; i++) { | 717 | for (i = 0; i < nr_frags; i++) { |
| 710 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 718 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
| 711 | bdp = greth->tx_bd_base + greth->tx_last; | 719 | bdp = greth->tx_bd_base + tx_last; |
| 712 | 720 | ||
| 713 | dma_unmap_page(greth->dev, | 721 | dma_unmap_page(greth->dev, |
| 714 | greth_read_bd(&bdp->addr), | 722 | greth_read_bd(&bdp->addr), |
| 715 | skb_frag_size(frag), | 723 | skb_frag_size(frag), |
| 716 | DMA_TO_DEVICE); | 724 | DMA_TO_DEVICE); |
| 717 | 725 | ||
| 718 | greth->tx_last = NEXT_TX(greth->tx_last); | 726 | tx_last = NEXT_TX(tx_last); |
| 719 | } | 727 | } |
| 720 | greth->tx_free += nr_frags+1; | ||
| 721 | dev_kfree_skb(skb); | 728 | dev_kfree_skb(skb); |
| 722 | } | 729 | } |
| 730 | if (skb) { /* skb is set only if the above while loop was entered */ | ||
| 731 | wmb(); | ||
| 732 | greth->tx_last = tx_last; | ||
| 723 | 733 | ||
| 724 | if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1))) | 734 | if (netif_queue_stopped(dev) && |
| 725 | netif_wake_queue(dev); | 735 | (greth_num_free_bds(tx_last, greth->tx_next) > |
| 736 | (MAX_SKB_FRAGS+1))) | ||
| 737 | netif_wake_queue(dev); | ||
| 738 | } | ||
| 726 | } | 739 | } |
| 727 | 740 | ||
| 728 | static int greth_rx(struct net_device *dev, int limit) | 741 | static int greth_rx(struct net_device *dev, int limit) |
| @@ -965,16 +978,12 @@ static int greth_poll(struct napi_struct *napi, int budget) | |||
| 965 | greth = container_of(napi, struct greth_private, napi); | 978 | greth = container_of(napi, struct greth_private, napi); |
| 966 | 979 | ||
| 967 | restart_txrx_poll: | 980 | restart_txrx_poll: |
| 968 | if (netif_queue_stopped(greth->netdev)) { | ||
| 969 | if (greth->gbit_mac) | ||
| 970 | greth_clean_tx_gbit(greth->netdev); | ||
| 971 | else | ||
| 972 | greth_clean_tx(greth->netdev); | ||
| 973 | } | ||
| 974 | |||
| 975 | if (greth->gbit_mac) { | 981 | if (greth->gbit_mac) { |
| 982 | greth_clean_tx_gbit(greth->netdev); | ||
| 976 | work_done += greth_rx_gbit(greth->netdev, budget - work_done); | 983 | work_done += greth_rx_gbit(greth->netdev, budget - work_done); |
| 977 | } else { | 984 | } else { |
| 985 | if (netif_queue_stopped(greth->netdev)) | ||
| 986 | greth_clean_tx(greth->netdev); | ||
| 978 | work_done += greth_rx(greth->netdev, budget - work_done); | 987 | work_done += greth_rx(greth->netdev, budget - work_done); |
| 979 | } | 988 | } |
| 980 | 989 | ||
| @@ -983,7 +992,8 @@ restart_txrx_poll: | |||
| 983 | spin_lock_irqsave(&greth->devlock, flags); | 992 | spin_lock_irqsave(&greth->devlock, flags); |
| 984 | 993 | ||
| 985 | ctrl = GRETH_REGLOAD(greth->regs->control); | 994 | ctrl = GRETH_REGLOAD(greth->regs->control); |
| 986 | if (netif_queue_stopped(greth->netdev)) { | 995 | if ((greth->gbit_mac && (greth->tx_last != greth->tx_next)) || |
| 996 | (!greth->gbit_mac && netif_queue_stopped(greth->netdev))) { | ||
| 987 | GRETH_REGSAVE(greth->regs->control, | 997 | GRETH_REGSAVE(greth->regs->control, |
| 988 | ctrl | GRETH_TXI | GRETH_RXI); | 998 | ctrl | GRETH_TXI | GRETH_RXI); |
| 989 | mask = GRETH_INT_RX | GRETH_INT_RE | | 999 | mask = GRETH_INT_RX | GRETH_INT_RE | |
diff --git a/drivers/net/ethernet/aeroflex/greth.h b/drivers/net/ethernet/aeroflex/greth.h index 232a622a85b7..ae16ac94daf8 100644 --- a/drivers/net/ethernet/aeroflex/greth.h +++ b/drivers/net/ethernet/aeroflex/greth.h | |||
| @@ -107,7 +107,7 @@ struct greth_private { | |||
| 107 | 107 | ||
| 108 | u16 tx_next; | 108 | u16 tx_next; |
| 109 | u16 tx_last; | 109 | u16 tx_last; |
| 110 | u16 tx_free; | 110 | u16 tx_free; /* only used on 10/100Mbit */ |
| 111 | u16 rx_cur; | 111 | u16 rx_cur; |
| 112 | 112 | ||
| 113 | struct greth_regs *regs; /* Address of controller registers. */ | 113 | struct greth_regs *regs; /* Address of controller registers. */ |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c index 346592dca33c..a3c11355a34d 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | |||
| @@ -272,8 +272,8 @@ static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer, | |||
| 272 | struct xgbe_prv_data *pdata = filp->private_data; | 272 | struct xgbe_prv_data *pdata = filp->private_data; |
| 273 | unsigned int value; | 273 | unsigned int value; |
| 274 | 274 | ||
| 275 | value = pdata->hw_if.read_mmd_regs(pdata, pdata->debugfs_xpcs_mmd, | 275 | value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd, |
| 276 | pdata->debugfs_xpcs_reg); | 276 | pdata->debugfs_xpcs_reg); |
| 277 | 277 | ||
| 278 | return xgbe_common_read(buffer, count, ppos, value); | 278 | return xgbe_common_read(buffer, count, ppos, value); |
| 279 | } | 279 | } |
| @@ -290,8 +290,8 @@ static ssize_t xpcs_reg_value_write(struct file *filp, | |||
| 290 | if (len < 0) | 290 | if (len < 0) |
| 291 | return len; | 291 | return len; |
| 292 | 292 | ||
| 293 | pdata->hw_if.write_mmd_regs(pdata, pdata->debugfs_xpcs_mmd, | 293 | XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg, |
| 294 | pdata->debugfs_xpcs_reg, value); | 294 | value); |
| 295 | 295 | ||
| 296 | return len; | 296 | return len; |
| 297 | } | 297 | } |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index edaca4496264..ea273836d999 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
| @@ -348,7 +348,7 @@ static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) | |||
| 348 | 348 | ||
| 349 | /* Clear MAC flow control */ | 349 | /* Clear MAC flow control */ |
| 350 | max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; | 350 | max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; |
| 351 | q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count); | 351 | q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); |
| 352 | reg = MAC_Q0TFCR; | 352 | reg = MAC_Q0TFCR; |
| 353 | for (i = 0; i < q_count; i++) { | 353 | for (i = 0; i < q_count; i++) { |
| 354 | reg_val = XGMAC_IOREAD(pdata, reg); | 354 | reg_val = XGMAC_IOREAD(pdata, reg); |
| @@ -373,7 +373,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata) | |||
| 373 | 373 | ||
| 374 | /* Set MAC flow control */ | 374 | /* Set MAC flow control */ |
| 375 | max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; | 375 | max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; |
| 376 | q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count); | 376 | q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); |
| 377 | reg = MAC_Q0TFCR; | 377 | reg = MAC_Q0TFCR; |
| 378 | for (i = 0; i < q_count; i++) { | 378 | for (i = 0; i < q_count; i++) { |
| 379 | reg_val = XGMAC_IOREAD(pdata, reg); | 379 | reg_val = XGMAC_IOREAD(pdata, reg); |
| @@ -509,8 +509,8 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata) | |||
| 509 | XGMAC_IOWRITE(pdata, MAC_IER, mac_ier); | 509 | XGMAC_IOWRITE(pdata, MAC_IER, mac_ier); |
| 510 | 510 | ||
| 511 | /* Enable all counter interrupts */ | 511 | /* Enable all counter interrupts */ |
| 512 | XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xff); | 512 | XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff); |
| 513 | XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xff); | 513 | XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff); |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata) | 516 | static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata) |
| @@ -1633,6 +1633,9 @@ static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata) | |||
| 1633 | { | 1633 | { |
| 1634 | unsigned int i, count; | 1634 | unsigned int i, count; |
| 1635 | 1635 | ||
| 1636 | if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) < 0x21) | ||
| 1637 | return 0; | ||
| 1638 | |||
| 1636 | for (i = 0; i < pdata->tx_q_count; i++) | 1639 | for (i = 0; i < pdata->tx_q_count; i++) |
| 1637 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1); | 1640 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1); |
| 1638 | 1641 | ||
| @@ -1703,8 +1706,8 @@ static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata) | |||
| 1703 | XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP); | 1706 | XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP); |
| 1704 | } | 1707 | } |
| 1705 | 1708 | ||
| 1706 | static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size, | 1709 | static unsigned int xgbe_calculate_per_queue_fifo(unsigned int fifo_size, |
| 1707 | unsigned char queue_count) | 1710 | unsigned int queue_count) |
| 1708 | { | 1711 | { |
| 1709 | unsigned int q_fifo_size = 0; | 1712 | unsigned int q_fifo_size = 0; |
| 1710 | enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256; | 1713 | enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256; |
| @@ -1748,6 +1751,10 @@ static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size, | |||
| 1748 | q_fifo_size = XGBE_FIFO_SIZE_KB(256); | 1751 | q_fifo_size = XGBE_FIFO_SIZE_KB(256); |
| 1749 | break; | 1752 | break; |
| 1750 | } | 1753 | } |
| 1754 | |||
| 1755 | /* The configured value is not the actual amount of fifo RAM */ | ||
| 1756 | q_fifo_size = min_t(unsigned int, XGBE_FIFO_MAX, q_fifo_size); | ||
| 1757 | |||
| 1751 | q_fifo_size = q_fifo_size / queue_count; | 1758 | q_fifo_size = q_fifo_size / queue_count; |
| 1752 | 1759 | ||
| 1753 | /* Set the queue fifo size programmable value */ | 1760 | /* Set the queue fifo size programmable value */ |
| @@ -1947,6 +1954,32 @@ static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata) | |||
| 1947 | xgbe_disable_rx_vlan_stripping(pdata); | 1954 | xgbe_disable_rx_vlan_stripping(pdata); |
| 1948 | } | 1955 | } |
| 1949 | 1956 | ||
| 1957 | static u64 xgbe_mmc_read(struct xgbe_prv_data *pdata, unsigned int reg_lo) | ||
| 1958 | { | ||
| 1959 | bool read_hi; | ||
| 1960 | u64 val; | ||
| 1961 | |||
| 1962 | switch (reg_lo) { | ||
| 1963 | /* These registers are always 64 bit */ | ||
| 1964 | case MMC_TXOCTETCOUNT_GB_LO: | ||
| 1965 | case MMC_TXOCTETCOUNT_G_LO: | ||
| 1966 | case MMC_RXOCTETCOUNT_GB_LO: | ||
| 1967 | case MMC_RXOCTETCOUNT_G_LO: | ||
| 1968 | read_hi = true; | ||
| 1969 | break; | ||
| 1970 | |||
| 1971 | default: | ||
| 1972 | read_hi = false; | ||
| 1973 | }; | ||
| 1974 | |||
| 1975 | val = XGMAC_IOREAD(pdata, reg_lo); | ||
| 1976 | |||
| 1977 | if (read_hi) | ||
| 1978 | val |= ((u64)XGMAC_IOREAD(pdata, reg_lo + 4) << 32); | ||
| 1979 | |||
| 1980 | return val; | ||
| 1981 | } | ||
| 1982 | |||
| 1950 | static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata) | 1983 | static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata) |
| 1951 | { | 1984 | { |
| 1952 | struct xgbe_mmc_stats *stats = &pdata->mmc_stats; | 1985 | struct xgbe_mmc_stats *stats = &pdata->mmc_stats; |
| @@ -1954,75 +1987,75 @@ static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata) | |||
| 1954 | 1987 | ||
| 1955 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB)) | 1988 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB)) |
| 1956 | stats->txoctetcount_gb += | 1989 | stats->txoctetcount_gb += |
| 1957 | XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO); | 1990 | xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO); |
| 1958 | 1991 | ||
| 1959 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB)) | 1992 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB)) |
| 1960 | stats->txframecount_gb += | 1993 | stats->txframecount_gb += |
| 1961 | XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO); | 1994 | xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO); |
| 1962 | 1995 | ||
| 1963 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G)) | 1996 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G)) |
| 1964 | stats->txbroadcastframes_g += | 1997 | stats->txbroadcastframes_g += |
| 1965 | XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO); | 1998 | xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO); |
| 1966 | 1999 | ||
| 1967 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G)) | 2000 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G)) |
| 1968 | stats->txmulticastframes_g += | 2001 | stats->txmulticastframes_g += |
| 1969 | XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO); | 2002 | xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO); |
| 1970 | 2003 | ||
| 1971 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB)) | 2004 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB)) |
| 1972 | stats->tx64octets_gb += | 2005 | stats->tx64octets_gb += |
| 1973 | XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO); | 2006 | xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO); |
| 1974 | 2007 | ||
| 1975 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB)) | 2008 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB)) |
| 1976 | stats->tx65to127octets_gb += | 2009 | stats->tx65to127octets_gb += |
| 1977 | XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO); | 2010 | xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO); |
| 1978 | 2011 | ||
| 1979 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB)) | 2012 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB)) |
| 1980 | stats->tx128to255octets_gb += | 2013 | stats->tx128to255octets_gb += |
| 1981 | XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO); | 2014 | xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO); |
| 1982 | 2015 | ||
| 1983 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB)) | 2016 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB)) |
| 1984 | stats->tx256to511octets_gb += | 2017 | stats->tx256to511octets_gb += |
| 1985 | XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO); | 2018 | xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO); |
| 1986 | 2019 | ||
| 1987 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB)) | 2020 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB)) |
| 1988 | stats->tx512to1023octets_gb += | 2021 | stats->tx512to1023octets_gb += |
| 1989 | XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO); | 2022 | xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO); |
| 1990 | 2023 | ||
| 1991 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB)) | 2024 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB)) |
| 1992 | stats->tx1024tomaxoctets_gb += | 2025 | stats->tx1024tomaxoctets_gb += |
| 1993 | XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); | 2026 | xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); |
| 1994 | 2027 | ||
| 1995 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB)) | 2028 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB)) |
| 1996 | stats->txunicastframes_gb += | 2029 | stats->txunicastframes_gb += |
| 1997 | XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO); | 2030 | xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO); |
| 1998 | 2031 | ||
| 1999 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB)) | 2032 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB)) |
| 2000 | stats->txmulticastframes_gb += | 2033 | stats->txmulticastframes_gb += |
| 2001 | XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO); | 2034 | xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO); |
| 2002 | 2035 | ||
| 2003 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB)) | 2036 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB)) |
| 2004 | stats->txbroadcastframes_g += | 2037 | stats->txbroadcastframes_g += |
| 2005 | XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO); | 2038 | xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO); |
| 2006 | 2039 | ||
| 2007 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR)) | 2040 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR)) |
| 2008 | stats->txunderflowerror += | 2041 | stats->txunderflowerror += |
| 2009 | XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO); | 2042 | xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO); |
| 2010 | 2043 | ||
| 2011 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G)) | 2044 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G)) |
| 2012 | stats->txoctetcount_g += | 2045 | stats->txoctetcount_g += |
| 2013 | XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO); | 2046 | xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO); |
| 2014 | 2047 | ||
| 2015 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G)) | 2048 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G)) |
| 2016 | stats->txframecount_g += | 2049 | stats->txframecount_g += |
| 2017 | XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO); | 2050 | xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO); |
| 2018 | 2051 | ||
| 2019 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES)) | 2052 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES)) |
| 2020 | stats->txpauseframes += | 2053 | stats->txpauseframes += |
| 2021 | XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO); | 2054 | xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO); |
| 2022 | 2055 | ||
| 2023 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G)) | 2056 | if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G)) |
| 2024 | stats->txvlanframes_g += | 2057 | stats->txvlanframes_g += |
| 2025 | XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO); | 2058 | xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO); |
| 2026 | } | 2059 | } |
| 2027 | 2060 | ||
| 2028 | static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata) | 2061 | static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata) |
| @@ -2032,95 +2065,95 @@ static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata) | |||
| 2032 | 2065 | ||
| 2033 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB)) | 2066 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB)) |
| 2034 | stats->rxframecount_gb += | 2067 | stats->rxframecount_gb += |
| 2035 | XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO); | 2068 | xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO); |
| 2036 | 2069 | ||
| 2037 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB)) | 2070 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB)) |
| 2038 | stats->rxoctetcount_gb += | 2071 | stats->rxoctetcount_gb += |
| 2039 | XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO); | 2072 | xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO); |
| 2040 | 2073 | ||
| 2041 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G)) | 2074 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G)) |
| 2042 | stats->rxoctetcount_g += | 2075 | stats->rxoctetcount_g += |
| 2043 | XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO); | 2076 | xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO); |
| 2044 | 2077 | ||
| 2045 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G)) | 2078 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G)) |
| 2046 | stats->rxbroadcastframes_g += | 2079 | stats->rxbroadcastframes_g += |
| 2047 | XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO); | 2080 | xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO); |
| 2048 | 2081 | ||
| 2049 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G)) | 2082 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G)) |
| 2050 | stats->rxmulticastframes_g += | 2083 | stats->rxmulticastframes_g += |
| 2051 | XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO); | 2084 | xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO); |
| 2052 | 2085 | ||
| 2053 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR)) | 2086 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR)) |
| 2054 | stats->rxcrcerror += | 2087 | stats->rxcrcerror += |
| 2055 | XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO); | 2088 | xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO); |
| 2056 | 2089 | ||
| 2057 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR)) | 2090 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR)) |
| 2058 | stats->rxrunterror += | 2091 | stats->rxrunterror += |
| 2059 | XGMAC_IOREAD(pdata, MMC_RXRUNTERROR); | 2092 | xgbe_mmc_read(pdata, MMC_RXRUNTERROR); |
| 2060 | 2093 | ||
| 2061 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR)) | 2094 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR)) |
| 2062 | stats->rxjabbererror += | 2095 | stats->rxjabbererror += |
| 2063 | XGMAC_IOREAD(pdata, MMC_RXJABBERERROR); | 2096 | xgbe_mmc_read(pdata, MMC_RXJABBERERROR); |
| 2064 | 2097 | ||
| 2065 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G)) | 2098 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G)) |
| 2066 | stats->rxundersize_g += | 2099 | stats->rxundersize_g += |
| 2067 | XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G); | 2100 | xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G); |
| 2068 | 2101 | ||
| 2069 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G)) | 2102 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G)) |
| 2070 | stats->rxoversize_g += | 2103 | stats->rxoversize_g += |
| 2071 | XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G); | 2104 | xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G); |
| 2072 | 2105 | ||
| 2073 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB)) | 2106 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB)) |
| 2074 | stats->rx64octets_gb += | 2107 | stats->rx64octets_gb += |
| 2075 | XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO); | 2108 | xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO); |
| 2076 | 2109 | ||
| 2077 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB)) | 2110 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB)) |
| 2078 | stats->rx65to127octets_gb += | 2111 | stats->rx65to127octets_gb += |
| 2079 | XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO); | 2112 | xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO); |
| 2080 | 2113 | ||
| 2081 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB)) | 2114 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB)) |
| 2082 | stats->rx128to255octets_gb += | 2115 | stats->rx128to255octets_gb += |
| 2083 | XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO); | 2116 | xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO); |
| 2084 | 2117 | ||
| 2085 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB)) | 2118 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB)) |
| 2086 | stats->rx256to511octets_gb += | 2119 | stats->rx256to511octets_gb += |
| 2087 | XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO); | 2120 | xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO); |
| 2088 | 2121 | ||
| 2089 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB)) | 2122 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB)) |
| 2090 | stats->rx512to1023octets_gb += | 2123 | stats->rx512to1023octets_gb += |
| 2091 | XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO); | 2124 | xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO); |
| 2092 | 2125 | ||
| 2093 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB)) | 2126 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB)) |
| 2094 | stats->rx1024tomaxoctets_gb += | 2127 | stats->rx1024tomaxoctets_gb += |
| 2095 | XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); | 2128 | xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); |
| 2096 | 2129 | ||
| 2097 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G)) | 2130 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G)) |
| 2098 | stats->rxunicastframes_g += | 2131 | stats->rxunicastframes_g += |
| 2099 | XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO); | 2132 | xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO); |
| 2100 | 2133 | ||
| 2101 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR)) | 2134 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR)) |
| 2102 | stats->rxlengtherror += | 2135 | stats->rxlengtherror += |
| 2103 | XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO); | 2136 | xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO); |
| 2104 | 2137 | ||
| 2105 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE)) | 2138 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE)) |
| 2106 | stats->rxoutofrangetype += | 2139 | stats->rxoutofrangetype += |
| 2107 | XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO); | 2140 | xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO); |
| 2108 | 2141 | ||
| 2109 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES)) | 2142 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES)) |
| 2110 | stats->rxpauseframes += | 2143 | stats->rxpauseframes += |
| 2111 | XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO); | 2144 | xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO); |
| 2112 | 2145 | ||
| 2113 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW)) | 2146 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW)) |
| 2114 | stats->rxfifooverflow += | 2147 | stats->rxfifooverflow += |
| 2115 | XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO); | 2148 | xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO); |
| 2116 | 2149 | ||
| 2117 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB)) | 2150 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB)) |
| 2118 | stats->rxvlanframes_gb += | 2151 | stats->rxvlanframes_gb += |
| 2119 | XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO); | 2152 | xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO); |
| 2120 | 2153 | ||
| 2121 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR)) | 2154 | if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR)) |
| 2122 | stats->rxwatchdogerror += | 2155 | stats->rxwatchdogerror += |
| 2123 | XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR); | 2156 | xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR); |
| 2124 | } | 2157 | } |
| 2125 | 2158 | ||
| 2126 | static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata) | 2159 | static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata) |
| @@ -2131,127 +2164,127 @@ static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata) | |||
| 2131 | XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1); | 2164 | XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1); |
| 2132 | 2165 | ||
| 2133 | stats->txoctetcount_gb += | 2166 | stats->txoctetcount_gb += |
| 2134 | XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO); | 2167 | xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO); |
| 2135 | 2168 | ||
| 2136 | stats->txframecount_gb += | 2169 | stats->txframecount_gb += |
| 2137 | XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO); | 2170 | xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO); |
| 2138 | 2171 | ||
| 2139 | stats->txbroadcastframes_g += | 2172 | stats->txbroadcastframes_g += |
| 2140 | XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO); | 2173 | xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO); |
| 2141 | 2174 | ||
| 2142 | stats->txmulticastframes_g += | 2175 | stats->txmulticastframes_g += |
| 2143 | XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO); | 2176 | xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO); |
| 2144 | 2177 | ||
| 2145 | stats->tx64octets_gb += | 2178 | stats->tx64octets_gb += |
| 2146 | XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO); | 2179 | xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO); |
| 2147 | 2180 | ||
| 2148 | stats->tx65to127octets_gb += | 2181 | stats->tx65to127octets_gb += |
| 2149 | XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO); | 2182 | xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO); |
| 2150 | 2183 | ||
| 2151 | stats->tx128to255octets_gb += | 2184 | stats->tx128to255octets_gb += |
| 2152 | XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO); | 2185 | xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO); |
| 2153 | 2186 | ||
| 2154 | stats->tx256to511octets_gb += | 2187 | stats->tx256to511octets_gb += |
| 2155 | XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO); | 2188 | xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO); |
| 2156 | 2189 | ||
| 2157 | stats->tx512to1023octets_gb += | 2190 | stats->tx512to1023octets_gb += |
| 2158 | XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO); | 2191 | xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO); |
| 2159 | 2192 | ||
| 2160 | stats->tx1024tomaxoctets_gb += | 2193 | stats->tx1024tomaxoctets_gb += |
| 2161 | XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); | 2194 | xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); |
| 2162 | 2195 | ||
| 2163 | stats->txunicastframes_gb += | 2196 | stats->txunicastframes_gb += |
| 2164 | XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO); | 2197 | xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO); |
| 2165 | 2198 | ||
| 2166 | stats->txmulticastframes_gb += | 2199 | stats->txmulticastframes_gb += |
| 2167 | XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO); | 2200 | xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO); |
| 2168 | 2201 | ||
| 2169 | stats->txbroadcastframes_g += | 2202 | stats->txbroadcastframes_g += |
| 2170 | XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO); | 2203 | xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO); |
| 2171 | 2204 | ||
| 2172 | stats->txunderflowerror += | 2205 | stats->txunderflowerror += |
| 2173 | XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO); | 2206 | xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO); |
| 2174 | 2207 | ||
| 2175 | stats->txoctetcount_g += | 2208 | stats->txoctetcount_g += |
| 2176 | XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO); | 2209 | xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO); |
| 2177 | 2210 | ||
| 2178 | stats->txframecount_g += | 2211 | stats->txframecount_g += |
| 2179 | XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO); | 2212 | xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO); |
| 2180 | 2213 | ||
| 2181 | stats->txpauseframes += | 2214 | stats->txpauseframes += |
| 2182 | XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO); | 2215 | xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO); |
| 2183 | 2216 | ||
| 2184 | stats->txvlanframes_g += | 2217 | stats->txvlanframes_g += |
| 2185 | XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO); | 2218 | xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO); |
| 2186 | 2219 | ||
| 2187 | stats->rxframecount_gb += | 2220 | stats->rxframecount_gb += |
| 2188 | XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO); | 2221 | xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO); |
| 2189 | 2222 | ||
| 2190 | stats->rxoctetcount_gb += | 2223 | stats->rxoctetcount_gb += |
| 2191 | XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO); | 2224 | xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO); |
| 2192 | 2225 | ||
| 2193 | stats->rxoctetcount_g += | 2226 | stats->rxoctetcount_g += |
| 2194 | XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO); | 2227 | xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO); |
| 2195 | 2228 | ||
| 2196 | stats->rxbroadcastframes_g += | 2229 | stats->rxbroadcastframes_g += |
| 2197 | XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO); | 2230 | xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO); |
| 2198 | 2231 | ||
| 2199 | stats->rxmulticastframes_g += | 2232 | stats->rxmulticastframes_g += |
| 2200 | XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO); | 2233 | xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO); |
| 2201 | 2234 | ||
| 2202 | stats->rxcrcerror += | 2235 | stats->rxcrcerror += |
| 2203 | XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO); | 2236 | xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO); |
| 2204 | 2237 | ||
| 2205 | stats->rxrunterror += | 2238 | stats->rxrunterror += |
| 2206 | XGMAC_IOREAD(pdata, MMC_RXRUNTERROR); | 2239 | xgbe_mmc_read(pdata, MMC_RXRUNTERROR); |
| 2207 | 2240 | ||
| 2208 | stats->rxjabbererror += | 2241 | stats->rxjabbererror += |
| 2209 | XGMAC_IOREAD(pdata, MMC_RXJABBERERROR); | 2242 | xgbe_mmc_read(pdata, MMC_RXJABBERERROR); |
| 2210 | 2243 | ||
| 2211 | stats->rxundersize_g += | 2244 | stats->rxundersize_g += |
| 2212 | XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G); | 2245 | xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G); |
| 2213 | 2246 | ||
| 2214 | stats->rxoversize_g += | 2247 | stats->rxoversize_g += |
| 2215 | XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G); | 2248 | xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G); |
| 2216 | 2249 | ||
| 2217 | stats->rx64octets_gb += | 2250 | stats->rx64octets_gb += |
| 2218 | XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO); | 2251 | xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO); |
| 2219 | 2252 | ||
| 2220 | stats->rx65to127octets_gb += | 2253 | stats->rx65to127octets_gb += |
| 2221 | XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO); | 2254 | xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO); |
| 2222 | 2255 | ||
| 2223 | stats->rx128to255octets_gb += | 2256 | stats->rx128to255octets_gb += |
| 2224 | XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO); | 2257 | xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO); |
| 2225 | 2258 | ||
| 2226 | stats->rx256to511octets_gb += | 2259 | stats->rx256to511octets_gb += |
| 2227 | XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO); | 2260 | xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO); |
| 2228 | 2261 | ||
| 2229 | stats->rx512to1023octets_gb += | 2262 | stats->rx512to1023octets_gb += |
| 2230 | XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO); | 2263 | xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO); |
| 2231 | 2264 | ||
| 2232 | stats->rx1024tomaxoctets_gb += | 2265 | stats->rx1024tomaxoctets_gb += |
| 2233 | XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); | 2266 | xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); |
| 2234 | 2267 | ||
| 2235 | stats->rxunicastframes_g += | 2268 | stats->rxunicastframes_g += |
| 2236 | XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO); | 2269 | xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO); |
| 2237 | 2270 | ||
| 2238 | stats->rxlengtherror += | 2271 | stats->rxlengtherror += |
| 2239 | XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO); | 2272 | xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO); |
| 2240 | 2273 | ||
| 2241 | stats->rxoutofrangetype += | 2274 | stats->rxoutofrangetype += |
| 2242 | XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO); | 2275 | xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO); |
| 2243 | 2276 | ||
| 2244 | stats->rxpauseframes += | 2277 | stats->rxpauseframes += |
| 2245 | XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO); | 2278 | xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO); |
| 2246 | 2279 | ||
| 2247 | stats->rxfifooverflow += | 2280 | stats->rxfifooverflow += |
| 2248 | XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO); | 2281 | xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO); |
| 2249 | 2282 | ||
| 2250 | stats->rxvlanframes_gb += | 2283 | stats->rxvlanframes_gb += |
| 2251 | XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO); | 2284 | xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO); |
| 2252 | 2285 | ||
| 2253 | stats->rxwatchdogerror += | 2286 | stats->rxwatchdogerror += |
| 2254 | XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR); | 2287 | xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR); |
| 2255 | 2288 | ||
| 2256 | /* Un-freeze counters */ | 2289 | /* Un-freeze counters */ |
| 2257 | XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0); | 2290 | XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index dc84f7193c2d..b26d75856553 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | |||
| @@ -361,6 +361,8 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata) | |||
| 361 | 361 | ||
| 362 | memset(hw_feat, 0, sizeof(*hw_feat)); | 362 | memset(hw_feat, 0, sizeof(*hw_feat)); |
| 363 | 363 | ||
| 364 | hw_feat->version = XGMAC_IOREAD(pdata, MAC_VR); | ||
| 365 | |||
| 364 | /* Hardware feature register 0 */ | 366 | /* Hardware feature register 0 */ |
| 365 | hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL); | 367 | hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL); |
| 366 | hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH); | 368 | hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c index a076aca138a1..46f613028e9c 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | |||
| @@ -361,15 +361,16 @@ static void xgbe_get_drvinfo(struct net_device *netdev, | |||
| 361 | struct ethtool_drvinfo *drvinfo) | 361 | struct ethtool_drvinfo *drvinfo) |
| 362 | { | 362 | { |
| 363 | struct xgbe_prv_data *pdata = netdev_priv(netdev); | 363 | struct xgbe_prv_data *pdata = netdev_priv(netdev); |
| 364 | struct xgbe_hw_features *hw_feat = &pdata->hw_feat; | ||
| 364 | 365 | ||
| 365 | strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver)); | 366 | strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver)); |
| 366 | strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version)); | 367 | strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version)); |
| 367 | strlcpy(drvinfo->bus_info, dev_name(pdata->dev), | 368 | strlcpy(drvinfo->bus_info, dev_name(pdata->dev), |
| 368 | sizeof(drvinfo->bus_info)); | 369 | sizeof(drvinfo->bus_info)); |
| 369 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d", | 370 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d", |
| 370 | XGMAC_IOREAD_BITS(pdata, MAC_VR, USERVER), | 371 | XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER), |
| 371 | XGMAC_IOREAD_BITS(pdata, MAC_VR, DEVID), | 372 | XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID), |
| 372 | XGMAC_IOREAD_BITS(pdata, MAC_VR, SNPSVER)); | 373 | XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER)); |
| 373 | drvinfo->n_stats = XGBE_STATS_COUNT; | 374 | drvinfo->n_stats = XGBE_STATS_COUNT; |
| 374 | } | 375 | } |
| 375 | 376 | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 8aa6a9353f7b..bdf9cfa70e88 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c | |||
| @@ -172,7 +172,7 @@ static struct xgbe_channel *xgbe_alloc_rings(struct xgbe_prv_data *pdata) | |||
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | if (i < pdata->rx_ring_count) { | 174 | if (i < pdata->rx_ring_count) { |
| 175 | spin_lock_init(&tx_ring->lock); | 175 | spin_lock_init(&rx_ring->lock); |
| 176 | channel->rx_ring = rx_ring++; | 176 | channel->rx_ring = rx_ring++; |
| 177 | } | 177 | } |
| 178 | 178 | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 07bf70a82908..e9fe6e6ddcc3 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h | |||
| @@ -183,6 +183,7 @@ | |||
| 183 | #define XGMAC_DRIVER_CONTEXT 1 | 183 | #define XGMAC_DRIVER_CONTEXT 1 |
| 184 | #define XGMAC_IOCTL_CONTEXT 2 | 184 | #define XGMAC_IOCTL_CONTEXT 2 |
| 185 | 185 | ||
| 186 | #define XGBE_FIFO_MAX 81920 | ||
| 186 | #define XGBE_FIFO_SIZE_B(x) (x) | 187 | #define XGBE_FIFO_SIZE_B(x) (x) |
| 187 | #define XGBE_FIFO_SIZE_KB(x) (x * 1024) | 188 | #define XGBE_FIFO_SIZE_KB(x) (x * 1024) |
| 188 | 189 | ||
| @@ -526,6 +527,9 @@ struct xgbe_desc_if { | |||
| 526 | * or configurations are present in the device. | 527 | * or configurations are present in the device. |
| 527 | */ | 528 | */ |
| 528 | struct xgbe_hw_features { | 529 | struct xgbe_hw_features { |
| 530 | /* HW Version */ | ||
| 531 | unsigned int version; | ||
| 532 | |||
| 529 | /* HW Feature Register0 */ | 533 | /* HW Feature Register0 */ |
| 530 | unsigned int gmii; /* 1000 Mbps support */ | 534 | unsigned int gmii; /* 1000 Mbps support */ |
| 531 | unsigned int vlhash; /* VLAN Hash Filter */ | 535 | unsigned int vlhash; /* VLAN Hash Filter */ |
diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig index 616dff6d3f5f..f4054d242f3c 100644 --- a/drivers/net/ethernet/apm/xgene/Kconfig +++ b/drivers/net/ethernet/apm/xgene/Kconfig | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | config NET_XGENE | 1 | config NET_XGENE |
| 2 | tristate "APM X-Gene SoC Ethernet Driver" | 2 | tristate "APM X-Gene SoC Ethernet Driver" |
| 3 | depends on HAS_DMA | ||
| 3 | select PHYLIB | 4 | select PHYLIB |
| 4 | help | 5 | help |
| 5 | This is the Ethernet driver for the on-chip ethernet interface on the | 6 | This is the Ethernet driver for the on-chip ethernet interface on the |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index e1a8f4e19983..e4222af2baa6 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c | |||
| @@ -563,15 +563,21 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata) | |||
| 563 | struct xgene_enet_desc_ring *ring; | 563 | struct xgene_enet_desc_ring *ring; |
| 564 | 564 | ||
| 565 | ring = pdata->tx_ring; | 565 | ring = pdata->tx_ring; |
| 566 | if (ring && ring->cp_ring && ring->cp_ring->cp_skb) | 566 | if (ring) { |
| 567 | devm_kfree(dev, ring->cp_ring->cp_skb); | 567 | if (ring->cp_ring && ring->cp_ring->cp_skb) |
| 568 | xgene_enet_free_desc_ring(ring); | 568 | devm_kfree(dev, ring->cp_ring->cp_skb); |
| 569 | xgene_enet_free_desc_ring(ring); | ||
| 570 | } | ||
| 569 | 571 | ||
| 570 | ring = pdata->rx_ring; | 572 | ring = pdata->rx_ring; |
| 571 | if (ring && ring->buf_pool && ring->buf_pool->rx_skb) | 573 | if (ring) { |
| 572 | devm_kfree(dev, ring->buf_pool->rx_skb); | 574 | if (ring->buf_pool) { |
| 573 | xgene_enet_free_desc_ring(ring->buf_pool); | 575 | if (ring->buf_pool->rx_skb) |
| 574 | xgene_enet_free_desc_ring(ring); | 576 | devm_kfree(dev, ring->buf_pool->rx_skb); |
| 577 | xgene_enet_free_desc_ring(ring->buf_pool); | ||
| 578 | } | ||
| 579 | xgene_enet_free_desc_ring(ring); | ||
| 580 | } | ||
| 575 | } | 581 | } |
| 576 | 582 | ||
| 577 | static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( | 583 | static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( |
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 7dcfb19a31c8..d8d07a818b89 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig | |||
| @@ -84,7 +84,7 @@ config BNX2 | |||
| 84 | 84 | ||
| 85 | config CNIC | 85 | config CNIC |
| 86 | tristate "QLogic CNIC support" | 86 | tristate "QLogic CNIC support" |
| 87 | depends on PCI | 87 | depends on PCI && (IPV6 || IPV6=n) |
| 88 | select BNX2 | 88 | select BNX2 |
| 89 | select UIO | 89 | select UIO |
| 90 | ---help--- | 90 | ---help--- |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4e6c82e20224..4ccc806b1150 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -483,11 +483,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
| 483 | 483 | ||
| 484 | #ifdef BNX2X_STOP_ON_ERROR | 484 | #ifdef BNX2X_STOP_ON_ERROR |
| 485 | fp->tpa_queue_used |= (1 << queue); | 485 | fp->tpa_queue_used |= (1 << queue); |
| 486 | #ifdef _ASM_GENERIC_INT_L64_H | ||
| 487 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n", | ||
| 488 | #else | ||
| 489 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", | 486 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", |
| 490 | #endif | ||
| 491 | fp->tpa_queue_used); | 487 | fp->tpa_queue_used); |
| 492 | #endif | 488 | #endif |
| 493 | } | 489 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 5ba8af50c84f..c4daa068f1db 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | |||
| @@ -2233,7 +2233,12 @@ struct shmem2_region { | |||
| 2233 | u32 reserved3; /* Offset 0x14C */ | 2233 | u32 reserved3; /* Offset 0x14C */ |
| 2234 | u32 reserved4; /* Offset 0x150 */ | 2234 | u32 reserved4; /* Offset 0x150 */ |
| 2235 | u32 link_attr_sync[PORT_MAX]; /* Offset 0x154 */ | 2235 | u32 link_attr_sync[PORT_MAX]; /* Offset 0x154 */ |
| 2236 | #define LINK_ATTR_SYNC_KR2_ENABLE (1<<0) | 2236 | #define LINK_ATTR_SYNC_KR2_ENABLE 0x00000001 |
| 2237 | #define LINK_SFP_EEPROM_COMP_CODE_MASK 0x0000ff00 | ||
| 2238 | #define LINK_SFP_EEPROM_COMP_CODE_SHIFT 8 | ||
| 2239 | #define LINK_SFP_EEPROM_COMP_CODE_SR 0x00001000 | ||
| 2240 | #define LINK_SFP_EEPROM_COMP_CODE_LR 0x00002000 | ||
| 2241 | #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 | ||
| 2237 | 2242 | ||
| 2238 | u32 reserved5[2]; | 2243 | u32 reserved5[2]; |
| 2239 | u32 reserved6[PORT_MAX]; | 2244 | u32 reserved6[PORT_MAX]; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 53fb4fa61b40..549549eaf580 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
| @@ -154,15 +154,22 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, | |||
| 154 | LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) | 154 | LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) |
| 155 | 155 | ||
| 156 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 | 156 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 |
| 157 | #define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0 | ||
| 157 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 | 158 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
| 158 | #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 | 159 | #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 |
| 159 | #define SFP_EEPROM_CON_TYPE_VAL_RJ45 0x22 | 160 | #define SFP_EEPROM_CON_TYPE_VAL_RJ45 0x22 |
| 160 | 161 | ||
| 161 | 162 | ||
| 162 | #define SFP_EEPROM_COMP_CODE_ADDR 0x3 | 163 | #define SFP_EEPROM_10G_COMP_CODE_ADDR 0x3 |
| 163 | #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4) | 164 | #define SFP_EEPROM_10G_COMP_CODE_SR_MASK (1<<4) |
| 164 | #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5) | 165 | #define SFP_EEPROM_10G_COMP_CODE_LR_MASK (1<<5) |
| 165 | #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6) | 166 | #define SFP_EEPROM_10G_COMP_CODE_LRM_MASK (1<<6) |
| 167 | |||
| 168 | #define SFP_EEPROM_1G_COMP_CODE_ADDR 0x6 | ||
| 169 | #define SFP_EEPROM_1G_COMP_CODE_SX (1<<0) | ||
| 170 | #define SFP_EEPROM_1G_COMP_CODE_LX (1<<1) | ||
| 171 | #define SFP_EEPROM_1G_COMP_CODE_CX (1<<2) | ||
| 172 | #define SFP_EEPROM_1G_COMP_CODE_BASE_T (1<<3) | ||
| 166 | 173 | ||
| 167 | #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 | 174 | #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 |
| 168 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 | 175 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 |
| @@ -3633,8 +3640,8 @@ static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, | |||
| 3633 | reg_set[i].val); | 3640 | reg_set[i].val); |
| 3634 | 3641 | ||
| 3635 | /* Start KR2 work-around timer which handles BCM8073 link-parner */ | 3642 | /* Start KR2 work-around timer which handles BCM8073 link-parner */ |
| 3636 | vars->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE; | 3643 | params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE; |
| 3637 | bnx2x_update_link_attr(params, vars->link_attr_sync); | 3644 | bnx2x_update_link_attr(params, params->link_attr_sync); |
| 3638 | } | 3645 | } |
| 3639 | 3646 | ||
| 3640 | static void bnx2x_disable_kr2(struct link_params *params, | 3647 | static void bnx2x_disable_kr2(struct link_params *params, |
| @@ -3666,8 +3673,8 @@ static void bnx2x_disable_kr2(struct link_params *params, | |||
| 3666 | for (i = 0; i < ARRAY_SIZE(reg_set); i++) | 3673 | for (i = 0; i < ARRAY_SIZE(reg_set); i++) |
| 3667 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, | 3674 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, |
| 3668 | reg_set[i].val); | 3675 | reg_set[i].val); |
| 3669 | vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; | 3676 | params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; |
| 3670 | bnx2x_update_link_attr(params, vars->link_attr_sync); | 3677 | bnx2x_update_link_attr(params, params->link_attr_sync); |
| 3671 | 3678 | ||
| 3672 | vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; | 3679 | vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; |
| 3673 | } | 3680 | } |
| @@ -4810,7 +4817,7 @@ void bnx2x_link_status_update(struct link_params *params, | |||
| 4810 | ~FEATURE_CONFIG_PFC_ENABLED; | 4817 | ~FEATURE_CONFIG_PFC_ENABLED; |
| 4811 | 4818 | ||
| 4812 | if (SHMEM2_HAS(bp, link_attr_sync)) | 4819 | if (SHMEM2_HAS(bp, link_attr_sync)) |
| 4813 | vars->link_attr_sync = SHMEM2_RD(bp, | 4820 | params->link_attr_sync = SHMEM2_RD(bp, |
| 4814 | link_attr_sync[params->port]); | 4821 | link_attr_sync[params->port]); |
| 4815 | 4822 | ||
| 4816 | DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", | 4823 | DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", |
| @@ -8057,21 +8064,24 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, | |||
| 8057 | { | 8064 | { |
| 8058 | struct bnx2x *bp = params->bp; | 8065 | struct bnx2x *bp = params->bp; |
| 8059 | u32 sync_offset = 0, phy_idx, media_types; | 8066 | u32 sync_offset = 0, phy_idx, media_types; |
| 8060 | u8 gport, val[2], check_limiting_mode = 0; | 8067 | u8 val[SFP_EEPROM_FC_TX_TECH_ADDR + 1], check_limiting_mode = 0; |
| 8061 | *edc_mode = EDC_MODE_LIMITING; | 8068 | *edc_mode = EDC_MODE_LIMITING; |
| 8062 | phy->media_type = ETH_PHY_UNSPECIFIED; | 8069 | phy->media_type = ETH_PHY_UNSPECIFIED; |
| 8063 | /* First check for copper cable */ | 8070 | /* First check for copper cable */ |
| 8064 | if (bnx2x_read_sfp_module_eeprom(phy, | 8071 | if (bnx2x_read_sfp_module_eeprom(phy, |
| 8065 | params, | 8072 | params, |
| 8066 | I2C_DEV_ADDR_A0, | 8073 | I2C_DEV_ADDR_A0, |
| 8067 | SFP_EEPROM_CON_TYPE_ADDR, | 8074 | 0, |
| 8068 | 2, | 8075 | SFP_EEPROM_FC_TX_TECH_ADDR + 1, |
| 8069 | (u8 *)val) != 0) { | 8076 | (u8 *)val) != 0) { |
| 8070 | DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); | 8077 | DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); |
| 8071 | return -EINVAL; | 8078 | return -EINVAL; |
| 8072 | } | 8079 | } |
| 8073 | 8080 | params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK; | |
| 8074 | switch (val[0]) { | 8081 | params->link_attr_sync |= val[SFP_EEPROM_10G_COMP_CODE_ADDR] << |
| 8082 | LINK_SFP_EEPROM_COMP_CODE_SHIFT; | ||
| 8083 | bnx2x_update_link_attr(params, params->link_attr_sync); | ||
| 8084 | switch (val[SFP_EEPROM_CON_TYPE_ADDR]) { | ||
| 8075 | case SFP_EEPROM_CON_TYPE_VAL_COPPER: | 8085 | case SFP_EEPROM_CON_TYPE_VAL_COPPER: |
| 8076 | { | 8086 | { |
| 8077 | u8 copper_module_type; | 8087 | u8 copper_module_type; |
| @@ -8079,17 +8089,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, | |||
| 8079 | /* Check if its active cable (includes SFP+ module) | 8089 | /* Check if its active cable (includes SFP+ module) |
| 8080 | * of passive cable | 8090 | * of passive cable |
| 8081 | */ | 8091 | */ |
| 8082 | if (bnx2x_read_sfp_module_eeprom(phy, | 8092 | copper_module_type = val[SFP_EEPROM_FC_TX_TECH_ADDR]; |
| 8083 | params, | ||
| 8084 | I2C_DEV_ADDR_A0, | ||
| 8085 | SFP_EEPROM_FC_TX_TECH_ADDR, | ||
| 8086 | 1, | ||
| 8087 | &copper_module_type) != 0) { | ||
| 8088 | DP(NETIF_MSG_LINK, | ||
| 8089 | "Failed to read copper-cable-type" | ||
| 8090 | " from SFP+ EEPROM\n"); | ||
| 8091 | return -EINVAL; | ||
| 8092 | } | ||
| 8093 | 8093 | ||
| 8094 | if (copper_module_type & | 8094 | if (copper_module_type & |
| 8095 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { | 8095 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { |
| @@ -8115,16 +8115,18 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, | |||
| 8115 | } | 8115 | } |
| 8116 | break; | 8116 | break; |
| 8117 | } | 8117 | } |
| 8118 | case SFP_EEPROM_CON_TYPE_VAL_UNKNOWN: | ||
| 8118 | case SFP_EEPROM_CON_TYPE_VAL_LC: | 8119 | case SFP_EEPROM_CON_TYPE_VAL_LC: |
| 8119 | case SFP_EEPROM_CON_TYPE_VAL_RJ45: | 8120 | case SFP_EEPROM_CON_TYPE_VAL_RJ45: |
| 8120 | check_limiting_mode = 1; | 8121 | check_limiting_mode = 1; |
| 8121 | if ((val[1] & (SFP_EEPROM_COMP_CODE_SR_MASK | | 8122 | if ((val[SFP_EEPROM_10G_COMP_CODE_ADDR] & |
| 8122 | SFP_EEPROM_COMP_CODE_LR_MASK | | 8123 | (SFP_EEPROM_10G_COMP_CODE_SR_MASK | |
| 8123 | SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) { | 8124 | SFP_EEPROM_10G_COMP_CODE_LR_MASK | |
| 8125 | SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) { | ||
| 8124 | DP(NETIF_MSG_LINK, "1G SFP module detected\n"); | 8126 | DP(NETIF_MSG_LINK, "1G SFP module detected\n"); |
| 8125 | gport = params->port; | ||
| 8126 | phy->media_type = ETH_PHY_SFP_1G_FIBER; | 8127 | phy->media_type = ETH_PHY_SFP_1G_FIBER; |
| 8127 | if (phy->req_line_speed != SPEED_1000) { | 8128 | if (phy->req_line_speed != SPEED_1000) { |
| 8129 | u8 gport = params->port; | ||
| 8128 | phy->req_line_speed = SPEED_1000; | 8130 | phy->req_line_speed = SPEED_1000; |
| 8129 | if (!CHIP_IS_E1x(bp)) { | 8131 | if (!CHIP_IS_E1x(bp)) { |
| 8130 | gport = BP_PATH(bp) + | 8132 | gport = BP_PATH(bp) + |
| @@ -8134,6 +8136,12 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, | |||
| 8134 | "Warning: Link speed was forced to 1000Mbps. Current SFP module in port %d is not compliant with 10G Ethernet\n", | 8136 | "Warning: Link speed was forced to 1000Mbps. Current SFP module in port %d is not compliant with 10G Ethernet\n", |
| 8135 | gport); | 8137 | gport); |
| 8136 | } | 8138 | } |
| 8139 | if (val[SFP_EEPROM_1G_COMP_CODE_ADDR] & | ||
| 8140 | SFP_EEPROM_1G_COMP_CODE_BASE_T) { | ||
| 8141 | bnx2x_sfp_set_transmitter(params, phy, 0); | ||
| 8142 | msleep(40); | ||
| 8143 | bnx2x_sfp_set_transmitter(params, phy, 1); | ||
| 8144 | } | ||
| 8137 | } else { | 8145 | } else { |
| 8138 | int idx, cfg_idx = 0; | 8146 | int idx, cfg_idx = 0; |
| 8139 | DP(NETIF_MSG_LINK, "10G Optic module detected\n"); | 8147 | DP(NETIF_MSG_LINK, "10G Optic module detected\n"); |
| @@ -8149,7 +8157,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, | |||
| 8149 | break; | 8157 | break; |
| 8150 | default: | 8158 | default: |
| 8151 | DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", | 8159 | DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", |
| 8152 | val[0]); | 8160 | val[SFP_EEPROM_CON_TYPE_ADDR]); |
| 8153 | return -EINVAL; | 8161 | return -EINVAL; |
| 8154 | } | 8162 | } |
| 8155 | sync_offset = params->shmem_base + | 8163 | sync_offset = params->shmem_base + |
| @@ -13507,7 +13515,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params, | |||
| 13507 | 13515 | ||
| 13508 | sigdet = bnx2x_warpcore_get_sigdet(phy, params); | 13516 | sigdet = bnx2x_warpcore_get_sigdet(phy, params); |
| 13509 | if (!sigdet) { | 13517 | if (!sigdet) { |
| 13510 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { | 13518 | if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { |
| 13511 | bnx2x_kr2_recovery(params, vars, phy); | 13519 | bnx2x_kr2_recovery(params, vars, phy); |
| 13512 | DP(NETIF_MSG_LINK, "No sigdet\n"); | 13520 | DP(NETIF_MSG_LINK, "No sigdet\n"); |
| 13513 | } | 13521 | } |
| @@ -13525,7 +13533,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params, | |||
| 13525 | 13533 | ||
| 13526 | /* CL73 has not begun yet */ | 13534 | /* CL73 has not begun yet */ |
| 13527 | if (base_page == 0) { | 13535 | if (base_page == 0) { |
| 13528 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { | 13536 | if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { |
| 13529 | bnx2x_kr2_recovery(params, vars, phy); | 13537 | bnx2x_kr2_recovery(params, vars, phy); |
| 13530 | DP(NETIF_MSG_LINK, "No BP\n"); | 13538 | DP(NETIF_MSG_LINK, "No BP\n"); |
| 13531 | } | 13539 | } |
| @@ -13541,7 +13549,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params, | |||
| 13541 | ((next_page & 0xe0) == 0x20)))); | 13549 | ((next_page & 0xe0) == 0x20)))); |
| 13542 | 13550 | ||
| 13543 | /* In case KR2 is already disabled, check if we need to re-enable it */ | 13551 | /* In case KR2 is already disabled, check if we need to re-enable it */ |
| 13544 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { | 13552 | if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { |
| 13545 | if (!not_kr2_device) { | 13553 | if (!not_kr2_device) { |
| 13546 | DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page, | 13554 | DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page, |
| 13547 | next_page); | 13555 | next_page); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 389f5f8cb0a3..d9cce4c3899b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | |||
| @@ -323,6 +323,9 @@ struct link_params { | |||
| 323 | #define LINK_FLAGS_INT_DISABLED (1<<0) | 323 | #define LINK_FLAGS_INT_DISABLED (1<<0) |
| 324 | #define PHY_INITIALIZED (1<<1) | 324 | #define PHY_INITIALIZED (1<<1) |
| 325 | u32 lfa_base; | 325 | u32 lfa_base; |
| 326 | |||
| 327 | /* The same definitions as the shmem2 parameter */ | ||
| 328 | u32 link_attr_sync; | ||
| 326 | }; | 329 | }; |
| 327 | 330 | ||
| 328 | /* Output parameters */ | 331 | /* Output parameters */ |
| @@ -364,8 +367,6 @@ struct link_vars { | |||
| 364 | u8 rx_tx_asic_rst; | 367 | u8 rx_tx_asic_rst; |
| 365 | u8 turn_to_run_wc_rt; | 368 | u8 turn_to_run_wc_rt; |
| 366 | u16 rsrv2; | 369 | u16 rsrv2; |
| 367 | /* The same definitions as the shmem2 parameter */ | ||
| 368 | u32 link_attr_sync; | ||
| 369 | }; | 370 | }; |
| 370 | 371 | ||
| 371 | /***********************************************************/ | 372 | /***********************************************************/ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c13364b6cc19..d1c093dcb054 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -6849,6 +6849,37 @@ static void bnx2x__common_init_phy(struct bnx2x *bp) | |||
| 6849 | bnx2x_release_phy_lock(bp); | 6849 | bnx2x_release_phy_lock(bp); |
| 6850 | } | 6850 | } |
| 6851 | 6851 | ||
| 6852 | static void bnx2x_config_endianity(struct bnx2x *bp, u32 val) | ||
| 6853 | { | ||
| 6854 | REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, val); | ||
| 6855 | REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, val); | ||
| 6856 | REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, val); | ||
| 6857 | REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, val); | ||
| 6858 | REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, val); | ||
| 6859 | |||
| 6860 | /* make sure this value is 0 */ | ||
| 6861 | REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0); | ||
| 6862 | |||
| 6863 | REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, val); | ||
| 6864 | REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, val); | ||
| 6865 | REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, val); | ||
| 6866 | REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, val); | ||
| 6867 | } | ||
| 6868 | |||
| 6869 | static void bnx2x_set_endianity(struct bnx2x *bp) | ||
| 6870 | { | ||
| 6871 | #ifdef __BIG_ENDIAN | ||
| 6872 | bnx2x_config_endianity(bp, 1); | ||
| 6873 | #else | ||
| 6874 | bnx2x_config_endianity(bp, 0); | ||
| 6875 | #endif | ||
| 6876 | } | ||
| 6877 | |||
| 6878 | static void bnx2x_reset_endianity(struct bnx2x *bp) | ||
| 6879 | { | ||
| 6880 | bnx2x_config_endianity(bp, 0); | ||
| 6881 | } | ||
| 6882 | |||
| 6852 | /** | 6883 | /** |
| 6853 | * bnx2x_init_hw_common - initialize the HW at the COMMON phase. | 6884 | * bnx2x_init_hw_common - initialize the HW at the COMMON phase. |
| 6854 | * | 6885 | * |
| @@ -6915,23 +6946,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) | |||
| 6915 | 6946 | ||
| 6916 | bnx2x_init_block(bp, BLOCK_PXP2, PHASE_COMMON); | 6947 | bnx2x_init_block(bp, BLOCK_PXP2, PHASE_COMMON); |
| 6917 | bnx2x_init_pxp(bp); | 6948 | bnx2x_init_pxp(bp); |
| 6918 | 6949 | bnx2x_set_endianity(bp); | |
| 6919 | #ifdef __BIG_ENDIAN | ||
| 6920 | REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1); | ||
| 6921 | REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1); | ||
| 6922 | REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1); | ||
| 6923 | REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1); | ||
| 6924 | REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1); | ||
| 6925 | /* make sure this value is 0 */ | ||
| 6926 | REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0); | ||
| 6927 | |||
| 6928 | /* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ | ||
| 6929 | REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); | ||
| 6930 | REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1); | ||
| 6931 | REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1); | ||
| 6932 | REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); | ||
| 6933 | #endif | ||
| 6934 | |||
| 6935 | bnx2x_ilt_init_page_size(bp, INITOP_SET); | 6950 | bnx2x_ilt_init_page_size(bp, INITOP_SET); |
| 6936 | 6951 | ||
| 6937 | if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) | 6952 | if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) |
| @@ -10052,6 +10067,8 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, | |||
| 10052 | } | 10067 | } |
| 10053 | 10068 | ||
| 10054 | #define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4)) | 10069 | #define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4)) |
| 10070 | #define BNX2X_PREV_UNDI_PROD_ADDR_H(f) (BAR_TSTRORM_INTMEM + \ | ||
| 10071 | 0x1848 + ((f) << 4)) | ||
| 10055 | #define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff) | 10072 | #define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff) |
| 10056 | #define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff) | 10073 | #define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff) |
| 10057 | #define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq)) | 10074 | #define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq)) |
| @@ -10059,8 +10076,6 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, | |||
| 10059 | #define BCM_5710_UNDI_FW_MF_MAJOR (0x07) | 10076 | #define BCM_5710_UNDI_FW_MF_MAJOR (0x07) |
| 10060 | #define BCM_5710_UNDI_FW_MF_MINOR (0x08) | 10077 | #define BCM_5710_UNDI_FW_MF_MINOR (0x08) |
| 10061 | #define BCM_5710_UNDI_FW_MF_VERS (0x05) | 10078 | #define BCM_5710_UNDI_FW_MF_VERS (0x05) |
| 10062 | #define BNX2X_PREV_UNDI_MF_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4)) | ||
| 10063 | #define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 4)) | ||
| 10064 | 10079 | ||
| 10065 | static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) | 10080 | static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) |
| 10066 | { | 10081 | { |
| @@ -10079,72 +10094,25 @@ static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) | |||
| 10079 | return false; | 10094 | return false; |
| 10080 | } | 10095 | } |
| 10081 | 10096 | ||
| 10082 | static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp) | 10097 | static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 inc) |
| 10083 | { | ||
| 10084 | u8 major, minor, version; | ||
| 10085 | u32 fw; | ||
| 10086 | |||
| 10087 | /* Must check that FW is loaded */ | ||
| 10088 | if (!(REG_RD(bp, MISC_REG_RESET_REG_1) & | ||
| 10089 | MISC_REGISTERS_RESET_REG_1_RST_XSEM)) { | ||
| 10090 | BNX2X_DEV_INFO("XSEM is reset - UNDI MF FW is not loaded\n"); | ||
| 10091 | return false; | ||
| 10092 | } | ||
| 10093 | |||
| 10094 | /* Read Currently loaded FW version */ | ||
| 10095 | fw = REG_RD(bp, XSEM_REG_PRAM); | ||
| 10096 | major = fw & 0xff; | ||
| 10097 | minor = (fw >> 0x8) & 0xff; | ||
| 10098 | version = (fw >> 0x10) & 0xff; | ||
| 10099 | BNX2X_DEV_INFO("Loaded FW: 0x%08x: Major 0x%02x Minor 0x%02x Version 0x%02x\n", | ||
| 10100 | fw, major, minor, version); | ||
| 10101 | |||
| 10102 | if (major > BCM_5710_UNDI_FW_MF_MAJOR) | ||
| 10103 | return true; | ||
| 10104 | |||
| 10105 | if ((major == BCM_5710_UNDI_FW_MF_MAJOR) && | ||
| 10106 | (minor > BCM_5710_UNDI_FW_MF_MINOR)) | ||
| 10107 | return true; | ||
| 10108 | |||
| 10109 | if ((major == BCM_5710_UNDI_FW_MF_MAJOR) && | ||
| 10110 | (minor == BCM_5710_UNDI_FW_MF_MINOR) && | ||
| 10111 | (version >= BCM_5710_UNDI_FW_MF_VERS)) | ||
| 10112 | return true; | ||
| 10113 | |||
| 10114 | return false; | ||
| 10115 | } | ||
| 10116 | |||
| 10117 | static void bnx2x_prev_unload_undi_mf(struct bnx2x *bp) | ||
| 10118 | { | ||
| 10119 | int i; | ||
| 10120 | |||
| 10121 | /* Due to legacy (FW) code, the first function on each engine has a | ||
| 10122 | * different offset macro from the rest of the functions. | ||
| 10123 | * Setting this for all 8 functions is harmless regardless of whether | ||
| 10124 | * this is actually a multi-function device. | ||
| 10125 | */ | ||
| 10126 | for (i = 0; i < 2; i++) | ||
| 10127 | REG_WR(bp, BNX2X_PREV_UNDI_MF_PORT(i), 1); | ||
| 10128 | |||
| 10129 | for (i = 2; i < 8; i++) | ||
| 10130 | REG_WR(bp, BNX2X_PREV_UNDI_MF_FUNC(i - 2), 1); | ||
| 10131 | |||
| 10132 | BNX2X_DEV_INFO("UNDI FW (MF) set to discard\n"); | ||
| 10133 | } | ||
| 10134 | |||
| 10135 | static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, u8 inc) | ||
| 10136 | { | 10098 | { |
| 10137 | u16 rcq, bd; | 10099 | u16 rcq, bd; |
| 10138 | u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port)); | 10100 | u32 addr, tmp_reg; |
| 10101 | |||
| 10102 | if (BP_FUNC(bp) < 2) | ||
| 10103 | addr = BNX2X_PREV_UNDI_PROD_ADDR(BP_PORT(bp)); | ||
| 10104 | else | ||
| 10105 | addr = BNX2X_PREV_UNDI_PROD_ADDR_H(BP_FUNC(bp) - 2); | ||
| 10139 | 10106 | ||
| 10107 | tmp_reg = REG_RD(bp, addr); | ||
| 10140 | rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc; | 10108 | rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc; |
| 10141 | bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc; | 10109 | bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc; |
| 10142 | 10110 | ||
| 10143 | tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd); | 10111 | tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd); |
| 10144 | REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg); | 10112 | REG_WR(bp, addr, tmp_reg); |
| 10145 | 10113 | ||
| 10146 | BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n", | 10114 | BNX2X_DEV_INFO("UNDI producer [%d/%d][%08x] rings bd -> 0x%04x, rcq -> 0x%04x\n", |
| 10147 | port, bd, rcq); | 10115 | BP_PORT(bp), BP_FUNC(bp), addr, bd, rcq); |
| 10148 | } | 10116 | } |
| 10149 | 10117 | ||
| 10150 | static int bnx2x_prev_mcp_done(struct bnx2x *bp) | 10118 | static int bnx2x_prev_mcp_done(struct bnx2x *bp) |
| @@ -10383,7 +10351,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) | |||
| 10383 | /* Reset should be performed after BRB is emptied */ | 10351 | /* Reset should be performed after BRB is emptied */ |
| 10384 | if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) { | 10352 | if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) { |
| 10385 | u32 timer_count = 1000; | 10353 | u32 timer_count = 1000; |
| 10386 | bool need_write = true; | ||
| 10387 | 10354 | ||
| 10388 | /* Close the MAC Rx to prevent BRB from filling up */ | 10355 | /* Close the MAC Rx to prevent BRB from filling up */ |
| 10389 | bnx2x_prev_unload_close_mac(bp, &mac_vals); | 10356 | bnx2x_prev_unload_close_mac(bp, &mac_vals); |
| @@ -10420,20 +10387,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) | |||
| 10420 | else | 10387 | else |
| 10421 | timer_count--; | 10388 | timer_count--; |
| 10422 | 10389 | ||
| 10423 | /* New UNDI FW supports MF and contains better | 10390 | /* If UNDI resides in memory, manually increment it */ |
| 10424 | * cleaning methods - might be redundant but harmless. | 10391 | if (prev_undi) |
| 10425 | */ | 10392 | bnx2x_prev_unload_undi_inc(bp, 1); |
| 10426 | if (bnx2x_prev_unload_undi_fw_supports_mf(bp)) { | 10393 | |
| 10427 | if (need_write) { | ||
| 10428 | bnx2x_prev_unload_undi_mf(bp); | ||
| 10429 | need_write = false; | ||
| 10430 | } | ||
| 10431 | } else if (prev_undi) { | ||
| 10432 | /* If UNDI resides in memory, | ||
| 10433 | * manually increment it | ||
| 10434 | */ | ||
| 10435 | bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1); | ||
| 10436 | } | ||
| 10437 | udelay(10); | 10394 | udelay(10); |
| 10438 | } | 10395 | } |
| 10439 | 10396 | ||
| @@ -13227,9 +13184,15 @@ static void __bnx2x_remove(struct pci_dev *pdev, | |||
| 13227 | bnx2x_iov_remove_one(bp); | 13184 | bnx2x_iov_remove_one(bp); |
| 13228 | 13185 | ||
| 13229 | /* Power on: we can't let PCI layer write to us while we are in D3 */ | 13186 | /* Power on: we can't let PCI layer write to us while we are in D3 */ |
| 13230 | if (IS_PF(bp)) | 13187 | if (IS_PF(bp)) { |
| 13231 | bnx2x_set_power_state(bp, PCI_D0); | 13188 | bnx2x_set_power_state(bp, PCI_D0); |
| 13232 | 13189 | ||
| 13190 | /* Set endianity registers to reset values in case next driver | ||
| 13191 | * boots in different endianty environment. | ||
| 13192 | */ | ||
| 13193 | bnx2x_reset_endianity(bp); | ||
| 13194 | } | ||
| 13195 | |||
| 13233 | /* Disable MSI/MSI-X */ | 13196 | /* Disable MSI/MSI-X */ |
| 13234 | bnx2x_disable_msi(bp); | 13197 | bnx2x_disable_msi(bp); |
| 13235 | 13198 | ||
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 27861a6c7ca5..a6a9f284c8dd 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <linux/if_vlan.h> | 31 | #include <linux/if_vlan.h> |
| 32 | #include <linux/prefetch.h> | 32 | #include <linux/prefetch.h> |
| 33 | #include <linux/random.h> | 33 | #include <linux/random.h> |
| 34 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 34 | #if IS_ENABLED(CONFIG_VLAN_8021Q) |
| 35 | #define BCM_VLAN 1 | 35 | #define BCM_VLAN 1 |
| 36 | #endif | 36 | #endif |
| 37 | #include <net/ip.h> | 37 | #include <net/ip.h> |
| @@ -3685,7 +3685,7 @@ static int cnic_get_v4_route(struct sockaddr_in *dst_addr, | |||
| 3685 | static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, | 3685 | static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, |
| 3686 | struct dst_entry **dst) | 3686 | struct dst_entry **dst) |
| 3687 | { | 3687 | { |
| 3688 | #if defined(CONFIG_IPV6) || (defined(CONFIG_IPV6_MODULE) && defined(MODULE)) | 3688 | #if IS_ENABLED(CONFIG_IPV6) |
| 3689 | struct flowi6 fl6; | 3689 | struct flowi6 fl6; |
| 3690 | 3690 | ||
| 3691 | memset(&fl6, 0, sizeof(fl6)); | 3691 | memset(&fl6, 0, sizeof(fl6)); |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 3ac5d23454a8..cb77ae93d89a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -11617,6 +11617,12 @@ static int tg3_open(struct net_device *dev) | |||
| 11617 | struct tg3 *tp = netdev_priv(dev); | 11617 | struct tg3 *tp = netdev_priv(dev); |
| 11618 | int err; | 11618 | int err; |
| 11619 | 11619 | ||
| 11620 | if (tp->pcierr_recovery) { | ||
| 11621 | netdev_err(dev, "Failed to open device. PCI error recovery " | ||
| 11622 | "in progress\n"); | ||
| 11623 | return -EAGAIN; | ||
| 11624 | } | ||
| 11625 | |||
| 11620 | if (tp->fw_needed) { | 11626 | if (tp->fw_needed) { |
| 11621 | err = tg3_request_firmware(tp); | 11627 | err = tg3_request_firmware(tp); |
| 11622 | if (tg3_asic_rev(tp) == ASIC_REV_57766) { | 11628 | if (tg3_asic_rev(tp) == ASIC_REV_57766) { |
| @@ -11674,6 +11680,12 @@ static int tg3_close(struct net_device *dev) | |||
| 11674 | { | 11680 | { |
| 11675 | struct tg3 *tp = netdev_priv(dev); | 11681 | struct tg3 *tp = netdev_priv(dev); |
| 11676 | 11682 | ||
| 11683 | if (tp->pcierr_recovery) { | ||
| 11684 | netdev_err(dev, "Failed to close device. PCI error recovery " | ||
| 11685 | "in progress\n"); | ||
| 11686 | return -EAGAIN; | ||
| 11687 | } | ||
| 11688 | |||
| 11677 | tg3_ptp_fini(tp); | 11689 | tg3_ptp_fini(tp); |
| 11678 | 11690 | ||
| 11679 | tg3_stop(tp); | 11691 | tg3_stop(tp); |
| @@ -17561,6 +17573,7 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
| 17561 | tp->rx_mode = TG3_DEF_RX_MODE; | 17573 | tp->rx_mode = TG3_DEF_RX_MODE; |
| 17562 | tp->tx_mode = TG3_DEF_TX_MODE; | 17574 | tp->tx_mode = TG3_DEF_TX_MODE; |
| 17563 | tp->irq_sync = 1; | 17575 | tp->irq_sync = 1; |
| 17576 | tp->pcierr_recovery = false; | ||
| 17564 | 17577 | ||
| 17565 | if (tg3_debug > 0) | 17578 | if (tg3_debug > 0) |
| 17566 | tp->msg_enable = tg3_debug; | 17579 | tp->msg_enable = tg3_debug; |
| @@ -18071,6 +18084,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, | |||
| 18071 | 18084 | ||
| 18072 | rtnl_lock(); | 18085 | rtnl_lock(); |
| 18073 | 18086 | ||
| 18087 | tp->pcierr_recovery = true; | ||
| 18088 | |||
| 18074 | /* We probably don't have netdev yet */ | 18089 | /* We probably don't have netdev yet */ |
| 18075 | if (!netdev || !netif_running(netdev)) | 18090 | if (!netdev || !netif_running(netdev)) |
| 18076 | goto done; | 18091 | goto done; |
| @@ -18195,6 +18210,7 @@ static void tg3_io_resume(struct pci_dev *pdev) | |||
| 18195 | tg3_phy_start(tp); | 18210 | tg3_phy_start(tp); |
| 18196 | 18211 | ||
| 18197 | done: | 18212 | done: |
| 18213 | tp->pcierr_recovery = false; | ||
| 18198 | rtnl_unlock(); | 18214 | rtnl_unlock(); |
| 18199 | } | 18215 | } |
| 18200 | 18216 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 461accaf0aa4..31c9f8295953 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -3407,6 +3407,7 @@ struct tg3 { | |||
| 3407 | 3407 | ||
| 3408 | struct device *hwmon_dev; | 3408 | struct device *hwmon_dev; |
| 3409 | bool link_up; | 3409 | bool link_up; |
| 3410 | bool pcierr_recovery; | ||
| 3410 | }; | 3411 | }; |
| 3411 | 3412 | ||
| 3412 | /* Accessor macros for chip and asic attributes | 3413 | /* Accessor macros for chip and asic attributes |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index ff8cae5e2535..ffc92a41d75b 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
| @@ -2506,7 +2506,7 @@ bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb) | |||
| 2506 | * For TSO, the TCP checksum field is seeded with pseudo-header sum | 2506 | * For TSO, the TCP checksum field is seeded with pseudo-header sum |
| 2507 | * excluding the length field. | 2507 | * excluding the length field. |
| 2508 | */ | 2508 | */ |
| 2509 | if (skb->protocol == htons(ETH_P_IP)) { | 2509 | if (vlan_get_protocol(skb) == htons(ETH_P_IP)) { |
| 2510 | struct iphdr *iph = ip_hdr(skb); | 2510 | struct iphdr *iph = ip_hdr(skb); |
| 2511 | 2511 | ||
| 2512 | /* Do we really need these? */ | 2512 | /* Do we really need these? */ |
| @@ -2870,12 +2870,13 @@ bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb, | |||
| 2870 | } | 2870 | } |
| 2871 | 2871 | ||
| 2872 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 2872 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 2873 | __be16 net_proto = vlan_get_protocol(skb); | ||
| 2873 | u8 proto = 0; | 2874 | u8 proto = 0; |
| 2874 | 2875 | ||
| 2875 | if (skb->protocol == htons(ETH_P_IP)) | 2876 | if (net_proto == htons(ETH_P_IP)) |
| 2876 | proto = ip_hdr(skb)->protocol; | 2877 | proto = ip_hdr(skb)->protocol; |
| 2877 | #ifdef NETIF_F_IPV6_CSUM | 2878 | #ifdef NETIF_F_IPV6_CSUM |
| 2878 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 2879 | else if (net_proto == htons(ETH_P_IPV6)) { |
| 2879 | /* nexthdr may not be TCP immediately. */ | 2880 | /* nexthdr may not be TCP immediately. */ |
| 2880 | proto = ipv6_hdr(skb)->nexthdr; | 2881 | proto = ipv6_hdr(skb)->nexthdr; |
| 2881 | } | 2882 | } |
diff --git a/drivers/net/ethernet/calxeda/Kconfig b/drivers/net/ethernet/calxeda/Kconfig index 184a063bed5f..07d2201530d2 100644 --- a/drivers/net/ethernet/calxeda/Kconfig +++ b/drivers/net/ethernet/calxeda/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config NET_CALXEDA_XGMAC | 1 | config NET_CALXEDA_XGMAC |
| 2 | tristate "Calxeda 1G/10G XGMAC Ethernet driver" | 2 | tristate "Calxeda 1G/10G XGMAC Ethernet driver" |
| 3 | depends on HAS_IOMEM && HAS_DMA | 3 | depends on HAS_IOMEM && HAS_DMA |
| 4 | depends on ARCH_HIGHBANK || COMPILE_TEST | ||
| 4 | select CRC32 | 5 | select CRC32 |
| 5 | help | 6 | help |
| 6 | This is the driver for the XGMAC Ethernet IP block found on Calxeda | 7 | This is the driver for the XGMAC Ethernet IP block found on Calxeda |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index d57282172ea5..c067b7888ac4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
| @@ -652,6 +652,7 @@ struct adapter { | |||
| 652 | struct tid_info tids; | 652 | struct tid_info tids; |
| 653 | void **tid_release_head; | 653 | void **tid_release_head; |
| 654 | spinlock_t tid_release_lock; | 654 | spinlock_t tid_release_lock; |
| 655 | struct workqueue_struct *workq; | ||
| 655 | struct work_struct tid_release_task; | 656 | struct work_struct tid_release_task; |
| 656 | struct work_struct db_full_task; | 657 | struct work_struct db_full_task; |
| 657 | struct work_struct db_drop_task; | 658 | struct work_struct db_drop_task; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 1afee70ce856..8c34811a1128 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -643,8 +643,6 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) | |||
| 643 | return ret; | 643 | return ret; |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | static struct workqueue_struct *workq; | ||
| 647 | |||
| 648 | /** | 646 | /** |
| 649 | * link_start - enable a port | 647 | * link_start - enable a port |
| 650 | * @dev: the port to enable | 648 | * @dev: the port to enable |
| @@ -1255,7 +1253,9 @@ freeout: t4_free_sge_resources(adap); | |||
| 1255 | goto freeout; | 1253 | goto freeout; |
| 1256 | } | 1254 | } |
| 1257 | 1255 | ||
| 1258 | t4_write_reg(adap, MPS_TRC_RSS_CONTROL, | 1256 | t4_write_reg(adap, is_t4(adap->params.chip) ? |
| 1257 | MPS_TRC_RSS_CONTROL : | ||
| 1258 | MPS_T5_TRC_RSS_CONTROL, | ||
| 1259 | RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | | 1259 | RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | |
| 1260 | QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); | 1260 | QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); |
| 1261 | return 0; | 1261 | return 0; |
| @@ -1763,7 +1763,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 1763 | 0xd004, 0xd03c, | 1763 | 0xd004, 0xd03c, |
| 1764 | 0xdfc0, 0xdfe0, | 1764 | 0xdfc0, 0xdfe0, |
| 1765 | 0xe000, 0xea7c, | 1765 | 0xe000, 0xea7c, |
| 1766 | 0xf000, 0x11190, | 1766 | 0xf000, 0x11110, |
| 1767 | 0x11118, 0x11190, | ||
| 1767 | 0x19040, 0x1906c, | 1768 | 0x19040, 0x1906c, |
| 1768 | 0x19078, 0x19080, | 1769 | 0x19078, 0x19080, |
| 1769 | 0x1908c, 0x19124, | 1770 | 0x1908c, 0x19124, |
| @@ -1970,7 +1971,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 1970 | 0xd004, 0xd03c, | 1971 | 0xd004, 0xd03c, |
| 1971 | 0xdfc0, 0xdfe0, | 1972 | 0xdfc0, 0xdfe0, |
| 1972 | 0xe000, 0x11088, | 1973 | 0xe000, 0x11088, |
| 1973 | 0x1109c, 0x1117c, | 1974 | 0x1109c, 0x11110, |
| 1975 | 0x11118, 0x1117c, | ||
| 1974 | 0x11190, 0x11204, | 1976 | 0x11190, 0x11204, |
| 1975 | 0x19040, 0x1906c, | 1977 | 0x19040, 0x1906c, |
| 1976 | 0x19078, 0x19080, | 1978 | 0x19078, 0x19080, |
| @@ -3340,7 +3342,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, | |||
| 3340 | adap->tid_release_head = (void **)((uintptr_t)p | chan); | 3342 | adap->tid_release_head = (void **)((uintptr_t)p | chan); |
| 3341 | if (!adap->tid_release_task_busy) { | 3343 | if (!adap->tid_release_task_busy) { |
| 3342 | adap->tid_release_task_busy = true; | 3344 | adap->tid_release_task_busy = true; |
| 3343 | queue_work(workq, &adap->tid_release_task); | 3345 | queue_work(adap->workq, &adap->tid_release_task); |
| 3344 | } | 3346 | } |
| 3345 | spin_unlock_bh(&adap->tid_release_lock); | 3347 | spin_unlock_bh(&adap->tid_release_lock); |
| 3346 | } | 3348 | } |
| @@ -4140,7 +4142,7 @@ void t4_db_full(struct adapter *adap) | |||
| 4140 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); | 4142 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); |
| 4141 | t4_set_reg_field(adap, SGE_INT_ENABLE3, | 4143 | t4_set_reg_field(adap, SGE_INT_ENABLE3, |
| 4142 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); | 4144 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); |
| 4143 | queue_work(workq, &adap->db_full_task); | 4145 | queue_work(adap->workq, &adap->db_full_task); |
| 4144 | } | 4146 | } |
| 4145 | } | 4147 | } |
| 4146 | 4148 | ||
| @@ -4150,7 +4152,7 @@ void t4_db_dropped(struct adapter *adap) | |||
| 4150 | disable_dbs(adap); | 4152 | disable_dbs(adap); |
| 4151 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); | 4153 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); |
| 4152 | } | 4154 | } |
| 4153 | queue_work(workq, &adap->db_drop_task); | 4155 | queue_work(adap->workq, &adap->db_drop_task); |
| 4154 | } | 4156 | } |
| 4155 | 4157 | ||
| 4156 | static void uld_attach(struct adapter *adap, unsigned int uld) | 4158 | static void uld_attach(struct adapter *adap, unsigned int uld) |
| @@ -5957,7 +5959,8 @@ static int adap_init0(struct adapter *adap) | |||
| 5957 | params[3] = FW_PARAM_PFVF(CQ_END); | 5959 | params[3] = FW_PARAM_PFVF(CQ_END); |
| 5958 | params[4] = FW_PARAM_PFVF(OCQ_START); | 5960 | params[4] = FW_PARAM_PFVF(OCQ_START); |
| 5959 | params[5] = FW_PARAM_PFVF(OCQ_END); | 5961 | params[5] = FW_PARAM_PFVF(OCQ_END); |
| 5960 | ret = t4_query_params(adap, 0, 0, 0, 6, params, val); | 5962 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, params, |
| 5963 | val); | ||
| 5961 | if (ret < 0) | 5964 | if (ret < 0) |
| 5962 | goto bye; | 5965 | goto bye; |
| 5963 | adap->vres.qp.start = val[0]; | 5966 | adap->vres.qp.start = val[0]; |
| @@ -5969,7 +5972,8 @@ static int adap_init0(struct adapter *adap) | |||
| 5969 | 5972 | ||
| 5970 | params[0] = FW_PARAM_DEV(MAXORDIRD_QP); | 5973 | params[0] = FW_PARAM_DEV(MAXORDIRD_QP); |
| 5971 | params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER); | 5974 | params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER); |
| 5972 | ret = t4_query_params(adap, 0, 0, 0, 2, params, val); | 5975 | ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, |
| 5976 | val); | ||
| 5973 | if (ret < 0) { | 5977 | if (ret < 0) { |
| 5974 | adap->params.max_ordird_qp = 8; | 5978 | adap->params.max_ordird_qp = 8; |
| 5975 | adap->params.max_ird_adapter = 32 * adap->tids.ntids; | 5979 | adap->params.max_ird_adapter = 32 * adap->tids.ntids; |
| @@ -6517,6 +6521,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 6517 | goto out_disable_device; | 6521 | goto out_disable_device; |
| 6518 | } | 6522 | } |
| 6519 | 6523 | ||
| 6524 | adapter->workq = create_singlethread_workqueue("cxgb4"); | ||
| 6525 | if (!adapter->workq) { | ||
| 6526 | err = -ENOMEM; | ||
| 6527 | goto out_free_adapter; | ||
| 6528 | } | ||
| 6529 | |||
| 6520 | /* PCI device has been enabled */ | 6530 | /* PCI device has been enabled */ |
| 6521 | adapter->flags |= DEV_ENABLED; | 6531 | adapter->flags |= DEV_ENABLED; |
| 6522 | 6532 | ||
| @@ -6715,6 +6725,9 @@ sriov: | |||
| 6715 | out_unmap_bar0: | 6725 | out_unmap_bar0: |
| 6716 | iounmap(adapter->regs); | 6726 | iounmap(adapter->regs); |
| 6717 | out_free_adapter: | 6727 | out_free_adapter: |
| 6728 | if (adapter->workq) | ||
| 6729 | destroy_workqueue(adapter->workq); | ||
| 6730 | |||
| 6718 | kfree(adapter); | 6731 | kfree(adapter); |
| 6719 | out_disable_device: | 6732 | out_disable_device: |
| 6720 | pci_disable_pcie_error_reporting(pdev); | 6733 | pci_disable_pcie_error_reporting(pdev); |
| @@ -6736,6 +6749,11 @@ static void remove_one(struct pci_dev *pdev) | |||
| 6736 | if (adapter) { | 6749 | if (adapter) { |
| 6737 | int i; | 6750 | int i; |
| 6738 | 6751 | ||
| 6752 | /* Tear down per-adapter Work Queue first since it can contain | ||
| 6753 | * references to our adapter data structure. | ||
| 6754 | */ | ||
| 6755 | destroy_workqueue(adapter->workq); | ||
| 6756 | |||
| 6739 | if (is_offload(adapter)) | 6757 | if (is_offload(adapter)) |
| 6740 | detach_ulds(adapter); | 6758 | detach_ulds(adapter); |
| 6741 | 6759 | ||
| @@ -6788,20 +6806,14 @@ static int __init cxgb4_init_module(void) | |||
| 6788 | { | 6806 | { |
| 6789 | int ret; | 6807 | int ret; |
| 6790 | 6808 | ||
| 6791 | workq = create_singlethread_workqueue("cxgb4"); | ||
| 6792 | if (!workq) | ||
| 6793 | return -ENOMEM; | ||
| 6794 | |||
| 6795 | /* Debugfs support is optional, just warn if this fails */ | 6809 | /* Debugfs support is optional, just warn if this fails */ |
| 6796 | cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | 6810 | cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); |
| 6797 | if (!cxgb4_debugfs_root) | 6811 | if (!cxgb4_debugfs_root) |
| 6798 | pr_warn("could not create debugfs entry, continuing\n"); | 6812 | pr_warn("could not create debugfs entry, continuing\n"); |
| 6799 | 6813 | ||
| 6800 | ret = pci_register_driver(&cxgb4_driver); | 6814 | ret = pci_register_driver(&cxgb4_driver); |
| 6801 | if (ret < 0) { | 6815 | if (ret < 0) |
| 6802 | debugfs_remove(cxgb4_debugfs_root); | 6816 | debugfs_remove(cxgb4_debugfs_root); |
| 6803 | destroy_workqueue(workq); | ||
| 6804 | } | ||
| 6805 | 6817 | ||
| 6806 | register_inet6addr_notifier(&cxgb4_inet6addr_notifier); | 6818 | register_inet6addr_notifier(&cxgb4_inet6addr_notifier); |
| 6807 | 6819 | ||
| @@ -6813,8 +6825,6 @@ static void __exit cxgb4_cleanup_module(void) | |||
| 6813 | unregister_inet6addr_notifier(&cxgb4_inet6addr_notifier); | 6825 | unregister_inet6addr_notifier(&cxgb4_inet6addr_notifier); |
| 6814 | pci_unregister_driver(&cxgb4_driver); | 6826 | pci_unregister_driver(&cxgb4_driver); |
| 6815 | debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ | 6827 | debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ |
| 6816 | flush_workqueue(workq); | ||
| 6817 | destroy_workqueue(workq); | ||
| 6818 | } | 6828 | } |
| 6819 | 6829 | ||
| 6820 | module_init(cxgb4_init_module); | 6830 | module_init(cxgb4_init_module); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index b0bba32d69d5..d22d728d4e5c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
| @@ -2303,7 +2303,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | |||
| 2303 | FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); | 2303 | FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); |
| 2304 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | | 2304 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | |
| 2305 | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); | 2305 | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); |
| 2306 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); | 2306 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE | |
| 2307 | FW_EQ_ETH_CMD_VIID(pi->viid)); | ||
| 2307 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | | 2308 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | |
| 2308 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | | 2309 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | |
| 2309 | FW_EQ_ETH_CMD_FETCHRO(1) | | 2310 | FW_EQ_ETH_CMD_FETCHRO(1) | |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a853133d8db8..41d04462b72e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
| @@ -168,6 +168,34 @@ void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val) | |||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | /* | 170 | /* |
| 171 | * t4_report_fw_error - report firmware error | ||
| 172 | * @adap: the adapter | ||
| 173 | * | ||
| 174 | * The adapter firmware can indicate error conditions to the host. | ||
| 175 | * If the firmware has indicated an error, print out the reason for | ||
| 176 | * the firmware error. | ||
| 177 | */ | ||
| 178 | static void t4_report_fw_error(struct adapter *adap) | ||
| 179 | { | ||
| 180 | static const char *const reason[] = { | ||
| 181 | "Crash", /* PCIE_FW_EVAL_CRASH */ | ||
| 182 | "During Device Preparation", /* PCIE_FW_EVAL_PREP */ | ||
| 183 | "During Device Configuration", /* PCIE_FW_EVAL_CONF */ | ||
| 184 | "During Device Initialization", /* PCIE_FW_EVAL_INIT */ | ||
| 185 | "Unexpected Event", /* PCIE_FW_EVAL_UNEXPECTEDEVENT */ | ||
| 186 | "Insufficient Airflow", /* PCIE_FW_EVAL_OVERHEAT */ | ||
| 187 | "Device Shutdown", /* PCIE_FW_EVAL_DEVICESHUTDOWN */ | ||
| 188 | "Reserved", /* reserved */ | ||
| 189 | }; | ||
| 190 | u32 pcie_fw; | ||
| 191 | |||
| 192 | pcie_fw = t4_read_reg(adap, MA_PCIE_FW); | ||
| 193 | if (pcie_fw & FW_PCIE_FW_ERR) | ||
| 194 | dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n", | ||
| 195 | reason[FW_PCIE_FW_EVAL_GET(pcie_fw)]); | ||
| 196 | } | ||
| 197 | |||
| 198 | /* | ||
| 171 | * Get the reply to a mailbox command and store it in @rpl in big-endian order. | 199 | * Get the reply to a mailbox command and store it in @rpl in big-endian order. |
| 172 | */ | 200 | */ |
| 173 | static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, | 201 | static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, |
| @@ -300,6 +328,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, | |||
| 300 | dump_mbox(adap, mbox, data_reg); | 328 | dump_mbox(adap, mbox, data_reg); |
| 301 | dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", | 329 | dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", |
| 302 | *(const u8 *)cmd, mbox); | 330 | *(const u8 *)cmd, mbox); |
| 331 | t4_report_fw_error(adap); | ||
| 303 | return -ETIMEDOUT; | 332 | return -ETIMEDOUT; |
| 304 | } | 333 | } |
| 305 | 334 | ||
| @@ -566,6 +595,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, | |||
| 566 | #define VPD_BASE 0x400 | 595 | #define VPD_BASE 0x400 |
| 567 | #define VPD_BASE_OLD 0 | 596 | #define VPD_BASE_OLD 0 |
| 568 | #define VPD_LEN 1024 | 597 | #define VPD_LEN 1024 |
| 598 | #define CHELSIO_VPD_UNIQUE_ID 0x82 | ||
| 569 | 599 | ||
| 570 | /** | 600 | /** |
| 571 | * t4_seeprom_wp - enable/disable EEPROM write protection | 601 | * t4_seeprom_wp - enable/disable EEPROM write protection |
| @@ -603,7 +633,14 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
| 603 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); | 633 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); |
| 604 | if (ret < 0) | 634 | if (ret < 0) |
| 605 | goto out; | 635 | goto out; |
| 606 | addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD; | 636 | |
| 637 | /* The VPD shall have a unique identifier specified by the PCI SIG. | ||
| 638 | * For chelsio adapters, the identifier is 0x82. The first byte of a VPD | ||
| 639 | * shall be CHELSIO_VPD_UNIQUE_ID (0x82). The VPD programming software | ||
| 640 | * is expected to automatically put this entry at the | ||
| 641 | * beginning of the VPD. | ||
| 642 | */ | ||
| 643 | addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD; | ||
| 607 | 644 | ||
| 608 | ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); | 645 | ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); |
| 609 | if (ret < 0) | 646 | if (ret < 0) |
| @@ -667,6 +704,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
| 667 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); | 704 | i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE); |
| 668 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); | 705 | memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); |
| 669 | strim(p->sn); | 706 | strim(p->sn); |
| 707 | i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE); | ||
| 670 | memcpy(p->pn, vpd + pn, min(i, PN_LEN)); | 708 | memcpy(p->pn, vpd + pn, min(i, PN_LEN)); |
| 671 | strim(p->pn); | 709 | strim(p->pn); |
| 672 | 710 | ||
| @@ -1394,15 +1432,18 @@ static void pcie_intr_handler(struct adapter *adapter) | |||
| 1394 | 1432 | ||
| 1395 | int fat; | 1433 | int fat; |
| 1396 | 1434 | ||
| 1397 | fat = t4_handle_intr_status(adapter, | 1435 | if (is_t4(adapter->params.chip)) |
| 1398 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, | 1436 | fat = t4_handle_intr_status(adapter, |
| 1399 | sysbus_intr_info) + | 1437 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, |
| 1400 | t4_handle_intr_status(adapter, | 1438 | sysbus_intr_info) + |
| 1401 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, | 1439 | t4_handle_intr_status(adapter, |
| 1402 | pcie_port_intr_info) + | 1440 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, |
| 1403 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, | 1441 | pcie_port_intr_info) + |
| 1404 | is_t4(adapter->params.chip) ? | 1442 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, |
| 1405 | pcie_intr_info : t5_pcie_intr_info); | 1443 | pcie_intr_info); |
| 1444 | else | ||
| 1445 | fat = t4_handle_intr_status(adapter, PCIE_INT_CAUSE, | ||
| 1446 | t5_pcie_intr_info); | ||
| 1406 | 1447 | ||
| 1407 | if (fat) | 1448 | if (fat) |
| 1408 | t4_fatal_err(adapter); | 1449 | t4_fatal_err(adapter); |
| @@ -1521,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter) | |||
| 1521 | 1562 | ||
| 1522 | int fat; | 1563 | int fat; |
| 1523 | 1564 | ||
| 1565 | if (t4_read_reg(adapter, MA_PCIE_FW) & FW_PCIE_FW_ERR) | ||
| 1566 | t4_report_fw_error(adapter); | ||
| 1567 | |||
| 1524 | fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, | 1568 | fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, |
| 1525 | cim_intr_info) + | 1569 | cim_intr_info) + |
| 1526 | t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, | 1570 | t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, |
| @@ -1768,10 +1812,16 @@ static void ma_intr_handler(struct adapter *adap) | |||
| 1768 | { | 1812 | { |
| 1769 | u32 v, status = t4_read_reg(adap, MA_INT_CAUSE); | 1813 | u32 v, status = t4_read_reg(adap, MA_INT_CAUSE); |
| 1770 | 1814 | ||
| 1771 | if (status & MEM_PERR_INT_CAUSE) | 1815 | if (status & MEM_PERR_INT_CAUSE) { |
| 1772 | dev_alert(adap->pdev_dev, | 1816 | dev_alert(adap->pdev_dev, |
| 1773 | "MA parity error, parity status %#x\n", | 1817 | "MA parity error, parity status %#x\n", |
| 1774 | t4_read_reg(adap, MA_PARITY_ERROR_STATUS)); | 1818 | t4_read_reg(adap, MA_PARITY_ERROR_STATUS)); |
| 1819 | if (is_t5(adap->params.chip)) | ||
| 1820 | dev_alert(adap->pdev_dev, | ||
| 1821 | "MA parity error, parity status %#x\n", | ||
| 1822 | t4_read_reg(adap, | ||
| 1823 | MA_PARITY_ERROR_STATUS2)); | ||
| 1824 | } | ||
| 1775 | if (status & MEM_WRAP_INT_CAUSE) { | 1825 | if (status & MEM_WRAP_INT_CAUSE) { |
| 1776 | v = t4_read_reg(adap, MA_INT_WRAP_STATUS); | 1826 | v = t4_read_reg(adap, MA_INT_WRAP_STATUS); |
| 1777 | dev_alert(adap->pdev_dev, "MA address wrap-around error by " | 1827 | dev_alert(adap->pdev_dev, "MA address wrap-around error by " |
| @@ -2733,12 +2783,16 @@ retry: | |||
| 2733 | /* | 2783 | /* |
| 2734 | * Issue the HELLO command to the firmware. If it's not successful | 2784 | * Issue the HELLO command to the firmware. If it's not successful |
| 2735 | * but indicates that we got a "busy" or "timeout" condition, retry | 2785 | * but indicates that we got a "busy" or "timeout" condition, retry |
| 2736 | * the HELLO until we exhaust our retry limit. | 2786 | * the HELLO until we exhaust our retry limit. If we do exceed our |
| 2787 | * retry limit, check to see if the firmware left us any error | ||
| 2788 | * information and report that if so. | ||
| 2737 | */ | 2789 | */ |
| 2738 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | 2790 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); |
| 2739 | if (ret < 0) { | 2791 | if (ret < 0) { |
| 2740 | if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) | 2792 | if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) |
| 2741 | goto retry; | 2793 | goto retry; |
| 2794 | if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR) | ||
| 2795 | t4_report_fw_error(adap); | ||
| 2742 | return ret; | 2796 | return ret; |
| 2743 | } | 2797 | } |
| 2744 | 2798 | ||
| @@ -3742,6 +3796,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) | |||
| 3742 | lc->link_ok = link_ok; | 3796 | lc->link_ok = link_ok; |
| 3743 | lc->speed = speed; | 3797 | lc->speed = speed; |
| 3744 | lc->fc = fc; | 3798 | lc->fc = fc; |
| 3799 | lc->supported = be16_to_cpu(p->u.info.pcap); | ||
| 3745 | t4_os_link_changed(adap, port, link_ok); | 3800 | t4_os_link_changed(adap, port, link_ok); |
| 3746 | } | 3801 | } |
| 3747 | if (mod != pi->mod_type) { | 3802 | if (mod != pi->mod_type) { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index e3146e83df20..39fb325474f7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
| @@ -511,6 +511,7 @@ | |||
| 511 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) | 511 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) |
| 512 | #define MA_PCIE_FW 0x30b8 | 512 | #define MA_PCIE_FW 0x30b8 |
| 513 | #define MA_PARITY_ERROR_STATUS 0x77f4 | 513 | #define MA_PARITY_ERROR_STATUS 0x77f4 |
| 514 | #define MA_PARITY_ERROR_STATUS2 0x7804 | ||
| 514 | 515 | ||
| 515 | #define MA_EXT_MEMORY1_BAR 0x7808 | 516 | #define MA_EXT_MEMORY1_BAR 0x7808 |
| 516 | #define EDC_0_BASE_ADDR 0x7900 | 517 | #define EDC_0_BASE_ADDR 0x7900 |
| @@ -959,6 +960,7 @@ | |||
| 959 | #define TRCMULTIFILTER 0x00000001U | 960 | #define TRCMULTIFILTER 0x00000001U |
| 960 | 961 | ||
| 961 | #define MPS_TRC_RSS_CONTROL 0x9808 | 962 | #define MPS_TRC_RSS_CONTROL 0x9808 |
| 963 | #define MPS_T5_TRC_RSS_CONTROL 0xa00c | ||
| 962 | #define RSSCONTROL_MASK 0x00ff0000U | 964 | #define RSSCONTROL_MASK 0x00ff0000U |
| 963 | #define RSSCONTROL_SHIFT 16 | 965 | #define RSSCONTROL_SHIFT 16 |
| 964 | #define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT) | 966 | #define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 0549170d7e2e..3409756a85b9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
| @@ -1227,6 +1227,7 @@ struct fw_eq_eth_cmd { | |||
| 1227 | #define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) | 1227 | #define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) |
| 1228 | #define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) | 1228 | #define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) |
| 1229 | 1229 | ||
| 1230 | #define FW_EQ_ETH_CMD_AUTOEQUEQE (1U << 30) | ||
| 1230 | #define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) | 1231 | #define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) |
| 1231 | 1232 | ||
| 1232 | struct fw_eq_ctrl_cmd { | 1233 | struct fw_eq_ctrl_cmd { |
| @@ -2227,6 +2228,10 @@ struct fw_debug_cmd { | |||
| 2227 | #define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) | 2228 | #define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) |
| 2228 | #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ | 2229 | #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ |
| 2229 | FW_PCIE_FW_MASTER_MASK) | 2230 | FW_PCIE_FW_MASTER_MASK) |
| 2231 | #define FW_PCIE_FW_EVAL_MASK 0x7 | ||
| 2232 | #define FW_PCIE_FW_EVAL_SHIFT 24 | ||
| 2233 | #define FW_PCIE_FW_EVAL_GET(x) (((x) >> FW_PCIE_FW_EVAL_SHIFT) & \ | ||
| 2234 | FW_PCIE_FW_EVAL_MASK) | ||
| 2230 | 2235 | ||
| 2231 | struct fw_hdr { | 2236 | struct fw_hdr { |
| 2232 | u8 ver; | 2237 | u8 ver; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index bdfa80ca5e31..a5fb9493dee8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c | |||
| @@ -2250,7 +2250,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, | |||
| 2250 | cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | | 2250 | cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | |
| 2251 | FW_EQ_ETH_CMD_EQSTART | | 2251 | FW_EQ_ETH_CMD_EQSTART | |
| 2252 | FW_LEN16(cmd)); | 2252 | FW_LEN16(cmd)); |
| 2253 | cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_VIID(pi->viid)); | 2253 | cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE | |
| 2254 | FW_EQ_ETH_CMD_VIID(pi->viid)); | ||
| 2254 | cmd.fetchszm_to_iqid = | 2255 | cmd.fetchszm_to_iqid = |
| 2255 | cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) | | 2256 | cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) | |
| 2256 | FW_EQ_ETH_CMD_PCIECHN(pi->port_id) | | 2257 | FW_EQ_ETH_CMD_PCIECHN(pi->port_id) | |
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 9f7fa644a397..ee41d98b44b6 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
| @@ -275,6 +275,9 @@ struct fec_enet_private { | |||
| 275 | struct clk *clk_enet_out; | 275 | struct clk *clk_enet_out; |
| 276 | struct clk *clk_ptp; | 276 | struct clk *clk_ptp; |
| 277 | 277 | ||
| 278 | bool ptp_clk_on; | ||
| 279 | struct mutex ptp_clk_mutex; | ||
| 280 | |||
| 278 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | 281 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ |
| 279 | unsigned char *tx_bounce[TX_RING_SIZE]; | 282 | unsigned char *tx_bounce[TX_RING_SIZE]; |
| 280 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | 283 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; |
| @@ -335,7 +338,7 @@ struct fec_enet_private { | |||
| 335 | u32 cycle_speed; | 338 | u32 cycle_speed; |
| 336 | int hwts_rx_en; | 339 | int hwts_rx_en; |
| 337 | int hwts_tx_en; | 340 | int hwts_tx_en; |
| 338 | struct timer_list time_keep; | 341 | struct delayed_work time_keep; |
| 339 | struct regulator *reg_phy; | 342 | struct regulator *reg_phy; |
| 340 | }; | 343 | }; |
| 341 | 344 | ||
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 4f87dffcb9b2..89355a719625 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -1611,17 +1611,27 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) | |||
| 1611 | goto failed_clk_enet_out; | 1611 | goto failed_clk_enet_out; |
| 1612 | } | 1612 | } |
| 1613 | if (fep->clk_ptp) { | 1613 | if (fep->clk_ptp) { |
| 1614 | mutex_lock(&fep->ptp_clk_mutex); | ||
| 1614 | ret = clk_prepare_enable(fep->clk_ptp); | 1615 | ret = clk_prepare_enable(fep->clk_ptp); |
| 1615 | if (ret) | 1616 | if (ret) { |
| 1617 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 1616 | goto failed_clk_ptp; | 1618 | goto failed_clk_ptp; |
| 1619 | } else { | ||
| 1620 | fep->ptp_clk_on = true; | ||
| 1621 | } | ||
| 1622 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 1617 | } | 1623 | } |
| 1618 | } else { | 1624 | } else { |
| 1619 | clk_disable_unprepare(fep->clk_ahb); | 1625 | clk_disable_unprepare(fep->clk_ahb); |
| 1620 | clk_disable_unprepare(fep->clk_ipg); | 1626 | clk_disable_unprepare(fep->clk_ipg); |
| 1621 | if (fep->clk_enet_out) | 1627 | if (fep->clk_enet_out) |
| 1622 | clk_disable_unprepare(fep->clk_enet_out); | 1628 | clk_disable_unprepare(fep->clk_enet_out); |
| 1623 | if (fep->clk_ptp) | 1629 | if (fep->clk_ptp) { |
| 1630 | mutex_lock(&fep->ptp_clk_mutex); | ||
| 1624 | clk_disable_unprepare(fep->clk_ptp); | 1631 | clk_disable_unprepare(fep->clk_ptp); |
| 1632 | fep->ptp_clk_on = false; | ||
| 1633 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 1634 | } | ||
| 1625 | } | 1635 | } |
| 1626 | 1636 | ||
| 1627 | return 0; | 1637 | return 0; |
| @@ -2625,6 +2635,8 @@ fec_probe(struct platform_device *pdev) | |||
| 2625 | if (IS_ERR(fep->clk_enet_out)) | 2635 | if (IS_ERR(fep->clk_enet_out)) |
| 2626 | fep->clk_enet_out = NULL; | 2636 | fep->clk_enet_out = NULL; |
| 2627 | 2637 | ||
| 2638 | fep->ptp_clk_on = false; | ||
| 2639 | mutex_init(&fep->ptp_clk_mutex); | ||
| 2628 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); | 2640 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); |
| 2629 | fep->bufdesc_ex = | 2641 | fep->bufdesc_ex = |
| 2630 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; | 2642 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; |
| @@ -2715,10 +2727,10 @@ fec_drv_remove(struct platform_device *pdev) | |||
| 2715 | struct net_device *ndev = platform_get_drvdata(pdev); | 2727 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 2716 | struct fec_enet_private *fep = netdev_priv(ndev); | 2728 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 2717 | 2729 | ||
| 2730 | cancel_delayed_work_sync(&fep->time_keep); | ||
| 2718 | cancel_work_sync(&fep->tx_timeout_work); | 2731 | cancel_work_sync(&fep->tx_timeout_work); |
| 2719 | unregister_netdev(ndev); | 2732 | unregister_netdev(ndev); |
| 2720 | fec_enet_mii_remove(fep); | 2733 | fec_enet_mii_remove(fep); |
| 2721 | del_timer_sync(&fep->time_keep); | ||
| 2722 | if (fep->reg_phy) | 2734 | if (fep->reg_phy) |
| 2723 | regulator_disable(fep->reg_phy); | 2735 | regulator_disable(fep->reg_phy); |
| 2724 | if (fep->ptp_clock) | 2736 | if (fep->ptp_clock) |
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 82386b29914a..cca3617a2321 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c | |||
| @@ -245,12 +245,20 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, | |||
| 245 | u64 ns; | 245 | u64 ns; |
| 246 | unsigned long flags; | 246 | unsigned long flags; |
| 247 | 247 | ||
| 248 | mutex_lock(&fep->ptp_clk_mutex); | ||
| 249 | /* Check the ptp clock */ | ||
| 250 | if (!fep->ptp_clk_on) { | ||
| 251 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 252 | return -EINVAL; | ||
| 253 | } | ||
| 254 | |||
| 248 | ns = ts->tv_sec * 1000000000ULL; | 255 | ns = ts->tv_sec * 1000000000ULL; |
| 249 | ns += ts->tv_nsec; | 256 | ns += ts->tv_nsec; |
| 250 | 257 | ||
| 251 | spin_lock_irqsave(&fep->tmreg_lock, flags); | 258 | spin_lock_irqsave(&fep->tmreg_lock, flags); |
| 252 | timecounter_init(&fep->tc, &fep->cc, ns); | 259 | timecounter_init(&fep->tc, &fep->cc, ns); |
| 253 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | 260 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); |
| 261 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 254 | return 0; | 262 | return 0; |
| 255 | } | 263 | } |
| 256 | 264 | ||
| @@ -338,17 +346,22 @@ int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr) | |||
| 338 | * fec_time_keep - call timecounter_read every second to avoid timer overrun | 346 | * fec_time_keep - call timecounter_read every second to avoid timer overrun |
| 339 | * because ENET just support 32bit counter, will timeout in 4s | 347 | * because ENET just support 32bit counter, will timeout in 4s |
| 340 | */ | 348 | */ |
| 341 | static void fec_time_keep(unsigned long _data) | 349 | static void fec_time_keep(struct work_struct *work) |
| 342 | { | 350 | { |
| 343 | struct fec_enet_private *fep = (struct fec_enet_private *)_data; | 351 | struct delayed_work *dwork = to_delayed_work(work); |
| 352 | struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep); | ||
| 344 | u64 ns; | 353 | u64 ns; |
| 345 | unsigned long flags; | 354 | unsigned long flags; |
| 346 | 355 | ||
| 347 | spin_lock_irqsave(&fep->tmreg_lock, flags); | 356 | mutex_lock(&fep->ptp_clk_mutex); |
| 348 | ns = timecounter_read(&fep->tc); | 357 | if (fep->ptp_clk_on) { |
| 349 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | 358 | spin_lock_irqsave(&fep->tmreg_lock, flags); |
| 359 | ns = timecounter_read(&fep->tc); | ||
| 360 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
| 361 | } | ||
| 362 | mutex_unlock(&fep->ptp_clk_mutex); | ||
| 350 | 363 | ||
| 351 | mod_timer(&fep->time_keep, jiffies + HZ); | 364 | schedule_delayed_work(&fep->time_keep, HZ); |
| 352 | } | 365 | } |
| 353 | 366 | ||
| 354 | /** | 367 | /** |
| @@ -386,15 +399,13 @@ void fec_ptp_init(struct platform_device *pdev) | |||
| 386 | 399 | ||
| 387 | fec_ptp_start_cyclecounter(ndev); | 400 | fec_ptp_start_cyclecounter(ndev); |
| 388 | 401 | ||
| 389 | init_timer(&fep->time_keep); | 402 | INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); |
| 390 | fep->time_keep.data = (unsigned long)fep; | ||
| 391 | fep->time_keep.function = fec_time_keep; | ||
| 392 | fep->time_keep.expires = jiffies + HZ; | ||
| 393 | add_timer(&fep->time_keep); | ||
| 394 | 403 | ||
| 395 | fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); | 404 | fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); |
| 396 | if (IS_ERR(fep->ptp_clock)) { | 405 | if (IS_ERR(fep->ptp_clock)) { |
| 397 | fep->ptp_clock = NULL; | 406 | fep->ptp_clock = NULL; |
| 398 | pr_err("ptp_clock_register failed\n"); | 407 | pr_err("ptp_clock_register failed\n"); |
| 399 | } | 408 | } |
| 409 | |||
| 410 | schedule_delayed_work(&fep->time_keep, HZ); | ||
| 400 | } | 411 | } |
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index a0b418e007a0..566b17db135a 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
| @@ -1994,7 +1994,7 @@ static void xmit_common(struct sk_buff *skb, struct ehea_swqe *swqe) | |||
| 1994 | { | 1994 | { |
| 1995 | swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT | EHEA_SWQE_CRC; | 1995 | swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT | EHEA_SWQE_CRC; |
| 1996 | 1996 | ||
| 1997 | if (skb->protocol != htons(ETH_P_IP)) | 1997 | if (vlan_get_protocol(skb) != htons(ETH_P_IP)) |
| 1998 | return; | 1998 | return; |
| 1999 | 1999 | ||
| 2000 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 2000 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index c9127562bd22..21978cc019e7 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
| @@ -292,6 +292,18 @@ failure: | |||
| 292 | atomic_add(buffers_added, &(pool->available)); | 292 | atomic_add(buffers_added, &(pool->available)); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | /* | ||
| 296 | * The final 8 bytes of the buffer list is a counter of frames dropped | ||
| 297 | * because there was not a buffer in the buffer list capable of holding | ||
| 298 | * the frame. | ||
| 299 | */ | ||
| 300 | static void ibmveth_update_rx_no_buffer(struct ibmveth_adapter *adapter) | ||
| 301 | { | ||
| 302 | __be64 *p = adapter->buffer_list_addr + 4096 - 8; | ||
| 303 | |||
| 304 | adapter->rx_no_buffer = be64_to_cpup(p); | ||
| 305 | } | ||
| 306 | |||
| 295 | /* replenish routine */ | 307 | /* replenish routine */ |
| 296 | static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) | 308 | static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) |
| 297 | { | 309 | { |
| @@ -307,8 +319,7 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) | |||
| 307 | ibmveth_replenish_buffer_pool(adapter, pool); | 319 | ibmveth_replenish_buffer_pool(adapter, pool); |
| 308 | } | 320 | } |
| 309 | 321 | ||
| 310 | adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) + | 322 | ibmveth_update_rx_no_buffer(adapter); |
| 311 | 4096 - 8); | ||
| 312 | } | 323 | } |
| 313 | 324 | ||
| 314 | /* empty and free ana buffer pool - also used to do cleanup in error paths */ | 325 | /* empty and free ana buffer pool - also used to do cleanup in error paths */ |
| @@ -698,8 +709,7 @@ static int ibmveth_close(struct net_device *netdev) | |||
| 698 | 709 | ||
| 699 | free_irq(netdev->irq, netdev); | 710 | free_irq(netdev->irq, netdev); |
| 700 | 711 | ||
| 701 | adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) + | 712 | ibmveth_update_rx_no_buffer(adapter); |
| 702 | 4096 - 8); | ||
| 703 | 713 | ||
| 704 | ibmveth_cleanup(adapter); | 714 | ibmveth_cleanup(adapter); |
| 705 | 715 | ||
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index cbc330b301cd..ad3d5d12173f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
| @@ -2674,7 +2674,8 @@ set_itr_now: | |||
| 2674 | #define E1000_TX_FLAGS_VLAN_SHIFT 16 | 2674 | #define E1000_TX_FLAGS_VLAN_SHIFT 16 |
| 2675 | 2675 | ||
| 2676 | static int e1000_tso(struct e1000_adapter *adapter, | 2676 | static int e1000_tso(struct e1000_adapter *adapter, |
| 2677 | struct e1000_tx_ring *tx_ring, struct sk_buff *skb) | 2677 | struct e1000_tx_ring *tx_ring, struct sk_buff *skb, |
| 2678 | __be16 protocol) | ||
| 2678 | { | 2679 | { |
| 2679 | struct e1000_context_desc *context_desc; | 2680 | struct e1000_context_desc *context_desc; |
| 2680 | struct e1000_buffer *buffer_info; | 2681 | struct e1000_buffer *buffer_info; |
| @@ -2692,7 +2693,7 @@ static int e1000_tso(struct e1000_adapter *adapter, | |||
| 2692 | 2693 | ||
| 2693 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 2694 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 2694 | mss = skb_shinfo(skb)->gso_size; | 2695 | mss = skb_shinfo(skb)->gso_size; |
| 2695 | if (skb->protocol == htons(ETH_P_IP)) { | 2696 | if (protocol == htons(ETH_P_IP)) { |
| 2696 | struct iphdr *iph = ip_hdr(skb); | 2697 | struct iphdr *iph = ip_hdr(skb); |
| 2697 | iph->tot_len = 0; | 2698 | iph->tot_len = 0; |
| 2698 | iph->check = 0; | 2699 | iph->check = 0; |
| @@ -2702,7 +2703,7 @@ static int e1000_tso(struct e1000_adapter *adapter, | |||
| 2702 | 0); | 2703 | 0); |
| 2703 | cmd_length = E1000_TXD_CMD_IP; | 2704 | cmd_length = E1000_TXD_CMD_IP; |
| 2704 | ipcse = skb_transport_offset(skb) - 1; | 2705 | ipcse = skb_transport_offset(skb) - 1; |
| 2705 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 2706 | } else if (skb_is_gso_v6(skb)) { |
| 2706 | ipv6_hdr(skb)->payload_len = 0; | 2707 | ipv6_hdr(skb)->payload_len = 0; |
| 2707 | tcp_hdr(skb)->check = | 2708 | tcp_hdr(skb)->check = |
| 2708 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 2709 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
| @@ -2745,7 +2746,8 @@ static int e1000_tso(struct e1000_adapter *adapter, | |||
| 2745 | } | 2746 | } |
| 2746 | 2747 | ||
| 2747 | static bool e1000_tx_csum(struct e1000_adapter *adapter, | 2748 | static bool e1000_tx_csum(struct e1000_adapter *adapter, |
| 2748 | struct e1000_tx_ring *tx_ring, struct sk_buff *skb) | 2749 | struct e1000_tx_ring *tx_ring, struct sk_buff *skb, |
| 2750 | __be16 protocol) | ||
| 2749 | { | 2751 | { |
| 2750 | struct e1000_context_desc *context_desc; | 2752 | struct e1000_context_desc *context_desc; |
| 2751 | struct e1000_buffer *buffer_info; | 2753 | struct e1000_buffer *buffer_info; |
| @@ -2756,7 +2758,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, | |||
| 2756 | if (skb->ip_summed != CHECKSUM_PARTIAL) | 2758 | if (skb->ip_summed != CHECKSUM_PARTIAL) |
| 2757 | return false; | 2759 | return false; |
| 2758 | 2760 | ||
| 2759 | switch (skb->protocol) { | 2761 | switch (protocol) { |
| 2760 | case cpu_to_be16(ETH_P_IP): | 2762 | case cpu_to_be16(ETH_P_IP): |
| 2761 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | 2763 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) |
| 2762 | cmd_len |= E1000_TXD_CMD_TCP; | 2764 | cmd_len |= E1000_TXD_CMD_TCP; |
| @@ -3097,6 +3099,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 3097 | int count = 0; | 3099 | int count = 0; |
| 3098 | int tso; | 3100 | int tso; |
| 3099 | unsigned int f; | 3101 | unsigned int f; |
| 3102 | __be16 protocol = vlan_get_protocol(skb); | ||
| 3100 | 3103 | ||
| 3101 | /* This goes back to the question of how to logically map a Tx queue | 3104 | /* This goes back to the question of how to logically map a Tx queue |
| 3102 | * to a flow. Right now, performance is impacted slightly negatively | 3105 | * to a flow. Right now, performance is impacted slightly negatively |
| @@ -3210,7 +3213,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 3210 | 3213 | ||
| 3211 | first = tx_ring->next_to_use; | 3214 | first = tx_ring->next_to_use; |
| 3212 | 3215 | ||
| 3213 | tso = e1000_tso(adapter, tx_ring, skb); | 3216 | tso = e1000_tso(adapter, tx_ring, skb, protocol); |
| 3214 | if (tso < 0) { | 3217 | if (tso < 0) { |
| 3215 | dev_kfree_skb_any(skb); | 3218 | dev_kfree_skb_any(skb); |
| 3216 | return NETDEV_TX_OK; | 3219 | return NETDEV_TX_OK; |
| @@ -3220,10 +3223,10 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 3220 | if (likely(hw->mac_type != e1000_82544)) | 3223 | if (likely(hw->mac_type != e1000_82544)) |
| 3221 | tx_ring->last_tx_tso = true; | 3224 | tx_ring->last_tx_tso = true; |
| 3222 | tx_flags |= E1000_TX_FLAGS_TSO; | 3225 | tx_flags |= E1000_TX_FLAGS_TSO; |
| 3223 | } else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) | 3226 | } else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol))) |
| 3224 | tx_flags |= E1000_TX_FLAGS_CSUM; | 3227 | tx_flags |= E1000_TX_FLAGS_CSUM; |
| 3225 | 3228 | ||
| 3226 | if (likely(skb->protocol == htons(ETH_P_IP))) | 3229 | if (protocol == htons(ETH_P_IP)) |
| 3227 | tx_flags |= E1000_TX_FLAGS_IPV4; | 3230 | tx_flags |= E1000_TX_FLAGS_IPV4; |
| 3228 | 3231 | ||
| 3229 | if (unlikely(skb->no_fcs)) | 3232 | if (unlikely(skb->no_fcs)) |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 65c3aef2bd36..247335d2c7ec 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
| @@ -5164,7 +5164,8 @@ link_up: | |||
| 5164 | #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 | 5164 | #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 |
| 5165 | #define E1000_TX_FLAGS_VLAN_SHIFT 16 | 5165 | #define E1000_TX_FLAGS_VLAN_SHIFT 16 |
| 5166 | 5166 | ||
| 5167 | static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) | 5167 | static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb, |
| 5168 | __be16 protocol) | ||
| 5168 | { | 5169 | { |
| 5169 | struct e1000_context_desc *context_desc; | 5170 | struct e1000_context_desc *context_desc; |
| 5170 | struct e1000_buffer *buffer_info; | 5171 | struct e1000_buffer *buffer_info; |
| @@ -5183,7 +5184,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) | |||
| 5183 | 5184 | ||
| 5184 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 5185 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 5185 | mss = skb_shinfo(skb)->gso_size; | 5186 | mss = skb_shinfo(skb)->gso_size; |
| 5186 | if (skb->protocol == htons(ETH_P_IP)) { | 5187 | if (protocol == htons(ETH_P_IP)) { |
| 5187 | struct iphdr *iph = ip_hdr(skb); | 5188 | struct iphdr *iph = ip_hdr(skb); |
| 5188 | iph->tot_len = 0; | 5189 | iph->tot_len = 0; |
| 5189 | iph->check = 0; | 5190 | iph->check = 0; |
| @@ -5231,7 +5232,8 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) | |||
| 5231 | return 1; | 5232 | return 1; |
| 5232 | } | 5233 | } |
| 5233 | 5234 | ||
| 5234 | static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) | 5235 | static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb, |
| 5236 | __be16 protocol) | ||
| 5235 | { | 5237 | { |
| 5236 | struct e1000_adapter *adapter = tx_ring->adapter; | 5238 | struct e1000_adapter *adapter = tx_ring->adapter; |
| 5237 | struct e1000_context_desc *context_desc; | 5239 | struct e1000_context_desc *context_desc; |
| @@ -5239,16 +5241,10 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) | |||
| 5239 | unsigned int i; | 5241 | unsigned int i; |
| 5240 | u8 css; | 5242 | u8 css; |
| 5241 | u32 cmd_len = E1000_TXD_CMD_DEXT; | 5243 | u32 cmd_len = E1000_TXD_CMD_DEXT; |
| 5242 | __be16 protocol; | ||
| 5243 | 5244 | ||
| 5244 | if (skb->ip_summed != CHECKSUM_PARTIAL) | 5245 | if (skb->ip_summed != CHECKSUM_PARTIAL) |
| 5245 | return false; | 5246 | return false; |
| 5246 | 5247 | ||
| 5247 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) | ||
| 5248 | protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; | ||
| 5249 | else | ||
| 5250 | protocol = skb->protocol; | ||
| 5251 | |||
| 5252 | switch (protocol) { | 5248 | switch (protocol) { |
| 5253 | case cpu_to_be16(ETH_P_IP): | 5249 | case cpu_to_be16(ETH_P_IP): |
| 5254 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | 5250 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) |
| @@ -5546,6 +5542,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 5546 | int count = 0; | 5542 | int count = 0; |
| 5547 | int tso; | 5543 | int tso; |
| 5548 | unsigned int f; | 5544 | unsigned int f; |
| 5545 | __be16 protocol = vlan_get_protocol(skb); | ||
| 5549 | 5546 | ||
| 5550 | if (test_bit(__E1000_DOWN, &adapter->state)) { | 5547 | if (test_bit(__E1000_DOWN, &adapter->state)) { |
| 5551 | dev_kfree_skb_any(skb); | 5548 | dev_kfree_skb_any(skb); |
| @@ -5620,7 +5617,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 5620 | 5617 | ||
| 5621 | first = tx_ring->next_to_use; | 5618 | first = tx_ring->next_to_use; |
| 5622 | 5619 | ||
| 5623 | tso = e1000_tso(tx_ring, skb); | 5620 | tso = e1000_tso(tx_ring, skb, protocol); |
| 5624 | if (tso < 0) { | 5621 | if (tso < 0) { |
| 5625 | dev_kfree_skb_any(skb); | 5622 | dev_kfree_skb_any(skb); |
| 5626 | return NETDEV_TX_OK; | 5623 | return NETDEV_TX_OK; |
| @@ -5628,14 +5625,14 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
| 5628 | 5625 | ||
| 5629 | if (tso) | 5626 | if (tso) |
| 5630 | tx_flags |= E1000_TX_FLAGS_TSO; | 5627 | tx_flags |= E1000_TX_FLAGS_TSO; |
| 5631 | else if (e1000_tx_csum(tx_ring, skb)) | 5628 | else if (e1000_tx_csum(tx_ring, skb, protocol)) |
| 5632 | tx_flags |= E1000_TX_FLAGS_CSUM; | 5629 | tx_flags |= E1000_TX_FLAGS_CSUM; |
| 5633 | 5630 | ||
| 5634 | /* Old method was to assume IPv4 packet by default if TSO was enabled. | 5631 | /* Old method was to assume IPv4 packet by default if TSO was enabled. |
| 5635 | * 82571 hardware supports TSO capabilities for IPv6 as well... | 5632 | * 82571 hardware supports TSO capabilities for IPv6 as well... |
| 5636 | * no longer assume, we must. | 5633 | * no longer assume, we must. |
| 5637 | */ | 5634 | */ |
| 5638 | if (skb->protocol == htons(ETH_P_IP)) | 5635 | if (protocol == htons(ETH_P_IP)) |
| 5639 | tx_flags |= E1000_TX_FLAGS_IPV4; | 5636 | tx_flags |= E1000_TX_FLAGS_IPV4; |
| 5640 | 5637 | ||
| 5641 | if (unlikely(skb->no_fcs)) | 5638 | if (unlikely(skb->no_fcs)) |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index bb7fe98b3a6c..537b6216971d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c | |||
| @@ -247,7 +247,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi) | |||
| 247 | u32 prttsyn_stat; | 247 | u32 prttsyn_stat; |
| 248 | int n; | 248 | int n; |
| 249 | 249 | ||
| 250 | if (pf->flags & I40E_FLAG_PTP) | 250 | if (!(pf->flags & I40E_FLAG_PTP)) |
| 251 | return; | 251 | return; |
| 252 | 252 | ||
| 253 | prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1); | 253 | prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1); |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index a51aa37b7b5a..369848e107f8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
| @@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, | |||
| 2295 | goto out_drop; | 2295 | goto out_drop; |
| 2296 | 2296 | ||
| 2297 | /* obtain protocol of skb */ | 2297 | /* obtain protocol of skb */ |
| 2298 | protocol = skb->protocol; | 2298 | protocol = vlan_get_protocol(skb); |
| 2299 | 2299 | ||
| 2300 | /* record the location of the first descriptor for this packet */ | 2300 | /* record the location of the first descriptor for this packet */ |
| 2301 | first = &tx_ring->tx_bi[tx_ring->next_to_use]; | 2301 | first = &tx_ring->tx_bi[tx_ring->next_to_use]; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 89672551dce9..3ac6a0d2f143 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | |||
| @@ -1003,11 +1003,19 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) | |||
| 1003 | static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, | 1003 | static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, |
| 1004 | u32 v_retval, u8 *msg, u16 msglen) | 1004 | u32 v_retval, u8 *msg, u16 msglen) |
| 1005 | { | 1005 | { |
| 1006 | struct i40e_pf *pf = vf->pf; | 1006 | struct i40e_pf *pf; |
| 1007 | struct i40e_hw *hw = &pf->hw; | 1007 | struct i40e_hw *hw; |
| 1008 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | 1008 | int abs_vf_id; |
| 1009 | i40e_status aq_ret; | 1009 | i40e_status aq_ret; |
| 1010 | 1010 | ||
| 1011 | /* validate the request */ | ||
| 1012 | if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs) | ||
| 1013 | return -EINVAL; | ||
| 1014 | |||
| 1015 | pf = vf->pf; | ||
| 1016 | hw = &pf->hw; | ||
| 1017 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1018 | |||
| 1011 | /* single place to detect unsuccessful return values */ | 1019 | /* single place to detect unsuccessful return values */ |
| 1012 | if (v_retval) { | 1020 | if (v_retval) { |
| 1013 | vf->num_invalid_msgs++; | 1021 | vf->num_invalid_msgs++; |
| @@ -1928,17 +1936,20 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf, | |||
| 1928 | { | 1936 | { |
| 1929 | struct i40e_hw *hw = &pf->hw; | 1937 | struct i40e_hw *hw = &pf->hw; |
| 1930 | struct i40e_vf *vf = pf->vf; | 1938 | struct i40e_vf *vf = pf->vf; |
| 1931 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1932 | int i; | 1939 | int i; |
| 1933 | 1940 | ||
| 1934 | for (i = 0; i < pf->num_alloc_vfs; i++) { | 1941 | for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { |
| 1942 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1943 | /* Not all vfs are enabled so skip the ones that are not */ | ||
| 1944 | if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) && | ||
| 1945 | !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) | ||
| 1946 | continue; | ||
| 1947 | |||
| 1935 | /* Ignore return value on purpose - a given VF may fail, but | 1948 | /* Ignore return value on purpose - a given VF may fail, but |
| 1936 | * we need to keep going and send to all of them | 1949 | * we need to keep going and send to all of them |
| 1937 | */ | 1950 | */ |
| 1938 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval, | 1951 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval, |
| 1939 | msg, msglen, NULL); | 1952 | msg, msglen, NULL); |
| 1940 | vf++; | ||
| 1941 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1942 | } | 1953 | } |
| 1943 | } | 1954 | } |
| 1944 | 1955 | ||
| @@ -1954,12 +1965,12 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf) | |||
| 1954 | struct i40e_hw *hw = &pf->hw; | 1965 | struct i40e_hw *hw = &pf->hw; |
| 1955 | struct i40e_vf *vf = pf->vf; | 1966 | struct i40e_vf *vf = pf->vf; |
| 1956 | struct i40e_link_status *ls = &pf->hw.phy.link_info; | 1967 | struct i40e_link_status *ls = &pf->hw.phy.link_info; |
| 1957 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1958 | int i; | 1968 | int i; |
| 1959 | 1969 | ||
| 1960 | pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; | 1970 | pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; |
| 1961 | pfe.severity = I40E_PF_EVENT_SEVERITY_INFO; | 1971 | pfe.severity = I40E_PF_EVENT_SEVERITY_INFO; |
| 1962 | for (i = 0; i < pf->num_alloc_vfs; i++) { | 1972 | for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { |
| 1973 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1963 | if (vf->link_forced) { | 1974 | if (vf->link_forced) { |
| 1964 | pfe.event_data.link_event.link_status = vf->link_up; | 1975 | pfe.event_data.link_event.link_status = vf->link_up; |
| 1965 | pfe.event_data.link_event.link_speed = | 1976 | pfe.event_data.link_event.link_speed = |
| @@ -1972,8 +1983,6 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf) | |||
| 1972 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT, | 1983 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT, |
| 1973 | 0, (u8 *)&pfe, sizeof(pfe), | 1984 | 0, (u8 *)&pfe, sizeof(pfe), |
| 1974 | NULL); | 1985 | NULL); |
| 1975 | vf++; | ||
| 1976 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
| 1977 | } | 1986 | } |
| 1978 | } | 1987 | } |
| 1979 | 1988 | ||
| @@ -2002,7 +2011,18 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) | |||
| 2002 | void i40e_vc_notify_vf_reset(struct i40e_vf *vf) | 2011 | void i40e_vc_notify_vf_reset(struct i40e_vf *vf) |
| 2003 | { | 2012 | { |
| 2004 | struct i40e_virtchnl_pf_event pfe; | 2013 | struct i40e_virtchnl_pf_event pfe; |
| 2005 | int abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id; | 2014 | int abs_vf_id; |
| 2015 | |||
| 2016 | /* validate the request */ | ||
| 2017 | if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs) | ||
| 2018 | return; | ||
| 2019 | |||
| 2020 | /* verify if the VF is in either init or active before proceeding */ | ||
| 2021 | if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) && | ||
| 2022 | !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) | ||
| 2023 | return; | ||
| 2024 | |||
| 2025 | abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id; | ||
| 2006 | 2026 | ||
| 2007 | pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING; | 2027 | pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING; |
| 2008 | pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM; | 2028 | pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM; |
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 79bf96ca6489..95a3ec236b49 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c | |||
| @@ -1597,7 +1597,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, | |||
| 1597 | goto out_drop; | 1597 | goto out_drop; |
| 1598 | 1598 | ||
| 1599 | /* obtain protocol of skb */ | 1599 | /* obtain protocol of skb */ |
| 1600 | protocol = skb->protocol; | 1600 | protocol = vlan_get_protocol(skb); |
| 1601 | 1601 | ||
| 1602 | /* record the location of the first descriptor for this packet */ | 1602 | /* record the location of the first descriptor for this packet */ |
| 1603 | first = &tx_ring->tx_bi[tx_ring->next_to_use]; | 1603 | first = &tx_ring->tx_bi[tx_ring->next_to_use]; |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index c9f1d1b7ef37..ade067de1689 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/mbus.h> | 20 | #include <linux/mbus.h> |
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/if_vlan.h> | ||
| 23 | #include <net/ip.h> | 24 | #include <net/ip.h> |
| 24 | #include <net/ipv6.h> | 25 | #include <net/ipv6.h> |
| 25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| @@ -1371,15 +1372,16 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) | |||
| 1371 | { | 1372 | { |
| 1372 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1373 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1373 | int ip_hdr_len = 0; | 1374 | int ip_hdr_len = 0; |
| 1375 | __be16 l3_proto = vlan_get_protocol(skb); | ||
| 1374 | u8 l4_proto; | 1376 | u8 l4_proto; |
| 1375 | 1377 | ||
| 1376 | if (skb->protocol == htons(ETH_P_IP)) { | 1378 | if (l3_proto == htons(ETH_P_IP)) { |
| 1377 | struct iphdr *ip4h = ip_hdr(skb); | 1379 | struct iphdr *ip4h = ip_hdr(skb); |
| 1378 | 1380 | ||
| 1379 | /* Calculate IPv4 checksum and L4 checksum */ | 1381 | /* Calculate IPv4 checksum and L4 checksum */ |
| 1380 | ip_hdr_len = ip4h->ihl; | 1382 | ip_hdr_len = ip4h->ihl; |
| 1381 | l4_proto = ip4h->protocol; | 1383 | l4_proto = ip4h->protocol; |
| 1382 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 1384 | } else if (l3_proto == htons(ETH_P_IPV6)) { |
| 1383 | struct ipv6hdr *ip6h = ipv6_hdr(skb); | 1385 | struct ipv6hdr *ip6h = ipv6_hdr(skb); |
| 1384 | 1386 | ||
| 1385 | /* Read l4_protocol from one of IPv6 extra headers */ | 1387 | /* Read l4_protocol from one of IPv6 extra headers */ |
| @@ -1390,7 +1392,7 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) | |||
| 1390 | return MVNETA_TX_L4_CSUM_NOT; | 1392 | return MVNETA_TX_L4_CSUM_NOT; |
| 1391 | 1393 | ||
| 1392 | return mvneta_txq_desc_csum(skb_network_offset(skb), | 1394 | return mvneta_txq_desc_csum(skb_network_offset(skb), |
| 1393 | skb->protocol, ip_hdr_len, l4_proto); | 1395 | l3_proto, ip_hdr_len, l4_proto); |
| 1394 | } | 1396 | } |
| 1395 | 1397 | ||
| 1396 | return MVNETA_TX_L4_CSUM_NOT; | 1398 | return MVNETA_TX_L4_CSUM_NOT; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index bb536aa613f4..abddcf8c40aa 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
| @@ -474,39 +474,12 @@ static int mlx4_en_tunnel_steer_add(struct mlx4_en_priv *priv, unsigned char *ad | |||
| 474 | int qpn, u64 *reg_id) | 474 | int qpn, u64 *reg_id) |
| 475 | { | 475 | { |
| 476 | int err; | 476 | int err; |
| 477 | struct mlx4_spec_list spec_eth_outer = { {NULL} }; | ||
| 478 | struct mlx4_spec_list spec_vxlan = { {NULL} }; | ||
| 479 | struct mlx4_spec_list spec_eth_inner = { {NULL} }; | ||
| 480 | |||
| 481 | struct mlx4_net_trans_rule rule = { | ||
| 482 | .queue_mode = MLX4_NET_TRANS_Q_FIFO, | ||
| 483 | .exclusive = 0, | ||
| 484 | .allow_loopback = 1, | ||
| 485 | .promisc_mode = MLX4_FS_REGULAR, | ||
| 486 | .priority = MLX4_DOMAIN_NIC, | ||
| 487 | }; | ||
| 488 | |||
| 489 | __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
| 490 | 477 | ||
| 491 | if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) | 478 | if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
| 492 | return 0; /* do nothing */ | 479 | return 0; /* do nothing */ |
| 493 | 480 | ||
| 494 | rule.port = priv->port; | 481 | err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn, |
| 495 | rule.qpn = qpn; | 482 | MLX4_DOMAIN_NIC, reg_id); |
| 496 | INIT_LIST_HEAD(&rule.list); | ||
| 497 | |||
| 498 | spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH; | ||
| 499 | memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN); | ||
| 500 | memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN); | ||
| 501 | |||
| 502 | spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN; /* any vxlan header */ | ||
| 503 | spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH; /* any inner eth header */ | ||
| 504 | |||
| 505 | list_add_tail(&spec_eth_outer.list, &rule.list); | ||
| 506 | list_add_tail(&spec_vxlan.list, &rule.list); | ||
| 507 | list_add_tail(&spec_eth_inner.list, &rule.list); | ||
| 508 | |||
| 509 | err = mlx4_flow_attach(priv->mdev->dev, &rule, reg_id); | ||
| 510 | if (err) { | 483 | if (err) { |
| 511 | en_err(priv, "failed to add vxlan steering rule, err %d\n", err); | 484 | en_err(priv, "failed to add vxlan steering rule, err %d\n", err); |
| 512 | return err; | 485 | return err; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index d80e7a6fac74..ca0f98c95105 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
| @@ -1020,6 +1020,44 @@ int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id) | |||
| 1020 | } | 1020 | } |
| 1021 | EXPORT_SYMBOL_GPL(mlx4_flow_detach); | 1021 | EXPORT_SYMBOL_GPL(mlx4_flow_detach); |
| 1022 | 1022 | ||
| 1023 | int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr, | ||
| 1024 | int port, int qpn, u16 prio, u64 *reg_id) | ||
| 1025 | { | ||
| 1026 | int err; | ||
| 1027 | struct mlx4_spec_list spec_eth_outer = { {NULL} }; | ||
| 1028 | struct mlx4_spec_list spec_vxlan = { {NULL} }; | ||
| 1029 | struct mlx4_spec_list spec_eth_inner = { {NULL} }; | ||
| 1030 | |||
| 1031 | struct mlx4_net_trans_rule rule = { | ||
| 1032 | .queue_mode = MLX4_NET_TRANS_Q_FIFO, | ||
| 1033 | .exclusive = 0, | ||
| 1034 | .allow_loopback = 1, | ||
| 1035 | .promisc_mode = MLX4_FS_REGULAR, | ||
| 1036 | }; | ||
| 1037 | |||
| 1038 | __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
| 1039 | |||
| 1040 | rule.port = port; | ||
| 1041 | rule.qpn = qpn; | ||
| 1042 | rule.priority = prio; | ||
| 1043 | INIT_LIST_HEAD(&rule.list); | ||
| 1044 | |||
| 1045 | spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH; | ||
| 1046 | memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN); | ||
| 1047 | memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN); | ||
| 1048 | |||
| 1049 | spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN; /* any vxlan header */ | ||
| 1050 | spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH; /* any inner eth header */ | ||
| 1051 | |||
| 1052 | list_add_tail(&spec_eth_outer.list, &rule.list); | ||
| 1053 | list_add_tail(&spec_vxlan.list, &rule.list); | ||
| 1054 | list_add_tail(&spec_eth_inner.list, &rule.list); | ||
| 1055 | |||
| 1056 | err = mlx4_flow_attach(dev, &rule, reg_id); | ||
| 1057 | return err; | ||
| 1058 | } | ||
| 1059 | EXPORT_SYMBOL(mlx4_tunnel_steer_add); | ||
| 1060 | |||
| 1023 | int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn, | 1061 | int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn, |
| 1024 | u32 max_range_qpn) | 1062 | u32 max_range_qpn) |
| 1025 | { | 1063 | { |
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 5020fd47825d..2f12c88c66ab 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c | |||
| @@ -206,7 +206,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget) | |||
| 206 | int rx_head = priv->rx_head; | 206 | int rx_head = priv->rx_head; |
| 207 | int rx = 0; | 207 | int rx = 0; |
| 208 | 208 | ||
| 209 | while (1) { | 209 | while (rx < budget) { |
| 210 | desc = priv->rx_desc_base + (RX_REG_DESC_SIZE * rx_head); | 210 | desc = priv->rx_desc_base + (RX_REG_DESC_SIZE * rx_head); |
| 211 | desc0 = readl(desc + RX_REG_OFFSET_DESC0); | 211 | desc0 = readl(desc + RX_REG_OFFSET_DESC0); |
| 212 | 212 | ||
| @@ -218,7 +218,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget) | |||
| 218 | net_dbg_ratelimited("packet error\n"); | 218 | net_dbg_ratelimited("packet error\n"); |
| 219 | priv->stats.rx_dropped++; | 219 | priv->stats.rx_dropped++; |
| 220 | priv->stats.rx_errors++; | 220 | priv->stats.rx_errors++; |
| 221 | continue; | 221 | goto rx_next; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | len = desc0 & RX_DESC0_FRAME_LEN_MASK; | 224 | len = desc0 & RX_DESC0_FRAME_LEN_MASK; |
| @@ -226,13 +226,19 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget) | |||
| 226 | if (len > RX_BUF_SIZE) | 226 | if (len > RX_BUF_SIZE) |
| 227 | len = RX_BUF_SIZE; | 227 | len = RX_BUF_SIZE; |
| 228 | 228 | ||
| 229 | skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size); | 229 | dma_sync_single_for_cpu(&ndev->dev, |
| 230 | priv->rx_mapping[rx_head], | ||
| 231 | priv->rx_buf_size, DMA_FROM_DEVICE); | ||
| 232 | skb = netdev_alloc_skb_ip_align(ndev, len); | ||
| 233 | |||
| 230 | if (unlikely(!skb)) { | 234 | if (unlikely(!skb)) { |
| 231 | net_dbg_ratelimited("build_skb failed\n"); | 235 | net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n"); |
| 232 | priv->stats.rx_dropped++; | 236 | priv->stats.rx_dropped++; |
| 233 | priv->stats.rx_errors++; | 237 | priv->stats.rx_errors++; |
| 238 | goto rx_next; | ||
| 234 | } | 239 | } |
| 235 | 240 | ||
| 241 | memcpy(skb->data, priv->rx_buf[rx_head], len); | ||
| 236 | skb_put(skb, len); | 242 | skb_put(skb, len); |
| 237 | skb->protocol = eth_type_trans(skb, ndev); | 243 | skb->protocol = eth_type_trans(skb, ndev); |
| 238 | napi_gro_receive(&priv->napi, skb); | 244 | napi_gro_receive(&priv->napi, skb); |
| @@ -244,18 +250,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget) | |||
| 244 | if (desc0 & RX_DESC0_MULTICAST) | 250 | if (desc0 & RX_DESC0_MULTICAST) |
| 245 | priv->stats.multicast++; | 251 | priv->stats.multicast++; |
| 246 | 252 | ||
| 253 | rx_next: | ||
| 247 | writel(RX_DESC0_DMA_OWN, desc + RX_REG_OFFSET_DESC0); | 254 | writel(RX_DESC0_DMA_OWN, desc + RX_REG_OFFSET_DESC0); |
| 248 | 255 | ||
| 249 | rx_head = RX_NEXT(rx_head); | 256 | rx_head = RX_NEXT(rx_head); |
| 250 | priv->rx_head = rx_head; | 257 | priv->rx_head = rx_head; |
| 251 | |||
| 252 | if (rx >= budget) | ||
| 253 | break; | ||
| 254 | } | 258 | } |
| 255 | 259 | ||
| 256 | if (rx < budget) { | 260 | if (rx < budget) { |
| 257 | napi_gro_flush(napi, false); | 261 | napi_complete(napi); |
| 258 | __napi_complete(napi); | ||
| 259 | } | 262 | } |
| 260 | 263 | ||
| 261 | priv->reg_imr |= RPKT_FINISH_M; | 264 | priv->reg_imr |= RPKT_FINISH_M; |
| @@ -346,10 +349,12 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 346 | len = ETH_ZLEN; | 349 | len = ETH_ZLEN; |
| 347 | } | 350 | } |
| 348 | 351 | ||
| 349 | txdes1 = readl(desc + TX_REG_OFFSET_DESC1); | 352 | dma_sync_single_for_device(&ndev->dev, priv->tx_mapping[tx_head], |
| 350 | txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS; | 353 | priv->tx_buf_size, DMA_TO_DEVICE); |
| 351 | txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE); | 354 | |
| 352 | txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK); | 355 | txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK); |
| 356 | if (tx_head == TX_DESC_NUM_MASK) | ||
| 357 | txdes1 |= TX_DESC1_END; | ||
| 353 | writel(txdes1, desc + TX_REG_OFFSET_DESC1); | 358 | writel(txdes1, desc + TX_REG_OFFSET_DESC1); |
| 354 | writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0); | 359 | writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0); |
| 355 | 360 | ||
| @@ -465,8 +470,7 @@ static int moxart_mac_probe(struct platform_device *pdev) | |||
| 465 | spin_lock_init(&priv->txlock); | 470 | spin_lock_init(&priv->txlock); |
| 466 | 471 | ||
| 467 | priv->tx_buf_size = TX_BUF_SIZE; | 472 | priv->tx_buf_size = TX_BUF_SIZE; |
| 468 | priv->rx_buf_size = RX_BUF_SIZE + | 473 | priv->rx_buf_size = RX_BUF_SIZE; |
| 469 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
| 470 | 474 | ||
| 471 | priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE * | 475 | priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE * |
| 472 | TX_DESC_NUM, &priv->tx_base, | 476 | TX_DESC_NUM, &priv->tx_base, |
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 8706c0dbd0c3..a44a03c45014 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
| @@ -1220,6 +1220,9 @@ static int lpc_eth_open(struct net_device *ndev) | |||
| 1220 | 1220 | ||
| 1221 | __lpc_eth_clock_enable(pldat, true); | 1221 | __lpc_eth_clock_enable(pldat, true); |
| 1222 | 1222 | ||
| 1223 | /* Suspended PHY makes LPC ethernet core block, so resume now */ | ||
| 1224 | phy_resume(pldat->phy_dev); | ||
| 1225 | |||
| 1223 | /* Reset and initialize */ | 1226 | /* Reset and initialize */ |
| 1224 | __lpc_eth_reset(pldat); | 1227 | __lpc_eth_reset(pldat); |
| 1225 | __lpc_eth_init(pldat); | 1228 | __lpc_eth_init(pldat); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 16039d1497b8..b84f5ea3d659 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
| @@ -268,7 +268,7 @@ struct qlcnic_fdt { | |||
| 268 | u16 cksum; | 268 | u16 cksum; |
| 269 | u16 unused; | 269 | u16 unused; |
| 270 | u8 model[16]; | 270 | u8 model[16]; |
| 271 | u16 mfg_id; | 271 | u8 mfg_id; |
| 272 | u16 id; | 272 | u16 id; |
| 273 | u8 flag; | 273 | u8 flag; |
| 274 | u8 erase_cmd; | 274 | u8 erase_cmd; |
| @@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | |||
| 2362 | return QLC_DEFAULT_VNIC_COUNT; | 2362 | return QLC_DEFAULT_VNIC_COUNT; |
| 2363 | } | 2363 | } |
| 2364 | 2364 | ||
| 2365 | static inline void qlcnic_swap32_buffer(u32 *buffer, int count) | ||
| 2366 | { | ||
| 2367 | #if defined(__BIG_ENDIAN) | ||
| 2368 | u32 *tmp = buffer; | ||
| 2369 | int i; | ||
| 2370 | |||
| 2371 | for (i = 0; i < count; i++) { | ||
| 2372 | *tmp = swab32(*tmp); | ||
| 2373 | tmp++; | ||
| 2374 | } | ||
| 2375 | #endif | ||
| 2376 | } | ||
| 2377 | |||
| 2365 | #ifdef CONFIG_QLCNIC_HWMON | 2378 | #ifdef CONFIG_QLCNIC_HWMON |
| 2366 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); | 2379 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); |
| 2367 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); | 2380 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index a4a4ec0b68f8..476e4998ef99 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
| @@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
| 2603 | } | 2603 | } |
| 2604 | 2604 | ||
| 2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, | 2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, |
| 2606 | (addr)); | 2606 | (addr & 0xFFFF0000)); |
| 2607 | 2607 | ||
| 2608 | range = flash_offset + (count * sizeof(u32)); | 2608 | range = flash_offset + (count * sizeof(u32)); |
| 2609 | /* Check if data is spread across multiple sectors */ | 2609 | /* Check if data is spread across multiple sectors */ |
| @@ -2753,7 +2753,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter) | |||
| 2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, | 2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, |
| 2754 | (u8 *)&adapter->ahw->fdt, | 2754 | (u8 *)&adapter->ahw->fdt, |
| 2755 | count); | 2755 | count); |
| 2756 | 2756 | qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count); | |
| 2757 | qlcnic_83xx_unlock_flash(adapter); | 2757 | qlcnic_83xx_unlock_flash(adapter); |
| 2758 | return ret; | 2758 | return ret; |
| 2759 | } | 2759 | } |
| @@ -2788,7 +2788,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter, | |||
| 2788 | 2788 | ||
| 2789 | addr1 = (sector_start_addr & 0xFF) << 16; | 2789 | addr1 = (sector_start_addr & 0xFF) << 16; |
| 2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; | 2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; |
| 2791 | reversed_addr = addr1 | addr2; | 2791 | reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00); |
| 2792 | 2792 | ||
| 2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, | 2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, |
| 2794 | reversed_addr); | 2794 | reversed_addr); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index f33559b72528..86783e1afcf7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
| @@ -1378,31 +1378,45 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
| 1378 | { | 1378 | { |
| 1379 | struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; | 1379 | struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; |
| 1380 | const struct firmware *fw = fw_info->fw; | 1380 | const struct firmware *fw = fw_info->fw; |
| 1381 | u32 dest, *p_cache; | 1381 | u32 dest, *p_cache, *temp; |
| 1382 | int i, ret = -EIO; | 1382 | int i, ret = -EIO; |
| 1383 | __le32 *temp_le; | ||
| 1383 | u8 data[16]; | 1384 | u8 data[16]; |
| 1384 | size_t size; | 1385 | size_t size; |
| 1385 | u64 addr; | 1386 | u64 addr; |
| 1386 | 1387 | ||
| 1388 | temp = kzalloc(fw->size, GFP_KERNEL); | ||
| 1389 | if (!temp) { | ||
| 1390 | release_firmware(fw); | ||
| 1391 | fw_info->fw = NULL; | ||
| 1392 | return -ENOMEM; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | temp_le = (__le32 *)fw->data; | ||
| 1396 | |||
| 1397 | /* FW image in file is in little endian, swap the data to nullify | ||
| 1398 | * the effect of writel() operation on big endian platform. | ||
| 1399 | */ | ||
| 1400 | for (i = 0; i < fw->size / sizeof(u32); i++) | ||
| 1401 | temp[i] = __le32_to_cpu(temp_le[i]); | ||
| 1402 | |||
| 1387 | dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR); | 1403 | dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR); |
| 1388 | size = (fw->size & ~0xF); | 1404 | size = (fw->size & ~0xF); |
| 1389 | p_cache = (u32 *)fw->data; | 1405 | p_cache = temp; |
| 1390 | addr = (u64)dest; | 1406 | addr = (u64)dest; |
| 1391 | 1407 | ||
| 1392 | ret = qlcnic_ms_mem_write128(adapter, addr, | 1408 | ret = qlcnic_ms_mem_write128(adapter, addr, |
| 1393 | p_cache, size / 16); | 1409 | p_cache, size / 16); |
| 1394 | if (ret) { | 1410 | if (ret) { |
| 1395 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); | 1411 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); |
| 1396 | release_firmware(fw); | 1412 | goto exit; |
| 1397 | fw_info->fw = NULL; | ||
| 1398 | return -EIO; | ||
| 1399 | } | 1413 | } |
| 1400 | 1414 | ||
| 1401 | /* alignment check */ | 1415 | /* alignment check */ |
| 1402 | if (fw->size & 0xF) { | 1416 | if (fw->size & 0xF) { |
| 1403 | addr = dest + size; | 1417 | addr = dest + size; |
| 1404 | for (i = 0; i < (fw->size & 0xF); i++) | 1418 | for (i = 0; i < (fw->size & 0xF); i++) |
| 1405 | data[i] = fw->data[size + i]; | 1419 | data[i] = temp[size + i]; |
| 1406 | for (; i < 16; i++) | 1420 | for (; i < 16; i++) |
| 1407 | data[i] = 0; | 1421 | data[i] = 0; |
| 1408 | ret = qlcnic_ms_mem_write128(adapter, addr, | 1422 | ret = qlcnic_ms_mem_write128(adapter, addr, |
| @@ -1410,15 +1424,16 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
| 1410 | if (ret) { | 1424 | if (ret) { |
| 1411 | dev_err(&adapter->pdev->dev, | 1425 | dev_err(&adapter->pdev->dev, |
| 1412 | "MS memory write failed\n"); | 1426 | "MS memory write failed\n"); |
| 1413 | release_firmware(fw); | 1427 | goto exit; |
| 1414 | fw_info->fw = NULL; | ||
| 1415 | return -EIO; | ||
| 1416 | } | 1428 | } |
| 1417 | } | 1429 | } |
| 1430 | |||
| 1431 | exit: | ||
| 1418 | release_firmware(fw); | 1432 | release_firmware(fw); |
| 1419 | fw_info->fw = NULL; | 1433 | fw_info->fw = NULL; |
| 1434 | kfree(temp); | ||
| 1420 | 1435 | ||
| 1421 | return 0; | 1436 | return ret; |
| 1422 | } | 1437 | } |
| 1423 | 1438 | ||
| 1424 | static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter) | 1439 | static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index e46fc39d425d..c9f57fb84b9e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | |||
| @@ -47,15 +47,26 @@ struct qlcnic_common_entry_hdr { | |||
| 47 | u32 type; | 47 | u32 type; |
| 48 | u32 offset; | 48 | u32 offset; |
| 49 | u32 cap_size; | 49 | u32 cap_size; |
| 50 | #if defined(__LITTLE_ENDIAN) | ||
| 50 | u8 mask; | 51 | u8 mask; |
| 51 | u8 rsvd[2]; | 52 | u8 rsvd[2]; |
| 52 | u8 flags; | 53 | u8 flags; |
| 54 | #else | ||
| 55 | u8 flags; | ||
| 56 | u8 rsvd[2]; | ||
| 57 | u8 mask; | ||
| 58 | #endif | ||
| 53 | } __packed; | 59 | } __packed; |
| 54 | 60 | ||
| 55 | struct __crb { | 61 | struct __crb { |
| 56 | u32 addr; | 62 | u32 addr; |
| 63 | #if defined(__LITTLE_ENDIAN) | ||
| 57 | u8 stride; | 64 | u8 stride; |
| 58 | u8 rsvd1[3]; | 65 | u8 rsvd1[3]; |
| 66 | #else | ||
| 67 | u8 rsvd1[3]; | ||
| 68 | u8 stride; | ||
| 69 | #endif | ||
| 59 | u32 data_size; | 70 | u32 data_size; |
| 60 | u32 no_ops; | 71 | u32 no_ops; |
| 61 | u32 rsvd2[4]; | 72 | u32 rsvd2[4]; |
| @@ -63,15 +74,28 @@ struct __crb { | |||
| 63 | 74 | ||
| 64 | struct __ctrl { | 75 | struct __ctrl { |
| 65 | u32 addr; | 76 | u32 addr; |
| 77 | #if defined(__LITTLE_ENDIAN) | ||
| 66 | u8 stride; | 78 | u8 stride; |
| 67 | u8 index_a; | 79 | u8 index_a; |
| 68 | u16 timeout; | 80 | u16 timeout; |
| 81 | #else | ||
| 82 | u16 timeout; | ||
| 83 | u8 index_a; | ||
| 84 | u8 stride; | ||
| 85 | #endif | ||
| 69 | u32 data_size; | 86 | u32 data_size; |
| 70 | u32 no_ops; | 87 | u32 no_ops; |
| 88 | #if defined(__LITTLE_ENDIAN) | ||
| 71 | u8 opcode; | 89 | u8 opcode; |
| 72 | u8 index_v; | 90 | u8 index_v; |
| 73 | u8 shl_val; | 91 | u8 shl_val; |
| 74 | u8 shr_val; | 92 | u8 shr_val; |
| 93 | #else | ||
| 94 | u8 shr_val; | ||
| 95 | u8 shl_val; | ||
| 96 | u8 index_v; | ||
| 97 | u8 opcode; | ||
| 98 | #endif | ||
| 75 | u32 val1; | 99 | u32 val1; |
| 76 | u32 val2; | 100 | u32 val2; |
| 77 | u32 val3; | 101 | u32 val3; |
| @@ -79,16 +103,27 @@ struct __ctrl { | |||
| 79 | 103 | ||
| 80 | struct __cache { | 104 | struct __cache { |
| 81 | u32 addr; | 105 | u32 addr; |
| 106 | #if defined(__LITTLE_ENDIAN) | ||
| 82 | u16 stride; | 107 | u16 stride; |
| 83 | u16 init_tag_val; | 108 | u16 init_tag_val; |
| 109 | #else | ||
| 110 | u16 init_tag_val; | ||
| 111 | u16 stride; | ||
| 112 | #endif | ||
| 84 | u32 size; | 113 | u32 size; |
| 85 | u32 no_ops; | 114 | u32 no_ops; |
| 86 | u32 ctrl_addr; | 115 | u32 ctrl_addr; |
| 87 | u32 ctrl_val; | 116 | u32 ctrl_val; |
| 88 | u32 read_addr; | 117 | u32 read_addr; |
| 118 | #if defined(__LITTLE_ENDIAN) | ||
| 89 | u8 read_addr_stride; | 119 | u8 read_addr_stride; |
| 90 | u8 read_addr_num; | 120 | u8 read_addr_num; |
| 91 | u8 rsvd1[2]; | 121 | u8 rsvd1[2]; |
| 122 | #else | ||
| 123 | u8 rsvd1[2]; | ||
| 124 | u8 read_addr_num; | ||
| 125 | u8 read_addr_stride; | ||
| 126 | #endif | ||
| 92 | } __packed; | 127 | } __packed; |
| 93 | 128 | ||
| 94 | struct __ocm { | 129 | struct __ocm { |
| @@ -122,23 +157,39 @@ struct __mux { | |||
| 122 | 157 | ||
| 123 | struct __queue { | 158 | struct __queue { |
| 124 | u32 sel_addr; | 159 | u32 sel_addr; |
| 160 | #if defined(__LITTLE_ENDIAN) | ||
| 125 | u16 stride; | 161 | u16 stride; |
| 126 | u8 rsvd[2]; | 162 | u8 rsvd[2]; |
| 163 | #else | ||
| 164 | u8 rsvd[2]; | ||
| 165 | u16 stride; | ||
| 166 | #endif | ||
| 127 | u32 size; | 167 | u32 size; |
| 128 | u32 no_ops; | 168 | u32 no_ops; |
| 129 | u8 rsvd2[8]; | 169 | u8 rsvd2[8]; |
| 130 | u32 read_addr; | 170 | u32 read_addr; |
| 171 | #if defined(__LITTLE_ENDIAN) | ||
| 131 | u8 read_addr_stride; | 172 | u8 read_addr_stride; |
| 132 | u8 read_addr_cnt; | 173 | u8 read_addr_cnt; |
| 133 | u8 rsvd3[2]; | 174 | u8 rsvd3[2]; |
| 175 | #else | ||
| 176 | u8 rsvd3[2]; | ||
| 177 | u8 read_addr_cnt; | ||
| 178 | u8 read_addr_stride; | ||
| 179 | #endif | ||
| 134 | } __packed; | 180 | } __packed; |
| 135 | 181 | ||
| 136 | struct __pollrd { | 182 | struct __pollrd { |
| 137 | u32 sel_addr; | 183 | u32 sel_addr; |
| 138 | u32 read_addr; | 184 | u32 read_addr; |
| 139 | u32 sel_val; | 185 | u32 sel_val; |
| 186 | #if defined(__LITTLE_ENDIAN) | ||
| 140 | u16 sel_val_stride; | 187 | u16 sel_val_stride; |
| 141 | u16 no_ops; | 188 | u16 no_ops; |
| 189 | #else | ||
| 190 | u16 no_ops; | ||
| 191 | u16 sel_val_stride; | ||
| 192 | #endif | ||
| 142 | u32 poll_wait; | 193 | u32 poll_wait; |
| 143 | u32 poll_mask; | 194 | u32 poll_mask; |
| 144 | u32 data_size; | 195 | u32 data_size; |
| @@ -153,9 +204,15 @@ struct __mux2 { | |||
| 153 | u32 no_ops; | 204 | u32 no_ops; |
| 154 | u32 sel_val_mask; | 205 | u32 sel_val_mask; |
| 155 | u32 read_addr; | 206 | u32 read_addr; |
| 207 | #if defined(__LITTLE_ENDIAN) | ||
| 156 | u8 sel_val_stride; | 208 | u8 sel_val_stride; |
| 157 | u8 data_size; | 209 | u8 data_size; |
| 158 | u8 rsvd[2]; | 210 | u8 rsvd[2]; |
| 211 | #else | ||
| 212 | u8 rsvd[2]; | ||
| 213 | u8 data_size; | ||
| 214 | u8 sel_val_stride; | ||
| 215 | #endif | ||
| 159 | } __packed; | 216 | } __packed; |
| 160 | 217 | ||
| 161 | struct __pollrdmwr { | 218 | struct __pollrdmwr { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index f5786d5792df..59a721fba018 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
| @@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, | |||
| 280 | if (ret != 0) | 280 | if (ret != 0) |
| 281 | return ret; | 281 | return ret; |
| 282 | qlcnic_read_crb(adapter, buf, offset, size); | 282 | qlcnic_read_crb(adapter, buf, offset, size); |
| 283 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 283 | 284 | ||
| 284 | return size; | 285 | return size; |
| 285 | } | 286 | } |
| @@ -296,6 +297,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, | |||
| 296 | if (ret != 0) | 297 | if (ret != 0) |
| 297 | return ret; | 298 | return ret; |
| 298 | 299 | ||
| 300 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 299 | qlcnic_write_crb(adapter, buf, offset, size); | 301 | qlcnic_write_crb(adapter, buf, offset, size); |
| 300 | return size; | 302 | return size; |
| 301 | } | 303 | } |
| @@ -329,6 +331,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, | |||
| 329 | return -EIO; | 331 | return -EIO; |
| 330 | 332 | ||
| 331 | memcpy(buf, &data, size); | 333 | memcpy(buf, &data, size); |
| 334 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 332 | 335 | ||
| 333 | return size; | 336 | return size; |
| 334 | } | 337 | } |
| @@ -346,6 +349,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
| 346 | if (ret != 0) | 349 | if (ret != 0) |
| 347 | return ret; | 350 | return ret; |
| 348 | 351 | ||
| 352 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 349 | memcpy(&data, buf, size); | 353 | memcpy(&data, buf, size); |
| 350 | 354 | ||
| 351 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) | 355 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) |
| @@ -412,6 +416,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
| 412 | if (rem) | 416 | if (rem) |
| 413 | return QL_STATUS_INVALID_PARAM; | 417 | return QL_STATUS_INVALID_PARAM; |
| 414 | 418 | ||
| 419 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 415 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 420 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
| 416 | ret = validate_pm_config(adapter, pm_cfg, count); | 421 | ret = validate_pm_config(adapter, pm_cfg, count); |
| 417 | 422 | ||
| @@ -474,6 +479,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
| 474 | pm_cfg[pci_func].dest_npar = 0; | 479 | pm_cfg[pci_func].dest_npar = 0; |
| 475 | pm_cfg[pci_func].pci_func = i; | 480 | pm_cfg[pci_func].pci_func = i; |
| 476 | } | 481 | } |
| 482 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 477 | return size; | 483 | return size; |
| 478 | } | 484 | } |
| 479 | 485 | ||
| @@ -555,6 +561,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
| 555 | if (rem) | 561 | if (rem) |
| 556 | return QL_STATUS_INVALID_PARAM; | 562 | return QL_STATUS_INVALID_PARAM; |
| 557 | 563 | ||
| 564 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 558 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; | 565 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; |
| 559 | ret = validate_esw_config(adapter, esw_cfg, count); | 566 | ret = validate_esw_config(adapter, esw_cfg, count); |
| 560 | if (ret) | 567 | if (ret) |
| @@ -649,6 +656,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
| 649 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | 656 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) |
| 650 | return QL_STATUS_INVALID_PARAM; | 657 | return QL_STATUS_INVALID_PARAM; |
| 651 | } | 658 | } |
| 659 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 652 | return size; | 660 | return size; |
| 653 | } | 661 | } |
| 654 | 662 | ||
| @@ -688,6 +696,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
| 688 | if (rem) | 696 | if (rem) |
| 689 | return QL_STATUS_INVALID_PARAM; | 697 | return QL_STATUS_INVALID_PARAM; |
| 690 | 698 | ||
| 699 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 691 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; | 700 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; |
| 692 | ret = validate_npar_config(adapter, np_cfg, count); | 701 | ret = validate_npar_config(adapter, np_cfg, count); |
| 693 | if (ret) | 702 | if (ret) |
| @@ -759,6 +768,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
| 759 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; | 768 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; |
| 760 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; | 769 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; |
| 761 | } | 770 | } |
| 771 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 762 | return size; | 772 | return size; |
| 763 | } | 773 | } |
| 764 | 774 | ||
| @@ -916,6 +926,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
| 916 | 926 | ||
| 917 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; | 927 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; |
| 918 | count = size / sizeof(struct qlcnic_pci_func_cfg); | 928 | count = size / sizeof(struct qlcnic_pci_func_cfg); |
| 929 | qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32)); | ||
| 919 | for (i = 0; i < count; i++) { | 930 | for (i = 0; i < count; i++) { |
| 920 | pci_cfg[i].pci_func = pci_info[i].id; | 931 | pci_cfg[i].pci_func = pci_info[i].id; |
| 921 | pci_cfg[i].func_type = pci_info[i].type; | 932 | pci_cfg[i].func_type = pci_info[i].type; |
| @@ -969,6 +980,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp, | |||
| 969 | } | 980 | } |
| 970 | 981 | ||
| 971 | qlcnic_83xx_unlock_flash(adapter); | 982 | qlcnic_83xx_unlock_flash(adapter); |
| 983 | qlcnic_swap32_buffer((u32 *)p_read_buf, count); | ||
| 972 | memcpy(buf, p_read_buf, size); | 984 | memcpy(buf, p_read_buf, size); |
| 973 | kfree(p_read_buf); | 985 | kfree(p_read_buf); |
| 974 | 986 | ||
| @@ -986,9 +998,10 @@ static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter, | |||
| 986 | if (!p_cache) | 998 | if (!p_cache) |
| 987 | return -ENOMEM; | 999 | return -ENOMEM; |
| 988 | 1000 | ||
| 1001 | count = size / sizeof(u32); | ||
| 1002 | qlcnic_swap32_buffer((u32 *)buf, count); | ||
| 989 | memcpy(p_cache, buf, size); | 1003 | memcpy(p_cache, buf, size); |
| 990 | p_src = p_cache; | 1004 | p_src = p_cache; |
| 991 | count = size / sizeof(u32); | ||
| 992 | 1005 | ||
| 993 | if (qlcnic_83xx_lock_flash(adapter) != 0) { | 1006 | if (qlcnic_83xx_lock_flash(adapter) != 0) { |
| 994 | kfree(p_cache); | 1007 | kfree(p_cache); |
| @@ -1053,6 +1066,7 @@ static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter, | |||
| 1053 | if (!p_cache) | 1066 | if (!p_cache) |
| 1054 | return -ENOMEM; | 1067 | return -ENOMEM; |
| 1055 | 1068 | ||
| 1069 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
| 1056 | memcpy(p_cache, buf, size); | 1070 | memcpy(p_cache, buf, size); |
| 1057 | p_src = p_cache; | 1071 | p_src = p_cache; |
| 1058 | count = size / sizeof(u32); | 1072 | count = size / sizeof(u32); |
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 188626e2a861..3e96f269150d 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c | |||
| @@ -2556,6 +2556,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr) | |||
| 2556 | 2556 | ||
| 2557 | if (skb_is_gso(skb)) { | 2557 | if (skb_is_gso(skb)) { |
| 2558 | int err; | 2558 | int err; |
| 2559 | __be16 l3_proto = vlan_get_protocol(skb); | ||
| 2559 | 2560 | ||
| 2560 | err = skb_cow_head(skb, 0); | 2561 | err = skb_cow_head(skb, 0); |
| 2561 | if (err < 0) | 2562 | if (err < 0) |
| @@ -2572,7 +2573,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr) | |||
| 2572 | << OB_MAC_TRANSPORT_HDR_SHIFT); | 2573 | << OB_MAC_TRANSPORT_HDR_SHIFT); |
| 2573 | mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); | 2574 | mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); |
| 2574 | mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO; | 2575 | mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO; |
| 2575 | if (likely(skb->protocol == htons(ETH_P_IP))) { | 2576 | if (likely(l3_proto == htons(ETH_P_IP))) { |
| 2576 | struct iphdr *iph = ip_hdr(skb); | 2577 | struct iphdr *iph = ip_hdr(skb); |
| 2577 | iph->check = 0; | 2578 | iph->check = 0; |
| 2578 | mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4; | 2579 | mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4; |
| @@ -2580,7 +2581,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr) | |||
| 2580 | iph->daddr, 0, | 2581 | iph->daddr, 0, |
| 2581 | IPPROTO_TCP, | 2582 | IPPROTO_TCP, |
| 2582 | 0); | 2583 | 0); |
| 2583 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 2584 | } else if (l3_proto == htons(ETH_P_IPV6)) { |
| 2584 | mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6; | 2585 | mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6; |
| 2585 | tcp_hdr(skb)->check = | 2586 | tcp_hdr(skb)->check = |
| 2586 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 2587 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 9e757c792d84..196e98a2d93b 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | config SH_ETH | 5 | config SH_ETH |
| 6 | tristate "Renesas SuperH Ethernet support" | 6 | tristate "Renesas SuperH Ethernet support" |
| 7 | depends on HAS_DMA | 7 | depends on HAS_DMA |
| 8 | depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST | ||
| 8 | select CRC32 | 9 | select CRC32 |
| 9 | select MII | 10 | select MII |
| 10 | select MDIO_BITBANG | 11 | select MDIO_BITBANG |
diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index c553f6b5a913..cf28daba4346 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | #include "stmmac.h" | 29 | #include "stmmac.h" |
| 30 | 30 | ||
| 31 | static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | 31 | static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) |
| 32 | { | 32 | { |
| 33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; | 33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; |
| 34 | unsigned int txsize = priv->dma_tx_size; | 34 | unsigned int txsize = priv->dma_tx_size; |
| @@ -47,7 +47,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 47 | 47 | ||
| 48 | desc->des2 = dma_map_single(priv->device, skb->data, | 48 | desc->des2 = dma_map_single(priv->device, skb->data, |
| 49 | bmax, DMA_TO_DEVICE); | 49 | bmax, DMA_TO_DEVICE); |
| 50 | priv->tx_skbuff_dma[entry] = desc->des2; | 50 | if (dma_mapping_error(priv->device, desc->des2)) |
| 51 | return -1; | ||
| 52 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 51 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE); | 53 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE); |
| 52 | 54 | ||
| 53 | while (len != 0) { | 55 | while (len != 0) { |
| @@ -59,7 +61,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 59 | desc->des2 = dma_map_single(priv->device, | 61 | desc->des2 = dma_map_single(priv->device, |
| 60 | (skb->data + bmax * i), | 62 | (skb->data + bmax * i), |
| 61 | bmax, DMA_TO_DEVICE); | 63 | bmax, DMA_TO_DEVICE); |
| 62 | priv->tx_skbuff_dma[entry] = desc->des2; | 64 | if (dma_mapping_error(priv->device, desc->des2)) |
| 65 | return -1; | ||
| 66 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 63 | priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum, | 67 | priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum, |
| 64 | STMMAC_CHAIN_MODE); | 68 | STMMAC_CHAIN_MODE); |
| 65 | priv->hw->desc->set_tx_owner(desc); | 69 | priv->hw->desc->set_tx_owner(desc); |
| @@ -69,7 +73,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 69 | desc->des2 = dma_map_single(priv->device, | 73 | desc->des2 = dma_map_single(priv->device, |
| 70 | (skb->data + bmax * i), len, | 74 | (skb->data + bmax * i), len, |
| 71 | DMA_TO_DEVICE); | 75 | DMA_TO_DEVICE); |
| 72 | priv->tx_skbuff_dma[entry] = desc->des2; | 76 | if (dma_mapping_error(priv->device, desc->des2)) |
| 77 | return -1; | ||
| 78 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 73 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, | 79 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, |
| 74 | STMMAC_CHAIN_MODE); | 80 | STMMAC_CHAIN_MODE); |
| 75 | priv->hw->desc->set_tx_owner(desc); | 81 | priv->hw->desc->set_tx_owner(desc); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index de507c32036c..593e6c4144a7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
| @@ -220,10 +220,10 @@ enum dma_irq_status { | |||
| 220 | handle_tx = 0x8, | 220 | handle_tx = 0x8, |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| 223 | #define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 1) | 223 | #define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 0) |
| 224 | #define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 2) | 224 | #define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 1) |
| 225 | #define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 3) | 225 | #define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 2) |
| 226 | #define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 4) | 226 | #define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 3) |
| 227 | 227 | ||
| 228 | #define CORE_PCS_ANE_COMPLETE (1 << 5) | 228 | #define CORE_PCS_ANE_COMPLETE (1 << 5) |
| 229 | #define CORE_PCS_LINK_STATUS (1 << 6) | 229 | #define CORE_PCS_LINK_STATUS (1 << 6) |
| @@ -287,7 +287,7 @@ struct dma_features { | |||
| 287 | 287 | ||
| 288 | /* Default LPI timers */ | 288 | /* Default LPI timers */ |
| 289 | #define STMMAC_DEFAULT_LIT_LS 0x3E8 | 289 | #define STMMAC_DEFAULT_LIT_LS 0x3E8 |
| 290 | #define STMMAC_DEFAULT_TWT_LS 0x0 | 290 | #define STMMAC_DEFAULT_TWT_LS 0x1E |
| 291 | 291 | ||
| 292 | #define STMMAC_CHAIN_MODE 0x1 | 292 | #define STMMAC_CHAIN_MODE 0x1 |
| 293 | #define STMMAC_RING_MODE 0x2 | 293 | #define STMMAC_RING_MODE 0x2 |
| @@ -425,7 +425,7 @@ struct stmmac_mode_ops { | |||
| 425 | void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, | 425 | void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, |
| 426 | unsigned int extend_desc); | 426 | unsigned int extend_desc); |
| 427 | unsigned int (*is_jumbo_frm) (int len, int ehn_desc); | 427 | unsigned int (*is_jumbo_frm) (int len, int ehn_desc); |
| 428 | unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); | 428 | int (*jumbo_frm)(void *priv, struct sk_buff *skb, int csum); |
| 429 | int (*set_16kib_bfsize)(int mtu); | 429 | int (*set_16kib_bfsize)(int mtu); |
| 430 | void (*init_desc3)(struct dma_desc *p); | 430 | void (*init_desc3)(struct dma_desc *p); |
| 431 | void (*refill_desc3) (void *priv, struct dma_desc *p); | 431 | void (*refill_desc3) (void *priv, struct dma_desc *p); |
| @@ -445,6 +445,7 @@ struct mac_device_info { | |||
| 445 | int multicast_filter_bins; | 445 | int multicast_filter_bins; |
| 446 | int unicast_filter_entries; | 446 | int unicast_filter_entries; |
| 447 | int mcast_bits_log2; | 447 | int mcast_bits_log2; |
| 448 | unsigned int rx_csum; | ||
| 448 | }; | 449 | }; |
| 449 | 450 | ||
| 450 | struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, | 451 | struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 71b5419256c1..64d8f56a9c17 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | |||
| @@ -153,7 +153,7 @@ enum inter_frame_gap { | |||
| 153 | #define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ | 153 | #define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ |
| 154 | 154 | ||
| 155 | #define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ | 155 | #define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ |
| 156 | GMAC_CONTROL_BE) | 156 | GMAC_CONTROL_BE | GMAC_CONTROL_DCRS) |
| 157 | 157 | ||
| 158 | /* GMAC Frame Filter defines */ | 158 | /* GMAC Frame Filter defines */ |
| 159 | #define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ | 159 | #define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index d8ef18786a1c..5efe60ea6526 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | |||
| @@ -58,7 +58,11 @@ static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw) | |||
| 58 | void __iomem *ioaddr = hw->pcsr; | 58 | void __iomem *ioaddr = hw->pcsr; |
| 59 | u32 value = readl(ioaddr + GMAC_CONTROL); | 59 | u32 value = readl(ioaddr + GMAC_CONTROL); |
| 60 | 60 | ||
| 61 | value |= GMAC_CONTROL_IPC; | 61 | if (hw->rx_csum) |
| 62 | value |= GMAC_CONTROL_IPC; | ||
| 63 | else | ||
| 64 | value &= ~GMAC_CONTROL_IPC; | ||
| 65 | |||
| 62 | writel(value, ioaddr + GMAC_CONTROL); | 66 | writel(value, ioaddr + GMAC_CONTROL); |
| 63 | 67 | ||
| 64 | value = readl(ioaddr + GMAC_CONTROL); | 68 | value = readl(ioaddr + GMAC_CONTROL); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index 8607488cbcfc..192c2491330b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h | |||
| @@ -68,7 +68,7 @@ struct stmmac_counters { | |||
| 68 | unsigned int mmc_rx_octetcount_g; | 68 | unsigned int mmc_rx_octetcount_g; |
| 69 | unsigned int mmc_rx_broadcastframe_g; | 69 | unsigned int mmc_rx_broadcastframe_g; |
| 70 | unsigned int mmc_rx_multicastframe_g; | 70 | unsigned int mmc_rx_multicastframe_g; |
| 71 | unsigned int mmc_rx_crc_errror; | 71 | unsigned int mmc_rx_crc_error; |
| 72 | unsigned int mmc_rx_align_error; | 72 | unsigned int mmc_rx_align_error; |
| 73 | unsigned int mmc_rx_run_error; | 73 | unsigned int mmc_rx_run_error; |
| 74 | unsigned int mmc_rx_jabber_error; | 74 | unsigned int mmc_rx_jabber_error; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 50617c5a0bdb..08c483bd2ec7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c | |||
| @@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc) | |||
| 196 | mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G); | 196 | mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G); |
| 197 | mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G); | 197 | mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G); |
| 198 | mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G); | 198 | mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G); |
| 199 | mmc->mmc_rx_crc_errror += readl(ioaddr + MMC_RX_CRC_ERRROR); | 199 | mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR); |
| 200 | mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR); | 200 | mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR); |
| 201 | mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR); | 201 | mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR); |
| 202 | mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR); | 202 | mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index 650a4be6bce5..5dd50c6cda5b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | #include "stmmac.h" | 29 | #include "stmmac.h" |
| 30 | 30 | ||
| 31 | static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | 31 | static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) |
| 32 | { | 32 | { |
| 33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; | 33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; |
| 34 | unsigned int txsize = priv->dma_tx_size; | 34 | unsigned int txsize = priv->dma_tx_size; |
| @@ -53,7 +53,10 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 53 | 53 | ||
| 54 | desc->des2 = dma_map_single(priv->device, skb->data, | 54 | desc->des2 = dma_map_single(priv->device, skb->data, |
| 55 | bmax, DMA_TO_DEVICE); | 55 | bmax, DMA_TO_DEVICE); |
| 56 | priv->tx_skbuff_dma[entry] = desc->des2; | 56 | if (dma_mapping_error(priv->device, desc->des2)) |
| 57 | return -1; | ||
| 58 | |||
| 59 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 57 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; | 60 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; |
| 58 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, | 61 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, |
| 59 | STMMAC_RING_MODE); | 62 | STMMAC_RING_MODE); |
| @@ -68,7 +71,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 68 | 71 | ||
| 69 | desc->des2 = dma_map_single(priv->device, skb->data + bmax, | 72 | desc->des2 = dma_map_single(priv->device, skb->data + bmax, |
| 70 | len, DMA_TO_DEVICE); | 73 | len, DMA_TO_DEVICE); |
| 71 | priv->tx_skbuff_dma[entry] = desc->des2; | 74 | if (dma_mapping_error(priv->device, desc->des2)) |
| 75 | return -1; | ||
| 76 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 72 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; | 77 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; |
| 73 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, | 78 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, |
| 74 | STMMAC_RING_MODE); | 79 | STMMAC_RING_MODE); |
| @@ -77,7 +82,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
| 77 | } else { | 82 | } else { |
| 78 | desc->des2 = dma_map_single(priv->device, skb->data, | 83 | desc->des2 = dma_map_single(priv->device, skb->data, |
| 79 | nopaged_len, DMA_TO_DEVICE); | 84 | nopaged_len, DMA_TO_DEVICE); |
| 80 | priv->tx_skbuff_dma[entry] = desc->des2; | 85 | if (dma_mapping_error(priv->device, desc->des2)) |
| 86 | return -1; | ||
| 87 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 81 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; | 88 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; |
| 82 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum, | 89 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum, |
| 83 | STMMAC_RING_MODE); | 90 | STMMAC_RING_MODE); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index ca01035634a7..58097c0e2ad5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
| @@ -34,6 +34,11 @@ | |||
| 34 | #include <linux/ptp_clock_kernel.h> | 34 | #include <linux/ptp_clock_kernel.h> |
| 35 | #include <linux/reset.h> | 35 | #include <linux/reset.h> |
| 36 | 36 | ||
| 37 | struct stmmac_tx_info { | ||
| 38 | dma_addr_t buf; | ||
| 39 | bool map_as_page; | ||
| 40 | }; | ||
| 41 | |||
| 37 | struct stmmac_priv { | 42 | struct stmmac_priv { |
| 38 | /* Frequently used values are kept adjacent for cache effect */ | 43 | /* Frequently used values are kept adjacent for cache effect */ |
| 39 | struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp; | 44 | struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp; |
| @@ -45,7 +50,7 @@ struct stmmac_priv { | |||
| 45 | u32 tx_count_frames; | 50 | u32 tx_count_frames; |
| 46 | u32 tx_coal_frames; | 51 | u32 tx_coal_frames; |
| 47 | u32 tx_coal_timer; | 52 | u32 tx_coal_timer; |
| 48 | dma_addr_t *tx_skbuff_dma; | 53 | struct stmmac_tx_info *tx_skbuff_dma; |
| 49 | dma_addr_t dma_tx_phy; | 54 | dma_addr_t dma_tx_phy; |
| 50 | int tx_coalesce; | 55 | int tx_coalesce; |
| 51 | int hwts_tx_en; | 56 | int hwts_tx_en; |
| @@ -105,6 +110,8 @@ struct stmmac_priv { | |||
| 105 | struct ptp_clock *ptp_clock; | 110 | struct ptp_clock *ptp_clock; |
| 106 | struct ptp_clock_info ptp_clock_ops; | 111 | struct ptp_clock_info ptp_clock_ops; |
| 107 | unsigned int default_addend; | 112 | unsigned int default_addend; |
| 113 | struct clk *clk_ptp_ref; | ||
| 114 | unsigned int clk_ptp_rate; | ||
| 108 | u32 adv_ts; | 115 | u32 adv_ts; |
| 109 | int use_riwt; | 116 | int use_riwt; |
| 110 | int irq_wake; | 117 | int irq_wake; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 9af50bae4dde..cf4f38db1c0a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |||
| @@ -175,7 +175,7 @@ static const struct stmmac_stats stmmac_mmc[] = { | |||
| 175 | STMMAC_MMC_STAT(mmc_rx_octetcount_g), | 175 | STMMAC_MMC_STAT(mmc_rx_octetcount_g), |
| 176 | STMMAC_MMC_STAT(mmc_rx_broadcastframe_g), | 176 | STMMAC_MMC_STAT(mmc_rx_broadcastframe_g), |
| 177 | STMMAC_MMC_STAT(mmc_rx_multicastframe_g), | 177 | STMMAC_MMC_STAT(mmc_rx_multicastframe_g), |
| 178 | STMMAC_MMC_STAT(mmc_rx_crc_errror), | 178 | STMMAC_MMC_STAT(mmc_rx_crc_error), |
| 179 | STMMAC_MMC_STAT(mmc_rx_align_error), | 179 | STMMAC_MMC_STAT(mmc_rx_align_error), |
| 180 | STMMAC_MMC_STAT(mmc_rx_run_error), | 180 | STMMAC_MMC_STAT(mmc_rx_run_error), |
| 181 | STMMAC_MMC_STAT(mmc_rx_jabber_error), | 181 | STMMAC_MMC_STAT(mmc_rx_jabber_error), |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 08addd653728..6e6ee226de04 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -275,6 +275,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg) | |||
| 275 | */ | 275 | */ |
| 276 | bool stmmac_eee_init(struct stmmac_priv *priv) | 276 | bool stmmac_eee_init(struct stmmac_priv *priv) |
| 277 | { | 277 | { |
| 278 | char *phy_bus_name = priv->plat->phy_bus_name; | ||
| 278 | bool ret = false; | 279 | bool ret = false; |
| 279 | 280 | ||
| 280 | /* Using PCS we cannot dial with the phy registers at this stage | 281 | /* Using PCS we cannot dial with the phy registers at this stage |
| @@ -284,6 +285,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv) | |||
| 284 | (priv->pcs == STMMAC_PCS_RTBI)) | 285 | (priv->pcs == STMMAC_PCS_RTBI)) |
| 285 | goto out; | 286 | goto out; |
| 286 | 287 | ||
| 288 | /* Never init EEE in case of a switch is attached */ | ||
| 289 | if (phy_bus_name && (!strcmp(phy_bus_name, "fixed"))) | ||
| 290 | goto out; | ||
| 291 | |||
| 287 | /* MAC core supports the EEE feature. */ | 292 | /* MAC core supports the EEE feature. */ |
| 288 | if (priv->dma_cap.eee) { | 293 | if (priv->dma_cap.eee) { |
| 289 | int tx_lpi_timer = priv->tx_lpi_timer; | 294 | int tx_lpi_timer = priv->tx_lpi_timer; |
| @@ -316,10 +321,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv) | |||
| 316 | priv->hw->mac->set_eee_timer(priv->hw, | 321 | priv->hw->mac->set_eee_timer(priv->hw, |
| 317 | STMMAC_DEFAULT_LIT_LS, | 322 | STMMAC_DEFAULT_LIT_LS, |
| 318 | tx_lpi_timer); | 323 | tx_lpi_timer); |
| 319 | } else | 324 | } |
| 320 | /* Set HW EEE according to the speed */ | 325 | /* Set HW EEE according to the speed */ |
| 321 | priv->hw->mac->set_eee_pls(priv->hw, | 326 | priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link); |
| 322 | priv->phydev->link); | ||
| 323 | 327 | ||
| 324 | pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); | 328 | pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); |
| 325 | 329 | ||
| @@ -603,16 +607,16 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 603 | /* calculate default added value: | 607 | /* calculate default added value: |
| 604 | * formula is : | 608 | * formula is : |
| 605 | * addend = (2^32)/freq_div_ratio; | 609 | * addend = (2^32)/freq_div_ratio; |
| 606 | * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz | 610 | * where, freq_div_ratio = clk_ptp_ref_i/50MHz |
| 607 | * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK; | 611 | * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i; |
| 608 | * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to | 612 | * NOTE: clk_ptp_ref_i should be >= 50MHz to |
| 609 | * achive 20ns accuracy. | 613 | * achive 20ns accuracy. |
| 610 | * | 614 | * |
| 611 | * 2^x * y == (y << x), hence | 615 | * 2^x * y == (y << x), hence |
| 612 | * 2^32 * 50000000 ==> (50000000 << 32) | 616 | * 2^32 * 50000000 ==> (50000000 << 32) |
| 613 | */ | 617 | */ |
| 614 | temp = (u64) (50000000ULL << 32); | 618 | temp = (u64) (50000000ULL << 32); |
| 615 | priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK); | 619 | priv->default_addend = div_u64(temp, priv->clk_ptp_rate); |
| 616 | priv->hw->ptp->config_addend(priv->ioaddr, | 620 | priv->hw->ptp->config_addend(priv->ioaddr, |
| 617 | priv->default_addend); | 621 | priv->default_addend); |
| 618 | 622 | ||
| @@ -638,6 +642,16 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) | |||
| 638 | if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) | 642 | if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) |
| 639 | return -EOPNOTSUPP; | 643 | return -EOPNOTSUPP; |
| 640 | 644 | ||
| 645 | /* Fall-back to main clock in case of no PTP ref is passed */ | ||
| 646 | priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref"); | ||
| 647 | if (IS_ERR(priv->clk_ptp_ref)) { | ||
| 648 | priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk); | ||
| 649 | priv->clk_ptp_ref = NULL; | ||
| 650 | } else { | ||
| 651 | clk_prepare_enable(priv->clk_ptp_ref); | ||
| 652 | priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref); | ||
| 653 | } | ||
| 654 | |||
| 641 | priv->adv_ts = 0; | 655 | priv->adv_ts = 0; |
| 642 | if (priv->dma_cap.atime_stamp && priv->extend_desc) | 656 | if (priv->dma_cap.atime_stamp && priv->extend_desc) |
| 643 | priv->adv_ts = 1; | 657 | priv->adv_ts = 1; |
| @@ -657,6 +671,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) | |||
| 657 | 671 | ||
| 658 | static void stmmac_release_ptp(struct stmmac_priv *priv) | 672 | static void stmmac_release_ptp(struct stmmac_priv *priv) |
| 659 | { | 673 | { |
| 674 | if (priv->clk_ptp_ref) | ||
| 675 | clk_disable_unprepare(priv->clk_ptp_ref); | ||
| 660 | stmmac_ptp_unregister(priv); | 676 | stmmac_ptp_unregister(priv); |
| 661 | } | 677 | } |
| 662 | 678 | ||
| @@ -1061,7 +1077,8 @@ static int init_dma_desc_rings(struct net_device *dev) | |||
| 1061 | else | 1077 | else |
| 1062 | p = priv->dma_tx + i; | 1078 | p = priv->dma_tx + i; |
| 1063 | p->des2 = 0; | 1079 | p->des2 = 0; |
| 1064 | priv->tx_skbuff_dma[i] = 0; | 1080 | priv->tx_skbuff_dma[i].buf = 0; |
| 1081 | priv->tx_skbuff_dma[i].map_as_page = false; | ||
| 1065 | priv->tx_skbuff[i] = NULL; | 1082 | priv->tx_skbuff[i] = NULL; |
| 1066 | } | 1083 | } |
| 1067 | 1084 | ||
| @@ -1100,17 +1117,24 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv) | |||
| 1100 | else | 1117 | else |
| 1101 | p = priv->dma_tx + i; | 1118 | p = priv->dma_tx + i; |
| 1102 | 1119 | ||
| 1103 | if (priv->tx_skbuff_dma[i]) { | 1120 | if (priv->tx_skbuff_dma[i].buf) { |
| 1104 | dma_unmap_single(priv->device, | 1121 | if (priv->tx_skbuff_dma[i].map_as_page) |
| 1105 | priv->tx_skbuff_dma[i], | 1122 | dma_unmap_page(priv->device, |
| 1106 | priv->hw->desc->get_tx_len(p), | 1123 | priv->tx_skbuff_dma[i].buf, |
| 1107 | DMA_TO_DEVICE); | 1124 | priv->hw->desc->get_tx_len(p), |
| 1108 | priv->tx_skbuff_dma[i] = 0; | 1125 | DMA_TO_DEVICE); |
| 1126 | else | ||
| 1127 | dma_unmap_single(priv->device, | ||
| 1128 | priv->tx_skbuff_dma[i].buf, | ||
| 1129 | priv->hw->desc->get_tx_len(p), | ||
| 1130 | DMA_TO_DEVICE); | ||
| 1109 | } | 1131 | } |
| 1110 | 1132 | ||
| 1111 | if (priv->tx_skbuff[i] != NULL) { | 1133 | if (priv->tx_skbuff[i] != NULL) { |
| 1112 | dev_kfree_skb_any(priv->tx_skbuff[i]); | 1134 | dev_kfree_skb_any(priv->tx_skbuff[i]); |
| 1113 | priv->tx_skbuff[i] = NULL; | 1135 | priv->tx_skbuff[i] = NULL; |
| 1136 | priv->tx_skbuff_dma[i].buf = 0; | ||
| 1137 | priv->tx_skbuff_dma[i].map_as_page = false; | ||
| 1114 | } | 1138 | } |
| 1115 | } | 1139 | } |
| 1116 | } | 1140 | } |
| @@ -1131,7 +1155,8 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv) | |||
| 1131 | if (!priv->rx_skbuff) | 1155 | if (!priv->rx_skbuff) |
| 1132 | goto err_rx_skbuff; | 1156 | goto err_rx_skbuff; |
| 1133 | 1157 | ||
| 1134 | priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), | 1158 | priv->tx_skbuff_dma = kmalloc_array(txsize, |
| 1159 | sizeof(*priv->tx_skbuff_dma), | ||
| 1135 | GFP_KERNEL); | 1160 | GFP_KERNEL); |
| 1136 | if (!priv->tx_skbuff_dma) | 1161 | if (!priv->tx_skbuff_dma) |
| 1137 | goto err_tx_skbuff_dma; | 1162 | goto err_tx_skbuff_dma; |
| @@ -1293,12 +1318,19 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) | |||
| 1293 | pr_debug("%s: curr %d, dirty %d\n", __func__, | 1318 | pr_debug("%s: curr %d, dirty %d\n", __func__, |
| 1294 | priv->cur_tx, priv->dirty_tx); | 1319 | priv->cur_tx, priv->dirty_tx); |
| 1295 | 1320 | ||
| 1296 | if (likely(priv->tx_skbuff_dma[entry])) { | 1321 | if (likely(priv->tx_skbuff_dma[entry].buf)) { |
| 1297 | dma_unmap_single(priv->device, | 1322 | if (priv->tx_skbuff_dma[entry].map_as_page) |
| 1298 | priv->tx_skbuff_dma[entry], | 1323 | dma_unmap_page(priv->device, |
| 1299 | priv->hw->desc->get_tx_len(p), | 1324 | priv->tx_skbuff_dma[entry].buf, |
| 1300 | DMA_TO_DEVICE); | 1325 | priv->hw->desc->get_tx_len(p), |
| 1301 | priv->tx_skbuff_dma[entry] = 0; | 1326 | DMA_TO_DEVICE); |
| 1327 | else | ||
| 1328 | dma_unmap_single(priv->device, | ||
| 1329 | priv->tx_skbuff_dma[entry].buf, | ||
| 1330 | priv->hw->desc->get_tx_len(p), | ||
| 1331 | DMA_TO_DEVICE); | ||
| 1332 | priv->tx_skbuff_dma[entry].buf = 0; | ||
| 1333 | priv->tx_skbuff_dma[entry].map_as_page = false; | ||
| 1302 | } | 1334 | } |
| 1303 | priv->hw->mode->clean_desc3(priv, p); | 1335 | priv->hw->mode->clean_desc3(priv, p); |
| 1304 | 1336 | ||
| @@ -1637,6 +1669,13 @@ static int stmmac_hw_setup(struct net_device *dev) | |||
| 1637 | /* Initialize the MAC Core */ | 1669 | /* Initialize the MAC Core */ |
| 1638 | priv->hw->mac->core_init(priv->hw, dev->mtu); | 1670 | priv->hw->mac->core_init(priv->hw, dev->mtu); |
| 1639 | 1671 | ||
| 1672 | ret = priv->hw->mac->rx_ipc(priv->hw); | ||
| 1673 | if (!ret) { | ||
| 1674 | pr_warn(" RX IPC Checksum Offload disabled\n"); | ||
| 1675 | priv->plat->rx_coe = STMMAC_RX_COE_NONE; | ||
| 1676 | priv->hw->rx_csum = 0; | ||
| 1677 | } | ||
| 1678 | |||
| 1640 | /* Enable the MAC Rx/Tx */ | 1679 | /* Enable the MAC Rx/Tx */ |
| 1641 | stmmac_set_mac(priv->ioaddr, true); | 1680 | stmmac_set_mac(priv->ioaddr, true); |
| 1642 | 1681 | ||
| @@ -1887,12 +1926,16 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1887 | if (likely(!is_jumbo)) { | 1926 | if (likely(!is_jumbo)) { |
| 1888 | desc->des2 = dma_map_single(priv->device, skb->data, | 1927 | desc->des2 = dma_map_single(priv->device, skb->data, |
| 1889 | nopaged_len, DMA_TO_DEVICE); | 1928 | nopaged_len, DMA_TO_DEVICE); |
| 1890 | priv->tx_skbuff_dma[entry] = desc->des2; | 1929 | if (dma_mapping_error(priv->device, desc->des2)) |
| 1930 | goto dma_map_err; | ||
| 1931 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 1891 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, | 1932 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, |
| 1892 | csum_insertion, priv->mode); | 1933 | csum_insertion, priv->mode); |
| 1893 | } else { | 1934 | } else { |
| 1894 | desc = first; | 1935 | desc = first; |
| 1895 | entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); | 1936 | entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); |
| 1937 | if (unlikely(entry < 0)) | ||
| 1938 | goto dma_map_err; | ||
| 1896 | } | 1939 | } |
| 1897 | 1940 | ||
| 1898 | for (i = 0; i < nfrags; i++) { | 1941 | for (i = 0; i < nfrags; i++) { |
| @@ -1908,7 +1951,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1908 | 1951 | ||
| 1909 | desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, | 1952 | desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, |
| 1910 | DMA_TO_DEVICE); | 1953 | DMA_TO_DEVICE); |
| 1911 | priv->tx_skbuff_dma[entry] = desc->des2; | 1954 | if (dma_mapping_error(priv->device, desc->des2)) |
| 1955 | goto dma_map_err; /* should reuse desc w/o issues */ | ||
| 1956 | |||
| 1957 | priv->tx_skbuff_dma[entry].buf = desc->des2; | ||
| 1958 | priv->tx_skbuff_dma[entry].map_as_page = true; | ||
| 1912 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, | 1959 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, |
| 1913 | priv->mode); | 1960 | priv->mode); |
| 1914 | wmb(); | 1961 | wmb(); |
| @@ -1975,7 +2022,12 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1975 | priv->hw->dma->enable_dma_transmission(priv->ioaddr); | 2022 | priv->hw->dma->enable_dma_transmission(priv->ioaddr); |
| 1976 | 2023 | ||
| 1977 | spin_unlock(&priv->tx_lock); | 2024 | spin_unlock(&priv->tx_lock); |
| 2025 | return NETDEV_TX_OK; | ||
| 1978 | 2026 | ||
| 2027 | dma_map_err: | ||
| 2028 | dev_err(priv->device, "Tx dma map failed\n"); | ||
| 2029 | dev_kfree_skb(skb); | ||
| 2030 | priv->dev->stats.tx_dropped++; | ||
| 1979 | return NETDEV_TX_OK; | 2031 | return NETDEV_TX_OK; |
| 1980 | } | 2032 | } |
| 1981 | 2033 | ||
| @@ -2028,7 +2080,12 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) | |||
| 2028 | priv->rx_skbuff_dma[entry] = | 2080 | priv->rx_skbuff_dma[entry] = |
| 2029 | dma_map_single(priv->device, skb->data, bfsize, | 2081 | dma_map_single(priv->device, skb->data, bfsize, |
| 2030 | DMA_FROM_DEVICE); | 2082 | DMA_FROM_DEVICE); |
| 2031 | 2083 | if (dma_mapping_error(priv->device, | |
| 2084 | priv->rx_skbuff_dma[entry])) { | ||
| 2085 | dev_err(priv->device, "Rx dma map failed\n"); | ||
| 2086 | dev_kfree_skb(skb); | ||
| 2087 | break; | ||
| 2088 | } | ||
| 2032 | p->des2 = priv->rx_skbuff_dma[entry]; | 2089 | p->des2 = priv->rx_skbuff_dma[entry]; |
| 2033 | 2090 | ||
| 2034 | priv->hw->mode->refill_desc3(priv, p); | 2091 | priv->hw->mode->refill_desc3(priv, p); |
| @@ -2055,7 +2112,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) | |||
| 2055 | unsigned int entry = priv->cur_rx % rxsize; | 2112 | unsigned int entry = priv->cur_rx % rxsize; |
| 2056 | unsigned int next_entry; | 2113 | unsigned int next_entry; |
| 2057 | unsigned int count = 0; | 2114 | unsigned int count = 0; |
| 2058 | int coe = priv->plat->rx_coe; | 2115 | int coe = priv->hw->rx_csum; |
| 2059 | 2116 | ||
| 2060 | if (netif_msg_rx_status(priv)) { | 2117 | if (netif_msg_rx_status(priv)) { |
| 2061 | pr_debug("%s: descriptor ring:\n", __func__); | 2118 | pr_debug("%s: descriptor ring:\n", __func__); |
| @@ -2276,8 +2333,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev, | |||
| 2276 | 2333 | ||
| 2277 | if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) | 2334 | if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) |
| 2278 | features &= ~NETIF_F_RXCSUM; | 2335 | features &= ~NETIF_F_RXCSUM; |
| 2279 | else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) | 2336 | |
| 2280 | features &= ~NETIF_F_IPV6_CSUM; | ||
| 2281 | if (!priv->plat->tx_coe) | 2337 | if (!priv->plat->tx_coe) |
| 2282 | features &= ~NETIF_F_ALL_CSUM; | 2338 | features &= ~NETIF_F_ALL_CSUM; |
| 2283 | 2339 | ||
| @@ -2292,6 +2348,24 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev, | |||
| 2292 | return features; | 2348 | return features; |
| 2293 | } | 2349 | } |
| 2294 | 2350 | ||
| 2351 | static int stmmac_set_features(struct net_device *netdev, | ||
| 2352 | netdev_features_t features) | ||
| 2353 | { | ||
| 2354 | struct stmmac_priv *priv = netdev_priv(netdev); | ||
| 2355 | |||
| 2356 | /* Keep the COE Type in case of csum is supporting */ | ||
| 2357 | if (features & NETIF_F_RXCSUM) | ||
| 2358 | priv->hw->rx_csum = priv->plat->rx_coe; | ||
| 2359 | else | ||
| 2360 | priv->hw->rx_csum = 0; | ||
| 2361 | /* No check needed because rx_coe has been set before and it will be | ||
| 2362 | * fixed in case of issue. | ||
| 2363 | */ | ||
| 2364 | priv->hw->mac->rx_ipc(priv->hw); | ||
| 2365 | |||
| 2366 | return 0; | ||
| 2367 | } | ||
| 2368 | |||
| 2295 | /** | 2369 | /** |
| 2296 | * stmmac_interrupt - main ISR | 2370 | * stmmac_interrupt - main ISR |
| 2297 | * @irq: interrupt number. | 2371 | * @irq: interrupt number. |
| @@ -2572,6 +2646,7 @@ static const struct net_device_ops stmmac_netdev_ops = { | |||
| 2572 | .ndo_stop = stmmac_release, | 2646 | .ndo_stop = stmmac_release, |
| 2573 | .ndo_change_mtu = stmmac_change_mtu, | 2647 | .ndo_change_mtu = stmmac_change_mtu, |
| 2574 | .ndo_fix_features = stmmac_fix_features, | 2648 | .ndo_fix_features = stmmac_fix_features, |
| 2649 | .ndo_set_features = stmmac_set_features, | ||
| 2575 | .ndo_set_rx_mode = stmmac_set_rx_mode, | 2650 | .ndo_set_rx_mode = stmmac_set_rx_mode, |
| 2576 | .ndo_tx_timeout = stmmac_tx_timeout, | 2651 | .ndo_tx_timeout = stmmac_tx_timeout, |
| 2577 | .ndo_do_ioctl = stmmac_ioctl, | 2652 | .ndo_do_ioctl = stmmac_ioctl, |
| @@ -2592,7 +2667,6 @@ static const struct net_device_ops stmmac_netdev_ops = { | |||
| 2592 | */ | 2667 | */ |
| 2593 | static int stmmac_hw_init(struct stmmac_priv *priv) | 2668 | static int stmmac_hw_init(struct stmmac_priv *priv) |
| 2594 | { | 2669 | { |
| 2595 | int ret; | ||
| 2596 | struct mac_device_info *mac; | 2670 | struct mac_device_info *mac; |
| 2597 | 2671 | ||
| 2598 | /* Identify the MAC HW device */ | 2672 | /* Identify the MAC HW device */ |
| @@ -2649,15 +2723,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv) | |||
| 2649 | /* To use alternate (extended) or normal descriptor structures */ | 2723 | /* To use alternate (extended) or normal descriptor structures */ |
| 2650 | stmmac_selec_desc_mode(priv); | 2724 | stmmac_selec_desc_mode(priv); |
| 2651 | 2725 | ||
| 2652 | ret = priv->hw->mac->rx_ipc(priv->hw); | 2726 | if (priv->plat->rx_coe) { |
| 2653 | if (!ret) { | 2727 | priv->hw->rx_csum = priv->plat->rx_coe; |
| 2654 | pr_warn(" RX IPC Checksum Offload not configured.\n"); | ||
| 2655 | priv->plat->rx_coe = STMMAC_RX_COE_NONE; | ||
| 2656 | } | ||
| 2657 | |||
| 2658 | if (priv->plat->rx_coe) | ||
| 2659 | pr_info(" RX Checksum Offload Engine supported (type %d)\n", | 2728 | pr_info(" RX Checksum Offload Engine supported (type %d)\n", |
| 2660 | priv->plat->rx_coe); | 2729 | priv->plat->rx_coe); |
| 2730 | } | ||
| 2661 | if (priv->plat->tx_coe) | 2731 | if (priv->plat->tx_coe) |
| 2662 | pr_info(" TX Checksum insertion supported\n"); | 2732 | pr_info(" TX Checksum insertion supported\n"); |
| 2663 | 2733 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index b7ad3565566c..c5ee79d8a8c5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | |||
| @@ -206,6 +206,7 @@ void stmmac_ptp_unregister(struct stmmac_priv *priv) | |||
| 206 | { | 206 | { |
| 207 | if (priv->ptp_clock) { | 207 | if (priv->ptp_clock) { |
| 208 | ptp_clock_unregister(priv->ptp_clock); | 208 | ptp_clock_unregister(priv->ptp_clock); |
| 209 | priv->ptp_clock = NULL; | ||
| 209 | pr_debug("Removed PTP HW clock successfully on %s\n", | 210 | pr_debug("Removed PTP HW clock successfully on %s\n", |
| 210 | priv->dev->name); | 211 | priv->dev->name); |
| 211 | } | 212 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h index 3dbc047622fa..4535df37c227 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | |||
| @@ -25,8 +25,6 @@ | |||
| 25 | #ifndef __STMMAC_PTP_H__ | 25 | #ifndef __STMMAC_PTP_H__ |
| 26 | #define __STMMAC_PTP_H__ | 26 | #define __STMMAC_PTP_H__ |
| 27 | 27 | ||
| 28 | #define STMMAC_SYSCLOCK 62500000 | ||
| 29 | |||
| 30 | /* IEEE 1588 PTP register offsets */ | 28 | /* IEEE 1588 PTP register offsets */ |
| 31 | #define PTP_TCR 0x0700 /* Timestamp Control Reg */ | 29 | #define PTP_TCR 0x0700 /* Timestamp Control Reg */ |
| 32 | #define PTP_SSIR 0x0704 /* Sub-Second Increment Reg */ | 30 | #define PTP_SSIR 0x0704 /* Sub-Second Increment Reg */ |
diff --git a/drivers/net/fddi/skfp/h/skfbi.h b/drivers/net/fddi/skfp/h/skfbi.h index c1ba26c06d73..3de2f0d15fe2 100644 --- a/drivers/net/fddi/skfp/h/skfbi.h +++ b/drivers/net/fddi/skfp/h/skfbi.h | |||
| @@ -147,11 +147,6 @@ | |||
| 147 | #define PCI_MEM64BIT (2<<1) /* Base addr anywhere in 64 Bit range */ | 147 | #define PCI_MEM64BIT (2<<1) /* Base addr anywhere in 64 Bit range */ |
| 148 | #define PCI_MEMSPACE 0x00000001L /* Bit 0: Memory Space Indic. */ | 148 | #define PCI_MEMSPACE 0x00000001L /* Bit 0: Memory Space Indic. */ |
| 149 | 149 | ||
| 150 | /* PCI_BASE_2ND 32 bit 2nd Base address */ | ||
| 151 | #define PCI_IOBASE 0xffffff00L /* Bit 31..8: I/O Base address */ | ||
| 152 | #define PCI_IOSIZE 0x000000fcL /* Bit 7..2: I/O Size Requirements */ | ||
| 153 | #define PCI_IOSPACE 0x00000001L /* Bit 0: I/O Space Indicator */ | ||
| 154 | |||
| 155 | /* PCI_SUB_VID 16 bit Subsystem Vendor ID */ | 150 | /* PCI_SUB_VID 16 bit Subsystem Vendor ID */ |
| 156 | /* PCI_SUB_ID 16 bit Subsystem ID */ | 151 | /* PCI_SUB_ID 16 bit Subsystem ID */ |
| 157 | 152 | ||
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 60e4ca01ccbb..a96955597755 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -739,7 +739,10 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |||
| 739 | struct macvlan_dev *vlan = netdev_priv(dev); | 739 | struct macvlan_dev *vlan = netdev_priv(dev); |
| 740 | int err = -EINVAL; | 740 | int err = -EINVAL; |
| 741 | 741 | ||
| 742 | if (!vlan->port->passthru) | 742 | /* Support unicast filter only on passthru devices. |
| 743 | * Multicast filter should be allowed on all devices. | ||
| 744 | */ | ||
| 745 | if (!vlan->port->passthru && is_unicast_ether_addr(addr)) | ||
| 743 | return -EOPNOTSUPP; | 746 | return -EOPNOTSUPP; |
| 744 | 747 | ||
| 745 | if (flags & NLM_F_REPLACE) | 748 | if (flags & NLM_F_REPLACE) |
| @@ -760,7 +763,10 @@ static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |||
| 760 | struct macvlan_dev *vlan = netdev_priv(dev); | 763 | struct macvlan_dev *vlan = netdev_priv(dev); |
| 761 | int err = -EINVAL; | 764 | int err = -EINVAL; |
| 762 | 765 | ||
| 763 | if (!vlan->port->passthru) | 766 | /* Support unicast filter only on passthru devices. |
| 767 | * Multicast filter should be allowed on all devices. | ||
| 768 | */ | ||
| 769 | if (!vlan->port->passthru && is_unicast_ether_addr(addr)) | ||
| 764 | return -EOPNOTSUPP; | 770 | return -EOPNOTSUPP; |
| 765 | 771 | ||
| 766 | if (is_unicast_ether_addr(addr)) | 772 | if (is_unicast_ether_addr(addr)) |
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 526b94cea569..fdce1ea28790 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c | |||
| @@ -157,6 +157,23 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev) | |||
| 157 | return bcm7xxx_28nm_afe_config_init(phydev); | 157 | return bcm7xxx_28nm_afe_config_init(phydev); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static int bcm7xxx_28nm_resume(struct phy_device *phydev) | ||
| 161 | { | ||
| 162 | int ret; | ||
| 163 | |||
| 164 | /* Re-apply workarounds coming out suspend/resume */ | ||
| 165 | ret = bcm7xxx_28nm_config_init(phydev); | ||
| 166 | if (ret) | ||
| 167 | return ret; | ||
| 168 | |||
| 169 | /* 28nm Gigabit PHYs come out of reset without any half-duplex | ||
| 170 | * or "hub" compliant advertised mode, fix that. This does not | ||
| 171 | * cause any problems with the PHY library since genphy_config_aneg() | ||
| 172 | * gracefully handles auto-negotiated and forced modes. | ||
| 173 | */ | ||
| 174 | return genphy_config_aneg(phydev); | ||
| 175 | } | ||
| 176 | |||
| 160 | static int phy_set_clr_bits(struct phy_device *dev, int location, | 177 | static int phy_set_clr_bits(struct phy_device *dev, int location, |
| 161 | int set_mask, int clr_mask) | 178 | int set_mask, int clr_mask) |
| 162 | { | 179 | { |
| @@ -212,7 +229,7 @@ static int bcm7xxx_config_init(struct phy_device *phydev) | |||
| 212 | } | 229 | } |
| 213 | 230 | ||
| 214 | /* Workaround for putting the PHY in IDDQ mode, required | 231 | /* Workaround for putting the PHY in IDDQ mode, required |
| 215 | * for all BCM7XXX PHYs | 232 | * for all BCM7XXX 40nm and 65nm PHYs |
| 216 | */ | 233 | */ |
| 217 | static int bcm7xxx_suspend(struct phy_device *phydev) | 234 | static int bcm7xxx_suspend(struct phy_device *phydev) |
| 218 | { | 235 | { |
| @@ -257,8 +274,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
| 257 | .config_init = bcm7xxx_28nm_afe_config_init, | 274 | .config_init = bcm7xxx_28nm_afe_config_init, |
| 258 | .config_aneg = genphy_config_aneg, | 275 | .config_aneg = genphy_config_aneg, |
| 259 | .read_status = genphy_read_status, | 276 | .read_status = genphy_read_status, |
| 260 | .suspend = bcm7xxx_suspend, | 277 | .resume = bcm7xxx_28nm_resume, |
| 261 | .resume = bcm7xxx_28nm_afe_config_init, | ||
| 262 | .driver = { .owner = THIS_MODULE }, | 278 | .driver = { .owner = THIS_MODULE }, |
| 263 | }, { | 279 | }, { |
| 264 | .phy_id = PHY_ID_BCM7439, | 280 | .phy_id = PHY_ID_BCM7439, |
| @@ -270,8 +286,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
| 270 | .config_init = bcm7xxx_28nm_afe_config_init, | 286 | .config_init = bcm7xxx_28nm_afe_config_init, |
| 271 | .config_aneg = genphy_config_aneg, | 287 | .config_aneg = genphy_config_aneg, |
| 272 | .read_status = genphy_read_status, | 288 | .read_status = genphy_read_status, |
| 273 | .suspend = bcm7xxx_suspend, | 289 | .resume = bcm7xxx_28nm_resume, |
| 274 | .resume = bcm7xxx_28nm_afe_config_init, | ||
| 275 | .driver = { .owner = THIS_MODULE }, | 290 | .driver = { .owner = THIS_MODULE }, |
| 276 | }, { | 291 | }, { |
| 277 | .phy_id = PHY_ID_BCM7445, | 292 | .phy_id = PHY_ID_BCM7445, |
| @@ -283,21 +298,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
| 283 | .config_init = bcm7xxx_28nm_config_init, | 298 | .config_init = bcm7xxx_28nm_config_init, |
| 284 | .config_aneg = genphy_config_aneg, | 299 | .config_aneg = genphy_config_aneg, |
| 285 | .read_status = genphy_read_status, | 300 | .read_status = genphy_read_status, |
| 286 | .suspend = bcm7xxx_suspend, | 301 | .resume = bcm7xxx_28nm_afe_config_init, |
| 287 | .resume = bcm7xxx_28nm_config_init, | ||
| 288 | .driver = { .owner = THIS_MODULE }, | ||
| 289 | }, { | ||
| 290 | .name = "Broadcom BCM7XXX 28nm", | ||
| 291 | .phy_id = PHY_ID_BCM7XXX_28, | ||
| 292 | .phy_id_mask = PHY_BCM_OUI_MASK, | ||
| 293 | .features = PHY_GBIT_FEATURES | | ||
| 294 | SUPPORTED_Pause | SUPPORTED_Asym_Pause, | ||
| 295 | .flags = PHY_IS_INTERNAL, | ||
| 296 | .config_init = bcm7xxx_28nm_config_init, | ||
| 297 | .config_aneg = genphy_config_aneg, | ||
| 298 | .read_status = genphy_read_status, | ||
| 299 | .suspend = bcm7xxx_suspend, | ||
| 300 | .resume = bcm7xxx_28nm_config_init, | ||
| 301 | .driver = { .owner = THIS_MODULE }, | 302 | .driver = { .owner = THIS_MODULE }, |
| 302 | }, { | 303 | }, { |
| 303 | .phy_id = PHY_BCM_OUI_4, | 304 | .phy_id = PHY_BCM_OUI_4, |
| @@ -331,7 +332,6 @@ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { | |||
| 331 | { PHY_ID_BCM7366, 0xfffffff0, }, | 332 | { PHY_ID_BCM7366, 0xfffffff0, }, |
| 332 | { PHY_ID_BCM7439, 0xfffffff0, }, | 333 | { PHY_ID_BCM7439, 0xfffffff0, }, |
| 333 | { PHY_ID_BCM7445, 0xfffffff0, }, | 334 | { PHY_ID_BCM7445, 0xfffffff0, }, |
| 334 | { PHY_ID_BCM7XXX_28, 0xfffffc00 }, | ||
| 335 | { PHY_BCM_OUI_4, 0xffff0000 }, | 335 | { PHY_BCM_OUI_4, 0xffff0000 }, |
| 336 | { PHY_BCM_OUI_5, 0xffffff00 }, | 336 | { PHY_BCM_OUI_5, 0xffffff00 }, |
| 337 | { } | 337 | { } |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c94e2a27446a..a854d38c231d 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -1036,31 +1036,31 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
| 1036 | /* First check if the EEE ability is supported */ | 1036 | /* First check if the EEE ability is supported */ |
| 1037 | eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE, | 1037 | eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE, |
| 1038 | MDIO_MMD_PCS, phydev->addr); | 1038 | MDIO_MMD_PCS, phydev->addr); |
| 1039 | if (eee_cap < 0) | 1039 | if (eee_cap <= 0) |
| 1040 | return eee_cap; | 1040 | goto eee_exit_err; |
| 1041 | 1041 | ||
| 1042 | cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); | 1042 | cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); |
| 1043 | if (!cap) | 1043 | if (!cap) |
| 1044 | return -EPROTONOSUPPORT; | 1044 | goto eee_exit_err; |
| 1045 | 1045 | ||
| 1046 | /* Check which link settings negotiated and verify it in | 1046 | /* Check which link settings negotiated and verify it in |
| 1047 | * the EEE advertising registers. | 1047 | * the EEE advertising registers. |
| 1048 | */ | 1048 | */ |
| 1049 | eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE, | 1049 | eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE, |
| 1050 | MDIO_MMD_AN, phydev->addr); | 1050 | MDIO_MMD_AN, phydev->addr); |
| 1051 | if (eee_lp < 0) | 1051 | if (eee_lp <= 0) |
| 1052 | return eee_lp; | 1052 | goto eee_exit_err; |
| 1053 | 1053 | ||
| 1054 | eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, | 1054 | eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, |
| 1055 | MDIO_MMD_AN, phydev->addr); | 1055 | MDIO_MMD_AN, phydev->addr); |
| 1056 | if (eee_adv < 0) | 1056 | if (eee_adv <= 0) |
| 1057 | return eee_adv; | 1057 | goto eee_exit_err; |
| 1058 | 1058 | ||
| 1059 | adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); | 1059 | adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); |
| 1060 | lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); | 1060 | lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); |
| 1061 | idx = phy_find_setting(phydev->speed, phydev->duplex); | 1061 | idx = phy_find_setting(phydev->speed, phydev->duplex); |
| 1062 | if (!(lp & adv & settings[idx].setting)) | 1062 | if (!(lp & adv & settings[idx].setting)) |
| 1063 | return -EPROTONOSUPPORT; | 1063 | goto eee_exit_err; |
| 1064 | 1064 | ||
| 1065 | if (clk_stop_enable) { | 1065 | if (clk_stop_enable) { |
| 1066 | /* Configure the PHY to stop receiving xMII | 1066 | /* Configure the PHY to stop receiving xMII |
| @@ -1080,7 +1080,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
| 1080 | 1080 | ||
| 1081 | return 0; /* EEE supported */ | 1081 | return 0; /* EEE supported */ |
| 1082 | } | 1082 | } |
| 1083 | 1083 | eee_exit_err: | |
| 1084 | return -EPROTONOSUPPORT; | 1084 | return -EPROTONOSUPPORT; |
| 1085 | } | 1085 | } |
| 1086 | EXPORT_SYMBOL(phy_init_eee); | 1086 | EXPORT_SYMBOL(phy_init_eee); |
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 180c49479c42..a4b08198fb9f 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c | |||
| @@ -43,6 +43,22 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev) | |||
| 43 | 43 | ||
| 44 | static int smsc_phy_config_init(struct phy_device *phydev) | 44 | static int smsc_phy_config_init(struct phy_device *phydev) |
| 45 | { | 45 | { |
| 46 | int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | ||
| 47 | |||
| 48 | if (rc < 0) | ||
| 49 | return rc; | ||
| 50 | |||
| 51 | /* Enable energy detect mode for this SMSC Transceivers */ | ||
| 52 | rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, | ||
| 53 | rc | MII_LAN83C185_EDPWRDOWN); | ||
| 54 | if (rc < 0) | ||
| 55 | return rc; | ||
| 56 | |||
| 57 | return smsc_phy_ack_interrupt(phydev); | ||
| 58 | } | ||
| 59 | |||
| 60 | static int smsc_phy_reset(struct phy_device *phydev) | ||
| 61 | { | ||
| 46 | int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); | 62 | int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); |
| 47 | if (rc < 0) | 63 | if (rc < 0) |
| 48 | return rc; | 64 | return rc; |
| @@ -66,18 +82,7 @@ static int smsc_phy_config_init(struct phy_device *phydev) | |||
| 66 | rc = phy_read(phydev, MII_BMCR); | 82 | rc = phy_read(phydev, MII_BMCR); |
| 67 | } while (rc & BMCR_RESET); | 83 | } while (rc & BMCR_RESET); |
| 68 | } | 84 | } |
| 69 | 85 | return 0; | |
| 70 | rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | ||
| 71 | if (rc < 0) | ||
| 72 | return rc; | ||
| 73 | |||
| 74 | /* Enable energy detect mode for this SMSC Transceivers */ | ||
| 75 | rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, | ||
| 76 | rc | MII_LAN83C185_EDPWRDOWN); | ||
| 77 | if (rc < 0) | ||
| 78 | return rc; | ||
| 79 | |||
| 80 | return smsc_phy_ack_interrupt (phydev); | ||
| 81 | } | 86 | } |
| 82 | 87 | ||
| 83 | static int lan911x_config_init(struct phy_device *phydev) | 88 | static int lan911x_config_init(struct phy_device *phydev) |
| @@ -142,6 +147,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
| 142 | .config_aneg = genphy_config_aneg, | 147 | .config_aneg = genphy_config_aneg, |
| 143 | .read_status = genphy_read_status, | 148 | .read_status = genphy_read_status, |
| 144 | .config_init = smsc_phy_config_init, | 149 | .config_init = smsc_phy_config_init, |
| 150 | .soft_reset = smsc_phy_reset, | ||
| 145 | 151 | ||
| 146 | /* IRQ related */ | 152 | /* IRQ related */ |
| 147 | .ack_interrupt = smsc_phy_ack_interrupt, | 153 | .ack_interrupt = smsc_phy_ack_interrupt, |
| @@ -164,6 +170,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
| 164 | .config_aneg = genphy_config_aneg, | 170 | .config_aneg = genphy_config_aneg, |
| 165 | .read_status = genphy_read_status, | 171 | .read_status = genphy_read_status, |
| 166 | .config_init = smsc_phy_config_init, | 172 | .config_init = smsc_phy_config_init, |
| 173 | .soft_reset = smsc_phy_reset, | ||
| 167 | 174 | ||
| 168 | /* IRQ related */ | 175 | /* IRQ related */ |
| 169 | .ack_interrupt = smsc_phy_ack_interrupt, | 176 | .ack_interrupt = smsc_phy_ack_interrupt, |
| @@ -186,6 +193,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
| 186 | .config_aneg = genphy_config_aneg, | 193 | .config_aneg = genphy_config_aneg, |
| 187 | .read_status = genphy_read_status, | 194 | .read_status = genphy_read_status, |
| 188 | .config_init = smsc_phy_config_init, | 195 | .config_init = smsc_phy_config_init, |
| 196 | .soft_reset = smsc_phy_reset, | ||
| 189 | 197 | ||
| 190 | /* IRQ related */ | 198 | /* IRQ related */ |
| 191 | .ack_interrupt = smsc_phy_ack_interrupt, | 199 | .ack_interrupt = smsc_phy_ack_interrupt, |
| @@ -230,6 +238,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
| 230 | .config_aneg = genphy_config_aneg, | 238 | .config_aneg = genphy_config_aneg, |
| 231 | .read_status = lan87xx_read_status, | 239 | .read_status = lan87xx_read_status, |
| 232 | .config_init = smsc_phy_config_init, | 240 | .config_init = smsc_phy_config_init, |
| 241 | .soft_reset = smsc_phy_reset, | ||
| 233 | 242 | ||
| 234 | /* IRQ related */ | 243 | /* IRQ related */ |
| 235 | .ack_interrupt = smsc_phy_ack_interrupt, | 244 | .ack_interrupt = smsc_phy_ack_interrupt, |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index d6e90c72c257..6dfcbf523936 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
| @@ -2056,7 +2056,6 @@ vmxnet3_set_mc(struct net_device *netdev) | |||
| 2056 | if (!netdev_mc_empty(netdev)) { | 2056 | if (!netdev_mc_empty(netdev)) { |
| 2057 | new_table = vmxnet3_copy_mc(netdev); | 2057 | new_table = vmxnet3_copy_mc(netdev); |
| 2058 | if (new_table) { | 2058 | if (new_table) { |
| 2059 | new_mode |= VMXNET3_RXM_MCAST; | ||
| 2060 | rxConf->mfTableLen = cpu_to_le16( | 2059 | rxConf->mfTableLen = cpu_to_le16( |
| 2061 | netdev_mc_count(netdev) * ETH_ALEN); | 2060 | netdev_mc_count(netdev) * ETH_ALEN); |
| 2062 | new_table_pa = dma_map_single( | 2061 | new_table_pa = dma_map_single( |
| @@ -2064,15 +2063,18 @@ vmxnet3_set_mc(struct net_device *netdev) | |||
| 2064 | new_table, | 2063 | new_table, |
| 2065 | rxConf->mfTableLen, | 2064 | rxConf->mfTableLen, |
| 2066 | PCI_DMA_TODEVICE); | 2065 | PCI_DMA_TODEVICE); |
| 2066 | } | ||
| 2067 | |||
| 2068 | if (new_table_pa) { | ||
| 2069 | new_mode |= VMXNET3_RXM_MCAST; | ||
| 2067 | rxConf->mfTablePA = cpu_to_le64(new_table_pa); | 2070 | rxConf->mfTablePA = cpu_to_le64(new_table_pa); |
| 2068 | } else { | 2071 | } else { |
| 2069 | netdev_info(netdev, "failed to copy mcast list" | 2072 | netdev_info(netdev, |
| 2070 | ", setting ALL_MULTI\n"); | 2073 | "failed to copy mcast list, setting ALL_MULTI\n"); |
| 2071 | new_mode |= VMXNET3_RXM_ALL_MULTI; | 2074 | new_mode |= VMXNET3_RXM_ALL_MULTI; |
| 2072 | } | 2075 | } |
| 2073 | } | 2076 | } |
| 2074 | 2077 | ||
| 2075 | |||
| 2076 | if (!(new_mode & VMXNET3_RXM_MCAST)) { | 2078 | if (!(new_mode & VMXNET3_RXM_MCAST)) { |
| 2077 | rxConf->mfTableLen = 0; | 2079 | rxConf->mfTableLen = 0; |
| 2078 | rxConf->mfTablePA = 0; | 2080 | rxConf->mfTablePA = 0; |
| @@ -2091,11 +2093,10 @@ vmxnet3_set_mc(struct net_device *netdev) | |||
| 2091 | VMXNET3_CMD_UPDATE_MAC_FILTERS); | 2093 | VMXNET3_CMD_UPDATE_MAC_FILTERS); |
| 2092 | spin_unlock_irqrestore(&adapter->cmd_lock, flags); | 2094 | spin_unlock_irqrestore(&adapter->cmd_lock, flags); |
| 2093 | 2095 | ||
| 2094 | if (new_table) { | 2096 | if (new_table_pa) |
| 2095 | dma_unmap_single(&adapter->pdev->dev, new_table_pa, | 2097 | dma_unmap_single(&adapter->pdev->dev, new_table_pa, |
| 2096 | rxConf->mfTableLen, PCI_DMA_TODEVICE); | 2098 | rxConf->mfTableLen, PCI_DMA_TODEVICE); |
| 2097 | kfree(new_table); | 2099 | kfree(new_table); |
| 2098 | } | ||
| 2099 | } | 2100 | } |
| 2100 | 2101 | ||
| 2101 | void | 2102 | void |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 29ee77f2c97f..3759479f959a 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
| @@ -69,10 +69,10 @@ | |||
| 69 | /* | 69 | /* |
| 70 | * Version numbers | 70 | * Version numbers |
| 71 | */ | 71 | */ |
| 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.2.0.0-k" | 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.2.1.0-k" |
| 73 | 73 | ||
| 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ | 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
| 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01020000 | 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01020100 |
| 76 | 76 | ||
| 77 | #if defined(CONFIG_PCI_MSI) | 77 | #if defined(CONFIG_PCI_MSI) |
| 78 | /* RSS only makes sense if MSI-X is supported. */ | 78 | /* RSS only makes sense if MSI-X is supported. */ |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 1fb7b37d1402..beb377b2d4b7 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1327,7 +1327,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb) | |||
| 1327 | } else if (vxlan->flags & VXLAN_F_L3MISS) { | 1327 | } else if (vxlan->flags & VXLAN_F_L3MISS) { |
| 1328 | union vxlan_addr ipa = { | 1328 | union vxlan_addr ipa = { |
| 1329 | .sin.sin_addr.s_addr = tip, | 1329 | .sin.sin_addr.s_addr = tip, |
| 1330 | .sa.sa_family = AF_INET, | 1330 | .sin.sin_family = AF_INET, |
| 1331 | }; | 1331 | }; |
| 1332 | 1332 | ||
| 1333 | vxlan_ip_miss(dev, &ipa); | 1333 | vxlan_ip_miss(dev, &ipa); |
| @@ -1488,7 +1488,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) | |||
| 1488 | } else if (vxlan->flags & VXLAN_F_L3MISS) { | 1488 | } else if (vxlan->flags & VXLAN_F_L3MISS) { |
| 1489 | union vxlan_addr ipa = { | 1489 | union vxlan_addr ipa = { |
| 1490 | .sin6.sin6_addr = msg->target, | 1490 | .sin6.sin6_addr = msg->target, |
| 1491 | .sa.sa_family = AF_INET6, | 1491 | .sin6.sin6_family = AF_INET6, |
| 1492 | }; | 1492 | }; |
| 1493 | 1493 | ||
| 1494 | vxlan_ip_miss(dev, &ipa); | 1494 | vxlan_ip_miss(dev, &ipa); |
| @@ -1521,7 +1521,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) | |||
| 1521 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { | 1521 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { |
| 1522 | union vxlan_addr ipa = { | 1522 | union vxlan_addr ipa = { |
| 1523 | .sin.sin_addr.s_addr = pip->daddr, | 1523 | .sin.sin_addr.s_addr = pip->daddr, |
| 1524 | .sa.sa_family = AF_INET, | 1524 | .sin.sin_family = AF_INET, |
| 1525 | }; | 1525 | }; |
| 1526 | 1526 | ||
| 1527 | vxlan_ip_miss(dev, &ipa); | 1527 | vxlan_ip_miss(dev, &ipa); |
| @@ -1542,7 +1542,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) | |||
| 1542 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { | 1542 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { |
| 1543 | union vxlan_addr ipa = { | 1543 | union vxlan_addr ipa = { |
| 1544 | .sin6.sin6_addr = pip6->daddr, | 1544 | .sin6.sin6_addr = pip6->daddr, |
| 1545 | .sa.sa_family = AF_INET6, | 1545 | .sin6.sin6_family = AF_INET6, |
| 1546 | }; | 1546 | }; |
| 1547 | 1547 | ||
| 1548 | vxlan_ip_miss(dev, &ipa); | 1548 | vxlan_ip_miss(dev, &ipa); |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 334c2ece855a..da92bfa76b7c 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
| @@ -2423,8 +2423,6 @@ static void at76_delete_device(struct at76_priv *priv) | |||
| 2423 | 2423 | ||
| 2424 | kfree_skb(priv->rx_skb); | 2424 | kfree_skb(priv->rx_skb); |
| 2425 | 2425 | ||
| 2426 | usb_put_dev(priv->udev); | ||
| 2427 | |||
| 2428 | at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw", | 2426 | at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw", |
| 2429 | __func__); | 2427 | __func__); |
| 2430 | ieee80211_free_hw(priv->hw); | 2428 | ieee80211_free_hw(priv->hw); |
| @@ -2558,6 +2556,7 @@ static void at76_disconnect(struct usb_interface *interface) | |||
| 2558 | 2556 | ||
| 2559 | wiphy_info(priv->hw->wiphy, "disconnecting\n"); | 2557 | wiphy_info(priv->hw->wiphy, "disconnecting\n"); |
| 2560 | at76_delete_device(priv); | 2558 | at76_delete_device(priv); |
| 2559 | usb_put_dev(priv->udev); | ||
| 2561 | dev_info(&interface->dev, "disconnected\n"); | 2560 | dev_info(&interface->dev, "disconnected\n"); |
| 2562 | } | 2561 | } |
| 2563 | 2562 | ||
diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 5fe29b9f8fa2..8f68426ca653 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c | |||
| @@ -253,7 +253,7 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, | |||
| 253 | 253 | ||
| 254 | if (strncmp("trigger", buf, 7) == 0) { | 254 | if (strncmp("trigger", buf, 7) == 0) { |
| 255 | ath9k_spectral_scan_trigger(sc->hw); | 255 | ath9k_spectral_scan_trigger(sc->hw); |
| 256 | } else if (strncmp("background", buf, 9) == 0) { | 256 | } else if (strncmp("background", buf, 10) == 0) { |
| 257 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND); | 257 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND); |
| 258 | ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); | 258 | ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); |
| 259 | } else if (strncmp("chanscan", buf, 8) == 0) { | 259 | } else if (strncmp("chanscan", buf, 8) == 0) { |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 6451d2b6abcf..824f5e287783 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
| @@ -51,7 +51,6 @@ config IWLWIFI_LEDS | |||
| 51 | 51 | ||
| 52 | config IWLDVM | 52 | config IWLDVM |
| 53 | tristate "Intel Wireless WiFi DVM Firmware support" | 53 | tristate "Intel Wireless WiFi DVM Firmware support" |
| 54 | depends on m | ||
| 55 | default IWLWIFI | 54 | default IWLWIFI |
| 56 | help | 55 | help |
| 57 | This is the driver that supports the DVM firmware which is | 56 | This is the driver that supports the DVM firmware which is |
| @@ -60,7 +59,6 @@ config IWLDVM | |||
| 60 | 59 | ||
| 61 | config IWLMVM | 60 | config IWLMVM |
| 62 | tristate "Intel Wireless WiFi MVM Firmware support" | 61 | tristate "Intel Wireless WiFi MVM Firmware support" |
| 63 | depends on m | ||
| 64 | help | 62 | help |
| 65 | This is the driver that supports the MVM firmware which is | 63 | This is the driver that supports the MVM firmware which is |
| 66 | currently only available for 7260 and 3160 devices. | 64 | currently only available for 7260 and 3160 devices. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 6dc5dd3ced44..ed50de6362ed 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
| @@ -1068,6 +1068,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 1068 | /* recalculate basic rates */ | 1068 | /* recalculate basic rates */ |
| 1069 | iwl_calc_basic_rates(priv, ctx); | 1069 | iwl_calc_basic_rates(priv, ctx); |
| 1070 | 1070 | ||
| 1071 | /* | ||
| 1072 | * force CTS-to-self frames protection if RTS-CTS is not preferred | ||
| 1073 | * one aggregation protection method | ||
| 1074 | */ | ||
| 1075 | if (!priv->hw_params.use_rts_for_aggregation) | ||
| 1076 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | ||
| 1077 | |||
| 1071 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 1078 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
| 1072 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) | 1079 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) |
| 1073 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | 1080 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; |
| @@ -1473,6 +1480,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1473 | else | 1480 | else |
| 1474 | ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 1481 | ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
| 1475 | 1482 | ||
| 1483 | if (bss_conf->use_cts_prot) | ||
| 1484 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | ||
| 1485 | else | ||
| 1486 | ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; | ||
| 1487 | |||
| 1476 | memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); | 1488 | memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); |
| 1477 | 1489 | ||
| 1478 | if (vif->type == NL80211_IFTYPE_AP || | 1490 | if (vif->type == NL80211_IFTYPE_AP || |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 48730064da73..d67a37a786aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
| @@ -67,8 +67,8 @@ | |||
| 67 | #include "iwl-agn-hw.h" | 67 | #include "iwl-agn-hw.h" |
| 68 | 68 | ||
| 69 | /* Highest firmware API version supported */ | 69 | /* Highest firmware API version supported */ |
| 70 | #define IWL7260_UCODE_API_MAX 9 | 70 | #define IWL7260_UCODE_API_MAX 10 |
| 71 | #define IWL3160_UCODE_API_MAX 9 | 71 | #define IWL3160_UCODE_API_MAX 10 |
| 72 | 72 | ||
| 73 | /* Oldest version we won't warn about */ | 73 | /* Oldest version we won't warn about */ |
| 74 | #define IWL7260_UCODE_API_OK 9 | 74 | #define IWL7260_UCODE_API_OK 9 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 44b19e015102..e93c6972290b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
| @@ -67,7 +67,7 @@ | |||
| 67 | #include "iwl-agn-hw.h" | 67 | #include "iwl-agn-hw.h" |
| 68 | 68 | ||
| 69 | /* Highest firmware API version supported */ | 69 | /* Highest firmware API version supported */ |
| 70 | #define IWL8000_UCODE_API_MAX 9 | 70 | #define IWL8000_UCODE_API_MAX 10 |
| 71 | 71 | ||
| 72 | /* Oldest version we won't warn about */ | 72 | /* Oldest version we won't warn about */ |
| 73 | #define IWL8000_UCODE_API_OK 8 | 73 | #define IWL8000_UCODE_API_OK 8 |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c index 33da3dfcfa4f..d4bd550f505c 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c | |||
| @@ -101,7 +101,7 @@ static bool halbtc_legacy(struct rtl_priv *adapter) | |||
| 101 | 101 | ||
| 102 | bool is_legacy = false; | 102 | bool is_legacy = false; |
| 103 | 103 | ||
| 104 | if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B)) | 104 | if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G)) |
| 105 | is_legacy = true; | 105 | is_legacy = true; |
| 106 | 106 | ||
| 107 | return is_legacy; | 107 | return is_legacy; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 361435f8608a..1ac6383e7947 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
| @@ -317,6 +317,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
| 317 | {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ | 317 | {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ |
| 318 | {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 318 | {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
| 319 | {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 319 | {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
| 320 | {RTL_USB_DEVICE(0x0df6, 0x0070, rtl92cu_hal_cfg)}, /*Sitecom - 150N */ | ||
| 320 | {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/ | 321 | {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/ |
| 321 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | 322 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ |
| 322 | {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ | 323 | {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index e29e15dca86e..f379689dde30 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -576,6 +576,9 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, | |||
| 576 | init_waitqueue_head(&queue->dealloc_wq); | 576 | init_waitqueue_head(&queue->dealloc_wq); |
| 577 | atomic_set(&queue->inflight_packets, 0); | 577 | atomic_set(&queue->inflight_packets, 0); |
| 578 | 578 | ||
| 579 | netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll, | ||
| 580 | XENVIF_NAPI_WEIGHT); | ||
| 581 | |||
| 579 | if (tx_evtchn == rx_evtchn) { | 582 | if (tx_evtchn == rx_evtchn) { |
| 580 | /* feature-split-event-channels == 0 */ | 583 | /* feature-split-event-channels == 0 */ |
| 581 | err = bind_interdomain_evtchn_to_irqhandler( | 584 | err = bind_interdomain_evtchn_to_irqhandler( |
| @@ -629,9 +632,6 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, | |||
| 629 | wake_up_process(queue->task); | 632 | wake_up_process(queue->task); |
| 630 | wake_up_process(queue->dealloc_task); | 633 | wake_up_process(queue->dealloc_task); |
| 631 | 634 | ||
| 632 | netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll, | ||
| 633 | XENVIF_NAPI_WEIGHT); | ||
| 634 | |||
| 635 | return 0; | 635 | return 0; |
| 636 | 636 | ||
| 637 | err_rx_unbind: | 637 | err_rx_unbind: |
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 9dd63b822025..e9bf2f47b61a 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c | |||
| @@ -510,7 +510,7 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt, | |||
| 510 | 510 | ||
| 511 | WARN_ON(nt->mw[mw_num].virt_addr == NULL); | 511 | WARN_ON(nt->mw[mw_num].virt_addr == NULL); |
| 512 | 512 | ||
| 513 | if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max) | 513 | if (nt->max_qps % mw_max && mw_num + 1 < nt->max_qps / mw_max) |
| 514 | num_qps_mw = nt->max_qps / mw_max + 1; | 514 | num_qps_mw = nt->max_qps / mw_max + 1; |
| 515 | else | 515 | else |
| 516 | num_qps_mw = nt->max_qps / mw_max; | 516 | num_qps_mw = nt->max_qps / mw_max; |
| @@ -576,6 +576,19 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size) | |||
| 576 | return -ENOMEM; | 576 | return -ENOMEM; |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | /* | ||
| 580 | * we must ensure that the memory address allocated is BAR size | ||
| 581 | * aligned in order for the XLAT register to take the value. This | ||
| 582 | * is a requirement of the hardware. It is recommended to setup CMA | ||
| 583 | * for BAR sizes equal or greater than 4MB. | ||
| 584 | */ | ||
| 585 | if (!IS_ALIGNED(mw->dma_addr, mw->size)) { | ||
| 586 | dev_err(&pdev->dev, "DMA memory %pad not aligned to BAR size\n", | ||
| 587 | &mw->dma_addr); | ||
| 588 | ntb_free_mw(nt, num_mw); | ||
| 589 | return -ENOMEM; | ||
| 590 | } | ||
| 591 | |||
| 579 | /* Notify HW the memory location of the receive buffer */ | 592 | /* Notify HW the memory location of the receive buffer */ |
| 580 | ntb_set_mw_addr(nt->ndev, num_mw, mw->dma_addr); | 593 | ntb_set_mw_addr(nt->ndev, num_mw, mw->dma_addr); |
| 581 | 594 | ||
| @@ -856,7 +869,7 @@ static int ntb_transport_init_queue(struct ntb_transport *nt, | |||
| 856 | qp->client_ready = NTB_LINK_DOWN; | 869 | qp->client_ready = NTB_LINK_DOWN; |
| 857 | qp->event_handler = NULL; | 870 | qp->event_handler = NULL; |
| 858 | 871 | ||
| 859 | if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max) | 872 | if (nt->max_qps % mw_max && mw_num + 1 < nt->max_qps / mw_max) |
| 860 | num_qps_mw = nt->max_qps / mw_max + 1; | 873 | num_qps_mw = nt->max_qps / mw_max + 1; |
| 861 | else | 874 | else |
| 862 | num_qps_mw = nt->max_qps / mw_max; | 875 | num_qps_mw = nt->max_qps / mw_max; |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index f46a24ffa3fe..79cb8313c7d8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
| @@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, | |||
| 453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); | 453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); |
| 454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); | 454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); |
| 455 | 455 | ||
| 456 | if (base && size && | 456 | if (size && |
| 457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) | 457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) |
| 458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", | 458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", |
| 459 | uname, &base, (unsigned long)size / SZ_1M); | 459 | uname, &base, (unsigned long)size / SZ_1M); |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3e06a699352d..1471e0a223a5 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
| @@ -301,16 +301,17 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar | |||
| 301 | /* Get the reg property (if any) */ | 301 | /* Get the reg property (if any) */ |
| 302 | addr = of_get_property(device, "reg", NULL); | 302 | addr = of_get_property(device, "reg", NULL); |
| 303 | 303 | ||
| 304 | /* Try the new-style interrupts-extended first */ | ||
| 305 | res = of_parse_phandle_with_args(device, "interrupts-extended", | ||
| 306 | "#interrupt-cells", index, out_irq); | ||
| 307 | if (!res) | ||
| 308 | return of_irq_parse_raw(addr, out_irq); | ||
| 309 | |||
| 304 | /* Get the interrupts property */ | 310 | /* Get the interrupts property */ |
| 305 | intspec = of_get_property(device, "interrupts", &intlen); | 311 | intspec = of_get_property(device, "interrupts", &intlen); |
| 306 | if (intspec == NULL) { | 312 | if (intspec == NULL) |
| 307 | /* Try the new-style interrupts-extended */ | 313 | return -EINVAL; |
| 308 | res = of_parse_phandle_with_args(device, "interrupts-extended", | 314 | |
| 309 | "#interrupt-cells", index, out_irq); | ||
| 310 | if (res) | ||
| 311 | return -EINVAL; | ||
| 312 | return of_irq_parse_raw(addr, out_irq); | ||
| 313 | } | ||
| 314 | intlen /= sizeof(*intspec); | 315 | intlen /= sizeof(*intspec); |
| 315 | 316 | ||
| 316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); | 317 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index d41002667833..a737cb5974de 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
| @@ -27,6 +27,7 @@ static struct selftest_results { | |||
| 27 | #define NO_OF_NODES 2 | 27 | #define NO_OF_NODES 2 |
| 28 | static struct device_node *nodes[NO_OF_NODES]; | 28 | static struct device_node *nodes[NO_OF_NODES]; |
| 29 | static int last_node_index; | 29 | static int last_node_index; |
| 30 | static bool selftest_live_tree; | ||
| 30 | 31 | ||
| 31 | #define selftest(result, fmt, ...) { \ | 32 | #define selftest(result, fmt, ...) { \ |
| 32 | if (!(result)) { \ | 33 | if (!(result)) { \ |
| @@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np) | |||
| 630 | { | 631 | { |
| 631 | struct device_node *next, *root = np, *dup; | 632 | struct device_node *next, *root = np, *dup; |
| 632 | 633 | ||
| 633 | if (!np) { | ||
| 634 | pr_warn("%s: No tree to attach; not running tests\n", | ||
| 635 | __func__); | ||
| 636 | return -ENODATA; | ||
| 637 | } | ||
| 638 | |||
| 639 | |||
| 640 | /* skip root node */ | 634 | /* skip root node */ |
| 641 | np = np->child; | 635 | np = np->child; |
| 642 | /* storing a copy in temporary node */ | 636 | /* storing a copy in temporary node */ |
| @@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np) | |||
| 672 | static int __init selftest_data_add(void) | 666 | static int __init selftest_data_add(void) |
| 673 | { | 667 | { |
| 674 | void *selftest_data; | 668 | void *selftest_data; |
| 675 | struct device_node *selftest_data_node; | 669 | struct device_node *selftest_data_node, *np; |
| 676 | extern uint8_t __dtb_testcases_begin[]; | 670 | extern uint8_t __dtb_testcases_begin[]; |
| 677 | extern uint8_t __dtb_testcases_end[]; | 671 | extern uint8_t __dtb_testcases_end[]; |
| 678 | const int size = __dtb_testcases_end - __dtb_testcases_begin; | 672 | const int size = __dtb_testcases_end - __dtb_testcases_begin; |
| 679 | 673 | ||
| 680 | if (!size || !of_allnodes) { | 674 | if (!size) { |
| 681 | pr_warn("%s: No testcase data to attach; not running tests\n", | 675 | pr_warn("%s: No testcase data to attach; not running tests\n", |
| 682 | __func__); | 676 | __func__); |
| 683 | return -ENODATA; | 677 | return -ENODATA; |
| @@ -692,6 +686,22 @@ static int __init selftest_data_add(void) | |||
| 692 | return -ENOMEM; | 686 | return -ENOMEM; |
| 693 | } | 687 | } |
| 694 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); | 688 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); |
| 689 | if (!selftest_data_node) { | ||
| 690 | pr_warn("%s: No tree to attach; not running tests\n", __func__); | ||
| 691 | return -ENODATA; | ||
| 692 | } | ||
| 693 | |||
| 694 | if (!of_allnodes) { | ||
| 695 | /* enabling flag for removing nodes */ | ||
| 696 | selftest_live_tree = true; | ||
| 697 | of_allnodes = selftest_data_node; | ||
| 698 | |||
| 699 | for_each_of_allnodes(np) | ||
| 700 | __of_attach_node_sysfs(np); | ||
| 701 | of_aliases = of_find_node_by_path("/aliases"); | ||
| 702 | of_chosen = of_find_node_by_path("/chosen"); | ||
| 703 | return 0; | ||
| 704 | } | ||
| 695 | 705 | ||
| 696 | /* attach the sub-tree to live tree */ | 706 | /* attach the sub-tree to live tree */ |
| 697 | return attach_node_and_children(selftest_data_node); | 707 | return attach_node_and_children(selftest_data_node); |
| @@ -723,6 +733,18 @@ static void selftest_data_remove(void) | |||
| 723 | struct device_node *np; | 733 | struct device_node *np; |
| 724 | struct property *prop; | 734 | struct property *prop; |
| 725 | 735 | ||
| 736 | if (selftest_live_tree) { | ||
| 737 | of_node_put(of_aliases); | ||
| 738 | of_node_put(of_chosen); | ||
| 739 | of_aliases = NULL; | ||
| 740 | of_chosen = NULL; | ||
| 741 | for_each_child_of_node(of_allnodes, np) | ||
| 742 | detach_node_and_children(np); | ||
| 743 | __of_detach_node_sysfs(of_allnodes); | ||
| 744 | of_allnodes = NULL; | ||
| 745 | return; | ||
| 746 | } | ||
| 747 | |||
| 726 | while (last_node_index >= 0) { | 748 | while (last_node_index >= 0) { |
| 727 | if (nodes[last_node_index]) { | 749 | if (nodes[last_node_index]) { |
| 728 | np = of_find_node_by_path(nodes[last_node_index]->full_name); | 750 | np = of_find_node_by_path(nodes[last_node_index]->full_name); |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 9eae9834bcc7..a0580afe1713 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
| @@ -913,7 +913,7 @@ static int __init dino_probe(struct parisc_device *dev) | |||
| 913 | printk("%s version %s found at 0x%lx\n", name, version, hpa); | 913 | printk("%s version %s found at 0x%lx\n", name, version, hpa); |
| 914 | 914 | ||
| 915 | if (!request_mem_region(hpa, PAGE_SIZE, name)) { | 915 | if (!request_mem_region(hpa, PAGE_SIZE, name)) { |
| 916 | printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n", | 916 | printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%lx)!\n", |
| 917 | hpa); | 917 | hpa); |
| 918 | return 1; | 918 | return 1; |
| 919 | } | 919 | } |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 2d8a4d05d78f..90f5ccacce4b 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
| @@ -1,9 +1,18 @@ | |||
| 1 | menu "PCI host controller drivers" | 1 | menu "PCI host controller drivers" |
| 2 | depends on PCI | 2 | depends on PCI |
| 3 | 3 | ||
| 4 | config PCI_DRA7XX | ||
| 5 | bool "TI DRA7xx PCIe controller" | ||
| 6 | select PCIE_DW | ||
| 7 | depends on OF && HAS_IOMEM && TI_PIPE3 | ||
| 8 | help | ||
| 9 | Enables support for the PCIe controller in the DRA7xx SoC. There | ||
| 10 | are two instances of PCIe controller in DRA7xx. This controller can | ||
| 11 | act both as EP and RC. This reuses the Designware core. | ||
| 12 | |||
| 4 | config PCI_MVEBU | 13 | config PCI_MVEBU |
| 5 | bool "Marvell EBU PCIe controller" | 14 | bool "Marvell EBU PCIe controller" |
| 6 | depends on ARCH_MVEBU || ARCH_DOVE || ARCH_KIRKWOOD | 15 | depends on ARCH_MVEBU || ARCH_DOVE |
| 7 | depends on OF | 16 | depends on OF |
| 8 | 17 | ||
| 9 | config PCIE_DW | 18 | config PCIE_DW |
| @@ -47,7 +56,7 @@ config PCI_HOST_GENERIC | |||
| 47 | controller, such as the one emulated by kvmtool. | 56 | controller, such as the one emulated by kvmtool. |
| 48 | 57 | ||
| 49 | config PCIE_SPEAR13XX | 58 | config PCIE_SPEAR13XX |
| 50 | tristate "STMicroelectronics SPEAr PCIe controller" | 59 | bool "STMicroelectronics SPEAr PCIe controller" |
| 51 | depends on ARCH_SPEAR13XX | 60 | depends on ARCH_SPEAR13XX |
| 52 | select PCIEPORTBUS | 61 | select PCIEPORTBUS |
| 53 | select PCIE_DW | 62 | select PCIE_DW |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 0daec7941aba..d0e88f114ff9 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | obj-$(CONFIG_PCIE_DW) += pcie-designware.o | 1 | obj-$(CONFIG_PCIE_DW) += pcie-designware.o |
| 2 | obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o | ||
| 2 | obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | 3 | obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o |
| 3 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 4 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
| 4 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o | 5 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o |
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c new file mode 100644 index 000000000000..52b34fee07fd --- /dev/null +++ b/drivers/pci/host/pci-dra7xx.c | |||
| @@ -0,0 +1,458 @@ | |||
| 1 | /* | ||
| 2 | * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Kishon Vijay Abraham I <kishon@ti.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/irq.h> | ||
| 17 | #include <linux/irqdomain.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/pci.h> | ||
| 21 | #include <linux/phy/phy.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/pm_runtime.h> | ||
| 24 | #include <linux/resource.h> | ||
| 25 | #include <linux/types.h> | ||
| 26 | |||
| 27 | #include "pcie-designware.h" | ||
| 28 | |||
| 29 | /* PCIe controller wrapper DRA7XX configuration registers */ | ||
| 30 | |||
| 31 | #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN 0x0024 | ||
| 32 | #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN 0x0028 | ||
| 33 | #define ERR_SYS BIT(0) | ||
| 34 | #define ERR_FATAL BIT(1) | ||
| 35 | #define ERR_NONFATAL BIT(2) | ||
| 36 | #define ERR_COR BIT(3) | ||
| 37 | #define ERR_AXI BIT(4) | ||
| 38 | #define ERR_ECRC BIT(5) | ||
| 39 | #define PME_TURN_OFF BIT(8) | ||
| 40 | #define PME_TO_ACK BIT(9) | ||
| 41 | #define PM_PME BIT(10) | ||
| 42 | #define LINK_REQ_RST BIT(11) | ||
| 43 | #define LINK_UP_EVT BIT(12) | ||
| 44 | #define CFG_BME_EVT BIT(13) | ||
| 45 | #define CFG_MSE_EVT BIT(14) | ||
| 46 | #define INTERRUPTS (ERR_SYS | ERR_FATAL | ERR_NONFATAL | ERR_COR | ERR_AXI | \ | ||
| 47 | ERR_ECRC | PME_TURN_OFF | PME_TO_ACK | PM_PME | \ | ||
| 48 | LINK_REQ_RST | LINK_UP_EVT | CFG_BME_EVT | CFG_MSE_EVT) | ||
| 49 | |||
| 50 | #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI 0x0034 | ||
| 51 | #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI 0x0038 | ||
| 52 | #define INTA BIT(0) | ||
| 53 | #define INTB BIT(1) | ||
| 54 | #define INTC BIT(2) | ||
| 55 | #define INTD BIT(3) | ||
| 56 | #define MSI BIT(4) | ||
| 57 | #define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD) | ||
| 58 | |||
| 59 | #define PCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104 | ||
| 60 | #define LTSSM_EN 0x1 | ||
| 61 | |||
| 62 | #define PCIECTRL_DRA7XX_CONF_PHY_CS 0x010C | ||
| 63 | #define LINK_UP BIT(16) | ||
| 64 | |||
| 65 | struct dra7xx_pcie { | ||
| 66 | void __iomem *base; | ||
| 67 | struct phy **phy; | ||
| 68 | int phy_count; | ||
| 69 | struct device *dev; | ||
| 70 | struct pcie_port pp; | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define to_dra7xx_pcie(x) container_of((x), struct dra7xx_pcie, pp) | ||
| 74 | |||
| 75 | static inline u32 dra7xx_pcie_readl(struct dra7xx_pcie *pcie, u32 offset) | ||
| 76 | { | ||
| 77 | return readl(pcie->base + offset); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset, | ||
| 81 | u32 value) | ||
| 82 | { | ||
| 83 | writel(value, pcie->base + offset); | ||
| 84 | } | ||
| 85 | |||
| 86 | static int dra7xx_pcie_link_up(struct pcie_port *pp) | ||
| 87 | { | ||
| 88 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
| 89 | u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS); | ||
| 90 | |||
| 91 | return !!(reg & LINK_UP); | ||
| 92 | } | ||
| 93 | |||
| 94 | static int dra7xx_pcie_establish_link(struct pcie_port *pp) | ||
| 95 | { | ||
| 96 | u32 reg; | ||
| 97 | unsigned int retries = 1000; | ||
| 98 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
| 99 | |||
| 100 | if (dw_pcie_link_up(pp)) { | ||
| 101 | dev_err(pp->dev, "link is already up\n"); | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); | ||
| 106 | reg |= LTSSM_EN; | ||
| 107 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); | ||
| 108 | |||
| 109 | while (retries--) { | ||
| 110 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS); | ||
| 111 | if (reg & LINK_UP) | ||
| 112 | break; | ||
| 113 | usleep_range(10, 20); | ||
| 114 | } | ||
| 115 | |||
| 116 | if (retries == 0) { | ||
| 117 | dev_err(pp->dev, "link is not up\n"); | ||
| 118 | return -ETIMEDOUT; | ||
| 119 | } | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp) | ||
| 125 | { | ||
| 126 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
| 127 | |||
| 128 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, | ||
| 129 | ~INTERRUPTS); | ||
| 130 | dra7xx_pcie_writel(dra7xx, | ||
| 131 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS); | ||
| 132 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, | ||
| 133 | ~LEG_EP_INTERRUPTS & ~MSI); | ||
| 134 | |||
| 135 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
| 136 | dra7xx_pcie_writel(dra7xx, | ||
| 137 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, MSI); | ||
| 138 | else | ||
| 139 | dra7xx_pcie_writel(dra7xx, | ||
| 140 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, | ||
| 141 | LEG_EP_INTERRUPTS); | ||
| 142 | } | ||
| 143 | |||
| 144 | static void dra7xx_pcie_host_init(struct pcie_port *pp) | ||
| 145 | { | ||
| 146 | dw_pcie_setup_rc(pp); | ||
| 147 | dra7xx_pcie_establish_link(pp); | ||
| 148 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
| 149 | dw_pcie_msi_init(pp); | ||
| 150 | dra7xx_pcie_enable_interrupts(pp); | ||
| 151 | } | ||
| 152 | |||
| 153 | static struct pcie_host_ops dra7xx_pcie_host_ops = { | ||
| 154 | .link_up = dra7xx_pcie_link_up, | ||
| 155 | .host_init = dra7xx_pcie_host_init, | ||
| 156 | }; | ||
| 157 | |||
| 158 | static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | ||
| 159 | irq_hw_number_t hwirq) | ||
| 160 | { | ||
| 161 | irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); | ||
| 162 | irq_set_chip_data(irq, domain->host_data); | ||
| 163 | set_irq_flags(irq, IRQF_VALID); | ||
| 164 | |||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static const struct irq_domain_ops intx_domain_ops = { | ||
| 169 | .map = dra7xx_pcie_intx_map, | ||
| 170 | }; | ||
| 171 | |||
| 172 | static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) | ||
| 173 | { | ||
| 174 | struct device *dev = pp->dev; | ||
| 175 | struct device_node *node = dev->of_node; | ||
| 176 | struct device_node *pcie_intc_node = of_get_next_child(node, NULL); | ||
| 177 | |||
| 178 | if (!pcie_intc_node) { | ||
| 179 | dev_err(dev, "No PCIe Intc node found\n"); | ||
| 180 | return PTR_ERR(pcie_intc_node); | ||
| 181 | } | ||
| 182 | |||
| 183 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | ||
| 184 | &intx_domain_ops, pp); | ||
| 185 | if (!pp->irq_domain) { | ||
| 186 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
| 187 | return PTR_ERR(pp->irq_domain); | ||
| 188 | } | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 193 | static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg) | ||
| 194 | { | ||
| 195 | struct pcie_port *pp = arg; | ||
| 196 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
| 197 | u32 reg; | ||
| 198 | |||
| 199 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI); | ||
| 200 | |||
| 201 | switch (reg) { | ||
| 202 | case MSI: | ||
| 203 | dw_handle_msi_irq(pp); | ||
| 204 | break; | ||
| 205 | case INTA: | ||
| 206 | case INTB: | ||
| 207 | case INTC: | ||
| 208 | case INTD: | ||
| 209 | generic_handle_irq(irq_find_mapping(pp->irq_domain, ffs(reg))); | ||
| 210 | break; | ||
| 211 | } | ||
| 212 | |||
| 213 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg); | ||
| 214 | |||
| 215 | return IRQ_HANDLED; | ||
| 216 | } | ||
| 217 | |||
| 218 | |||
| 219 | static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) | ||
| 220 | { | ||
| 221 | struct dra7xx_pcie *dra7xx = arg; | ||
| 222 | u32 reg; | ||
| 223 | |||
| 224 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN); | ||
| 225 | |||
| 226 | if (reg & ERR_SYS) | ||
| 227 | dev_dbg(dra7xx->dev, "System Error\n"); | ||
| 228 | |||
| 229 | if (reg & ERR_FATAL) | ||
| 230 | dev_dbg(dra7xx->dev, "Fatal Error\n"); | ||
| 231 | |||
| 232 | if (reg & ERR_NONFATAL) | ||
| 233 | dev_dbg(dra7xx->dev, "Non Fatal Error\n"); | ||
| 234 | |||
| 235 | if (reg & ERR_COR) | ||
| 236 | dev_dbg(dra7xx->dev, "Correctable Error\n"); | ||
| 237 | |||
| 238 | if (reg & ERR_AXI) | ||
| 239 | dev_dbg(dra7xx->dev, "AXI tag lookup fatal Error\n"); | ||
| 240 | |||
| 241 | if (reg & ERR_ECRC) | ||
| 242 | dev_dbg(dra7xx->dev, "ECRC Error\n"); | ||
| 243 | |||
| 244 | if (reg & PME_TURN_OFF) | ||
| 245 | dev_dbg(dra7xx->dev, | ||
| 246 | "Power Management Event Turn-Off message received\n"); | ||
| 247 | |||
| 248 | if (reg & PME_TO_ACK) | ||
| 249 | dev_dbg(dra7xx->dev, | ||
| 250 | "Power Management Turn-Off Ack message received\n"); | ||
| 251 | |||
| 252 | if (reg & PM_PME) | ||
| 253 | dev_dbg(dra7xx->dev, | ||
| 254 | "PM Power Management Event message received\n"); | ||
| 255 | |||
| 256 | if (reg & LINK_REQ_RST) | ||
| 257 | dev_dbg(dra7xx->dev, "Link Request Reset\n"); | ||
| 258 | |||
| 259 | if (reg & LINK_UP_EVT) | ||
| 260 | dev_dbg(dra7xx->dev, "Link-up state change\n"); | ||
| 261 | |||
| 262 | if (reg & CFG_BME_EVT) | ||
| 263 | dev_dbg(dra7xx->dev, "CFG 'Bus Master Enable' change\n"); | ||
| 264 | |||
| 265 | if (reg & CFG_MSE_EVT) | ||
| 266 | dev_dbg(dra7xx->dev, "CFG 'Memory Space Enable' change\n"); | ||
| 267 | |||
| 268 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, reg); | ||
| 269 | |||
| 270 | return IRQ_HANDLED; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int add_pcie_port(struct dra7xx_pcie *dra7xx, | ||
| 274 | struct platform_device *pdev) | ||
| 275 | { | ||
| 276 | int ret; | ||
| 277 | struct pcie_port *pp; | ||
| 278 | struct resource *res; | ||
| 279 | struct device *dev = &pdev->dev; | ||
| 280 | |||
| 281 | pp = &dra7xx->pp; | ||
| 282 | pp->dev = dev; | ||
| 283 | pp->ops = &dra7xx_pcie_host_ops; | ||
| 284 | |||
| 285 | pp->irq = platform_get_irq(pdev, 1); | ||
| 286 | if (pp->irq < 0) { | ||
| 287 | dev_err(dev, "missing IRQ resource\n"); | ||
| 288 | return -EINVAL; | ||
| 289 | } | ||
| 290 | |||
| 291 | ret = devm_request_irq(&pdev->dev, pp->irq, | ||
| 292 | dra7xx_pcie_msi_irq_handler, IRQF_SHARED, | ||
| 293 | "dra7-pcie-msi", pp); | ||
| 294 | if (ret) { | ||
| 295 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
| 296 | return ret; | ||
| 297 | } | ||
| 298 | |||
| 299 | if (!IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 300 | ret = dra7xx_pcie_init_irq_domain(pp); | ||
| 301 | if (ret < 0) | ||
| 302 | return ret; | ||
| 303 | } | ||
| 304 | |||
| 305 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics"); | ||
| 306 | pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res)); | ||
| 307 | if (!pp->dbi_base) | ||
| 308 | return -ENOMEM; | ||
| 309 | |||
| 310 | ret = dw_pcie_host_init(pp); | ||
| 311 | if (ret) { | ||
| 312 | dev_err(dra7xx->dev, "failed to initialize host\n"); | ||
| 313 | return ret; | ||
| 314 | } | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) | ||
| 320 | { | ||
| 321 | u32 reg; | ||
| 322 | int ret; | ||
| 323 | int irq; | ||
| 324 | int i; | ||
| 325 | int phy_count; | ||
| 326 | struct phy **phy; | ||
| 327 | void __iomem *base; | ||
| 328 | struct resource *res; | ||
| 329 | struct dra7xx_pcie *dra7xx; | ||
| 330 | struct device *dev = &pdev->dev; | ||
| 331 | struct device_node *np = dev->of_node; | ||
| 332 | char name[10]; | ||
| 333 | |||
| 334 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); | ||
| 335 | if (!dra7xx) | ||
| 336 | return -ENOMEM; | ||
| 337 | |||
| 338 | irq = platform_get_irq(pdev, 0); | ||
| 339 | if (irq < 0) { | ||
| 340 | dev_err(dev, "missing IRQ resource\n"); | ||
| 341 | return -EINVAL; | ||
| 342 | } | ||
| 343 | |||
| 344 | ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, | ||
| 345 | IRQF_SHARED, "dra7xx-pcie-main", dra7xx); | ||
| 346 | if (ret) { | ||
| 347 | dev_err(dev, "failed to request irq\n"); | ||
| 348 | return ret; | ||
| 349 | } | ||
| 350 | |||
| 351 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); | ||
| 352 | base = devm_ioremap_nocache(dev, res->start, resource_size(res)); | ||
| 353 | if (!base) | ||
| 354 | return -ENOMEM; | ||
| 355 | |||
| 356 | phy_count = of_property_count_strings(np, "phy-names"); | ||
| 357 | if (phy_count < 0) { | ||
| 358 | dev_err(dev, "unable to find the strings\n"); | ||
| 359 | return phy_count; | ||
| 360 | } | ||
| 361 | |||
| 362 | phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); | ||
| 363 | if (!phy) | ||
| 364 | return -ENOMEM; | ||
| 365 | |||
| 366 | for (i = 0; i < phy_count; i++) { | ||
| 367 | snprintf(name, sizeof(name), "pcie-phy%d", i); | ||
| 368 | phy[i] = devm_phy_get(dev, name); | ||
| 369 | if (IS_ERR(phy[i])) | ||
| 370 | return PTR_ERR(phy[i]); | ||
| 371 | |||
| 372 | ret = phy_init(phy[i]); | ||
| 373 | if (ret < 0) | ||
| 374 | goto err_phy; | ||
| 375 | |||
| 376 | ret = phy_power_on(phy[i]); | ||
| 377 | if (ret < 0) { | ||
| 378 | phy_exit(phy[i]); | ||
| 379 | goto err_phy; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | dra7xx->base = base; | ||
| 384 | dra7xx->phy = phy; | ||
| 385 | dra7xx->dev = dev; | ||
| 386 | dra7xx->phy_count = phy_count; | ||
| 387 | |||
| 388 | pm_runtime_enable(dev); | ||
| 389 | ret = pm_runtime_get_sync(dev); | ||
| 390 | if (IS_ERR_VALUE(ret)) { | ||
| 391 | dev_err(dev, "pm_runtime_get_sync failed\n"); | ||
| 392 | goto err_phy; | ||
| 393 | } | ||
| 394 | |||
| 395 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); | ||
| 396 | reg &= ~LTSSM_EN; | ||
| 397 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); | ||
| 398 | |||
| 399 | platform_set_drvdata(pdev, dra7xx); | ||
| 400 | |||
| 401 | ret = add_pcie_port(dra7xx, pdev); | ||
| 402 | if (ret < 0) | ||
| 403 | goto err_add_port; | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | |||
| 407 | err_add_port: | ||
| 408 | pm_runtime_put(dev); | ||
| 409 | pm_runtime_disable(dev); | ||
| 410 | |||
| 411 | err_phy: | ||
| 412 | while (--i >= 0) { | ||
| 413 | phy_power_off(phy[i]); | ||
| 414 | phy_exit(phy[i]); | ||
| 415 | } | ||
| 416 | |||
| 417 | return ret; | ||
| 418 | } | ||
| 419 | |||
| 420 | static int __exit dra7xx_pcie_remove(struct platform_device *pdev) | ||
| 421 | { | ||
| 422 | struct dra7xx_pcie *dra7xx = platform_get_drvdata(pdev); | ||
| 423 | struct pcie_port *pp = &dra7xx->pp; | ||
| 424 | struct device *dev = &pdev->dev; | ||
| 425 | int count = dra7xx->phy_count; | ||
| 426 | |||
| 427 | if (pp->irq_domain) | ||
| 428 | irq_domain_remove(pp->irq_domain); | ||
| 429 | pm_runtime_put(dev); | ||
| 430 | pm_runtime_disable(dev); | ||
| 431 | while (count--) { | ||
| 432 | phy_power_off(dra7xx->phy[count]); | ||
| 433 | phy_exit(dra7xx->phy[count]); | ||
| 434 | } | ||
| 435 | |||
| 436 | return 0; | ||
| 437 | } | ||
| 438 | |||
| 439 | static const struct of_device_id of_dra7xx_pcie_match[] = { | ||
| 440 | { .compatible = "ti,dra7-pcie", }, | ||
| 441 | {}, | ||
| 442 | }; | ||
| 443 | MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match); | ||
| 444 | |||
| 445 | static struct platform_driver dra7xx_pcie_driver = { | ||
| 446 | .remove = __exit_p(dra7xx_pcie_remove), | ||
| 447 | .driver = { | ||
| 448 | .name = "dra7-pcie", | ||
| 449 | .owner = THIS_MODULE, | ||
| 450 | .of_match_table = of_dra7xx_pcie_match, | ||
| 451 | }, | ||
| 452 | }; | ||
| 453 | |||
| 454 | module_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe); | ||
| 455 | |||
| 456 | MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); | ||
| 457 | MODULE_DESCRIPTION("TI PCIe controller driver"); | ||
| 458 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index abd65784618d..0fb0fdb223d5 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
| 28 | #include <linux/debugfs.h> | ||
| 28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 29 | #include <linux/export.h> | 30 | #include <linux/export.h> |
| 30 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
| @@ -276,6 +277,7 @@ struct tegra_pcie { | |||
| 276 | unsigned int num_supplies; | 277 | unsigned int num_supplies; |
| 277 | 278 | ||
| 278 | const struct tegra_pcie_soc_data *soc_data; | 279 | const struct tegra_pcie_soc_data *soc_data; |
| 280 | struct dentry *debugfs; | ||
| 279 | }; | 281 | }; |
| 280 | 282 | ||
| 281 | struct tegra_pcie_port { | 283 | struct tegra_pcie_port { |
| @@ -1739,6 +1741,115 @@ static const struct of_device_id tegra_pcie_of_match[] = { | |||
| 1739 | }; | 1741 | }; |
| 1740 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); | 1742 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); |
| 1741 | 1743 | ||
| 1744 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) | ||
| 1745 | { | ||
| 1746 | struct tegra_pcie *pcie = s->private; | ||
| 1747 | |||
| 1748 | if (list_empty(&pcie->ports)) | ||
| 1749 | return NULL; | ||
| 1750 | |||
| 1751 | seq_printf(s, "Index Status\n"); | ||
| 1752 | |||
| 1753 | return seq_list_start(&pcie->ports, *pos); | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | static void *tegra_pcie_ports_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
| 1757 | { | ||
| 1758 | struct tegra_pcie *pcie = s->private; | ||
| 1759 | |||
| 1760 | return seq_list_next(v, &pcie->ports, pos); | ||
| 1761 | } | ||
| 1762 | |||
| 1763 | static void tegra_pcie_ports_seq_stop(struct seq_file *s, void *v) | ||
| 1764 | { | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | static int tegra_pcie_ports_seq_show(struct seq_file *s, void *v) | ||
| 1768 | { | ||
| 1769 | bool up = false, active = false; | ||
| 1770 | struct tegra_pcie_port *port; | ||
| 1771 | unsigned int value; | ||
| 1772 | |||
| 1773 | port = list_entry(v, struct tegra_pcie_port, list); | ||
| 1774 | |||
| 1775 | value = readl(port->base + RP_VEND_XP); | ||
| 1776 | |||
| 1777 | if (value & RP_VEND_XP_DL_UP) | ||
| 1778 | up = true; | ||
| 1779 | |||
| 1780 | value = readl(port->base + RP_LINK_CONTROL_STATUS); | ||
| 1781 | |||
| 1782 | if (value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE) | ||
| 1783 | active = true; | ||
| 1784 | |||
| 1785 | seq_printf(s, "%2u ", port->index); | ||
| 1786 | |||
| 1787 | if (up) | ||
| 1788 | seq_printf(s, "up"); | ||
| 1789 | |||
| 1790 | if (active) { | ||
| 1791 | if (up) | ||
| 1792 | seq_printf(s, ", "); | ||
| 1793 | |||
| 1794 | seq_printf(s, "active"); | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | seq_printf(s, "\n"); | ||
| 1798 | return 0; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | static const struct seq_operations tegra_pcie_ports_seq_ops = { | ||
| 1802 | .start = tegra_pcie_ports_seq_start, | ||
| 1803 | .next = tegra_pcie_ports_seq_next, | ||
| 1804 | .stop = tegra_pcie_ports_seq_stop, | ||
| 1805 | .show = tegra_pcie_ports_seq_show, | ||
| 1806 | }; | ||
| 1807 | |||
| 1808 | static int tegra_pcie_ports_open(struct inode *inode, struct file *file) | ||
| 1809 | { | ||
| 1810 | struct tegra_pcie *pcie = inode->i_private; | ||
| 1811 | struct seq_file *s; | ||
| 1812 | int err; | ||
| 1813 | |||
| 1814 | err = seq_open(file, &tegra_pcie_ports_seq_ops); | ||
| 1815 | if (err) | ||
| 1816 | return err; | ||
| 1817 | |||
| 1818 | s = file->private_data; | ||
| 1819 | s->private = pcie; | ||
| 1820 | |||
| 1821 | return 0; | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | static const struct file_operations tegra_pcie_ports_ops = { | ||
| 1825 | .owner = THIS_MODULE, | ||
| 1826 | .open = tegra_pcie_ports_open, | ||
| 1827 | .read = seq_read, | ||
| 1828 | .llseek = seq_lseek, | ||
| 1829 | .release = seq_release, | ||
| 1830 | }; | ||
| 1831 | |||
| 1832 | static int tegra_pcie_debugfs_init(struct tegra_pcie *pcie) | ||
| 1833 | { | ||
| 1834 | struct dentry *file; | ||
| 1835 | |||
| 1836 | pcie->debugfs = debugfs_create_dir("pcie", NULL); | ||
| 1837 | if (!pcie->debugfs) | ||
| 1838 | return -ENOMEM; | ||
| 1839 | |||
| 1840 | file = debugfs_create_file("ports", S_IFREG | S_IRUGO, pcie->debugfs, | ||
| 1841 | pcie, &tegra_pcie_ports_ops); | ||
| 1842 | if (!file) | ||
| 1843 | goto remove; | ||
| 1844 | |||
| 1845 | return 0; | ||
| 1846 | |||
| 1847 | remove: | ||
| 1848 | debugfs_remove_recursive(pcie->debugfs); | ||
| 1849 | pcie->debugfs = NULL; | ||
| 1850 | return -ENOMEM; | ||
| 1851 | } | ||
| 1852 | |||
| 1742 | static int tegra_pcie_probe(struct platform_device *pdev) | 1853 | static int tegra_pcie_probe(struct platform_device *pdev) |
| 1743 | { | 1854 | { |
| 1744 | const struct of_device_id *match; | 1855 | const struct of_device_id *match; |
| @@ -1793,6 +1904,13 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
| 1793 | goto disable_msi; | 1904 | goto disable_msi; |
| 1794 | } | 1905 | } |
| 1795 | 1906 | ||
| 1907 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | ||
| 1908 | err = tegra_pcie_debugfs_init(pcie); | ||
| 1909 | if (err < 0) | ||
| 1910 | dev_err(&pdev->dev, "failed to setup debugfs: %d\n", | ||
| 1911 | err); | ||
| 1912 | } | ||
| 1913 | |||
| 1796 | platform_set_drvdata(pdev, pcie); | 1914 | platform_set_drvdata(pdev, pcie); |
| 1797 | return 0; | 1915 | return 0; |
| 1798 | 1916 | ||
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 1eaf4df3618a..52bd3a143563 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
| 21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 22 | #include <linux/pci_regs.h> | 22 | #include <linux/pci_regs.h> |
| 23 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| 24 | 25 | ||
| 25 | #include "pcie-designware.h" | 26 | #include "pcie-designware.h" |
| @@ -217,27 +218,47 @@ static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0) | |||
| 217 | return 0; | 218 | return 0; |
| 218 | } | 219 | } |
| 219 | 220 | ||
| 221 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | ||
| 222 | { | ||
| 223 | unsigned int res, bit, val; | ||
| 224 | |||
| 225 | res = (irq / 32) * 12; | ||
| 226 | bit = irq % 32; | ||
| 227 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | ||
| 228 | val &= ~(1 << bit); | ||
| 229 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
| 230 | } | ||
| 231 | |||
| 220 | static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, | 232 | static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, |
| 221 | unsigned int nvec, unsigned int pos) | 233 | unsigned int nvec, unsigned int pos) |
| 222 | { | 234 | { |
| 223 | unsigned int i, res, bit, val; | 235 | unsigned int i; |
| 224 | 236 | ||
| 225 | for (i = 0; i < nvec; i++) { | 237 | for (i = 0; i < nvec; i++) { |
| 226 | irq_set_msi_desc_off(irq_base, i, NULL); | 238 | irq_set_msi_desc_off(irq_base, i, NULL); |
| 227 | clear_bit(pos + i, pp->msi_irq_in_use); | 239 | clear_bit(pos + i, pp->msi_irq_in_use); |
| 228 | /* Disable corresponding interrupt on MSI controller */ | 240 | /* Disable corresponding interrupt on MSI controller */ |
| 229 | res = ((pos + i) / 32) * 12; | 241 | if (pp->ops->msi_clear_irq) |
| 230 | bit = (pos + i) % 32; | 242 | pp->ops->msi_clear_irq(pp, pos + i); |
| 231 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | 243 | else |
| 232 | val &= ~(1 << bit); | 244 | dw_pcie_msi_clear_irq(pp, pos + i); |
| 233 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
| 234 | } | 245 | } |
| 235 | } | 246 | } |
| 236 | 247 | ||
| 248 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | ||
| 249 | { | ||
| 250 | unsigned int res, bit, val; | ||
| 251 | |||
| 252 | res = (irq / 32) * 12; | ||
| 253 | bit = irq % 32; | ||
| 254 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | ||
| 255 | val |= 1 << bit; | ||
| 256 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
| 257 | } | ||
| 258 | |||
| 237 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | 259 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) |
| 238 | { | 260 | { |
| 239 | int res, bit, irq, pos0, pos1, i; | 261 | int irq, pos0, pos1, i; |
| 240 | u32 val; | ||
| 241 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); | 262 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); |
| 242 | 263 | ||
| 243 | if (!pp) { | 264 | if (!pp) { |
| @@ -281,11 +302,10 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | |||
| 281 | } | 302 | } |
| 282 | set_bit(pos0 + i, pp->msi_irq_in_use); | 303 | set_bit(pos0 + i, pp->msi_irq_in_use); |
| 283 | /*Enable corresponding interrupt in MSI interrupt controller */ | 304 | /*Enable corresponding interrupt in MSI interrupt controller */ |
| 284 | res = ((pos0 + i) / 32) * 12; | 305 | if (pp->ops->msi_set_irq) |
| 285 | bit = (pos0 + i) % 32; | 306 | pp->ops->msi_set_irq(pp, pos0 + i); |
| 286 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | 307 | else |
| 287 | val |= 1 << bit; | 308 | dw_pcie_msi_set_irq(pp, pos0 + i); |
| 288 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
| 289 | } | 309 | } |
| 290 | 310 | ||
| 291 | *pos = pos0; | 311 | *pos = pos0; |
| @@ -353,7 +373,10 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, | |||
| 353 | */ | 373 | */ |
| 354 | desc->msi_attrib.multiple = msgvec; | 374 | desc->msi_attrib.multiple = msgvec; |
| 355 | 375 | ||
| 356 | msg.address_lo = virt_to_phys((void *)pp->msi_data); | 376 | if (pp->ops->get_msi_data) |
| 377 | msg.address_lo = pp->ops->get_msi_data(pp); | ||
| 378 | else | ||
| 379 | msg.address_lo = virt_to_phys((void *)pp->msi_data); | ||
| 357 | msg.address_hi = 0x0; | 380 | msg.address_hi = 0x0; |
| 358 | msg.data = pos; | 381 | msg.data = pos; |
| 359 | write_msi_msg(irq, &msg); | 382 | write_msi_msg(irq, &msg); |
| @@ -396,10 +419,35 @@ static const struct irq_domain_ops msi_domain_ops = { | |||
| 396 | int __init dw_pcie_host_init(struct pcie_port *pp) | 419 | int __init dw_pcie_host_init(struct pcie_port *pp) |
| 397 | { | 420 | { |
| 398 | struct device_node *np = pp->dev->of_node; | 421 | struct device_node *np = pp->dev->of_node; |
| 422 | struct platform_device *pdev = to_platform_device(pp->dev); | ||
| 399 | struct of_pci_range range; | 423 | struct of_pci_range range; |
| 400 | struct of_pci_range_parser parser; | 424 | struct of_pci_range_parser parser; |
| 401 | u32 val; | 425 | struct resource *cfg_res; |
| 402 | int i; | 426 | u32 val, na, ns; |
| 427 | const __be32 *addrp; | ||
| 428 | int i, index; | ||
| 429 | |||
| 430 | /* Find the address cell size and the number of cells in order to get | ||
| 431 | * the untranslated address. | ||
| 432 | */ | ||
| 433 | of_property_read_u32(np, "#address-cells", &na); | ||
| 434 | ns = of_n_size_cells(np); | ||
| 435 | |||
| 436 | cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); | ||
| 437 | if (cfg_res) { | ||
| 438 | pp->config.cfg0_size = resource_size(cfg_res)/2; | ||
| 439 | pp->config.cfg1_size = resource_size(cfg_res)/2; | ||
| 440 | pp->cfg0_base = cfg_res->start; | ||
| 441 | pp->cfg1_base = cfg_res->start + pp->config.cfg0_size; | ||
| 442 | |||
| 443 | /* Find the untranslated configuration space address */ | ||
| 444 | index = of_property_match_string(np, "reg-names", "config"); | ||
| 445 | addrp = of_get_address(np, index, false, false); | ||
| 446 | pp->cfg0_mod_base = of_read_number(addrp, ns); | ||
| 447 | pp->cfg1_mod_base = pp->cfg0_mod_base + pp->config.cfg0_size; | ||
| 448 | } else { | ||
| 449 | dev_err(pp->dev, "missing *config* reg space\n"); | ||
| 450 | } | ||
| 403 | 451 | ||
| 404 | if (of_pci_range_parser_init(&parser, np)) { | 452 | if (of_pci_range_parser_init(&parser, np)) { |
| 405 | dev_err(pp->dev, "missing ranges property\n"); | 453 | dev_err(pp->dev, "missing ranges property\n"); |
| @@ -422,17 +470,33 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 422 | pp->config.io_size = resource_size(&pp->io); | 470 | pp->config.io_size = resource_size(&pp->io); |
| 423 | pp->config.io_bus_addr = range.pci_addr; | 471 | pp->config.io_bus_addr = range.pci_addr; |
| 424 | pp->io_base = range.cpu_addr; | 472 | pp->io_base = range.cpu_addr; |
| 473 | |||
| 474 | /* Find the untranslated IO space address */ | ||
| 475 | pp->io_mod_base = of_read_number(parser.range - | ||
| 476 | parser.np + na, ns); | ||
| 425 | } | 477 | } |
| 426 | if (restype == IORESOURCE_MEM) { | 478 | if (restype == IORESOURCE_MEM) { |
| 427 | of_pci_range_to_resource(&range, np, &pp->mem); | 479 | of_pci_range_to_resource(&range, np, &pp->mem); |
| 428 | pp->mem.name = "MEM"; | 480 | pp->mem.name = "MEM"; |
| 429 | pp->config.mem_size = resource_size(&pp->mem); | 481 | pp->config.mem_size = resource_size(&pp->mem); |
| 430 | pp->config.mem_bus_addr = range.pci_addr; | 482 | pp->config.mem_bus_addr = range.pci_addr; |
| 483 | |||
| 484 | /* Find the untranslated MEM space address */ | ||
| 485 | pp->mem_mod_base = of_read_number(parser.range - | ||
| 486 | parser.np + na, ns); | ||
| 431 | } | 487 | } |
| 432 | if (restype == 0) { | 488 | if (restype == 0) { |
| 433 | of_pci_range_to_resource(&range, np, &pp->cfg); | 489 | of_pci_range_to_resource(&range, np, &pp->cfg); |
| 434 | pp->config.cfg0_size = resource_size(&pp->cfg)/2; | 490 | pp->config.cfg0_size = resource_size(&pp->cfg)/2; |
| 435 | pp->config.cfg1_size = resource_size(&pp->cfg)/2; | 491 | pp->config.cfg1_size = resource_size(&pp->cfg)/2; |
| 492 | pp->cfg0_base = pp->cfg.start; | ||
| 493 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; | ||
| 494 | |||
| 495 | /* Find the untranslated configuration space address */ | ||
| 496 | pp->cfg0_mod_base = of_read_number(parser.range - | ||
| 497 | parser.np + na, ns); | ||
| 498 | pp->cfg1_mod_base = pp->cfg0_mod_base + | ||
| 499 | pp->config.cfg0_size; | ||
| 436 | } | 500 | } |
| 437 | } | 501 | } |
| 438 | 502 | ||
| @@ -445,8 +509,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 445 | } | 509 | } |
| 446 | } | 510 | } |
| 447 | 511 | ||
| 448 | pp->cfg0_base = pp->cfg.start; | ||
| 449 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; | ||
| 450 | pp->mem_base = pp->mem.start; | 512 | pp->mem_base = pp->mem.start; |
| 451 | 513 | ||
| 452 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, | 514 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, |
| @@ -509,9 +571,9 @@ static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev) | |||
| 509 | /* Program viewport 0 : OUTBOUND : CFG0 */ | 571 | /* Program viewport 0 : OUTBOUND : CFG0 */ |
| 510 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, | 572 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, |
| 511 | PCIE_ATU_VIEWPORT); | 573 | PCIE_ATU_VIEWPORT); |
| 512 | dw_pcie_writel_rc(pp, pp->cfg0_base, PCIE_ATU_LOWER_BASE); | 574 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE); |
| 513 | dw_pcie_writel_rc(pp, (pp->cfg0_base >> 32), PCIE_ATU_UPPER_BASE); | 575 | dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 514 | dw_pcie_writel_rc(pp, pp->cfg0_base + pp->config.cfg0_size - 1, | 576 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->config.cfg0_size - 1, |
| 515 | PCIE_ATU_LIMIT); | 577 | PCIE_ATU_LIMIT); |
| 516 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 578 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
| 517 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 579 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
| @@ -525,9 +587,9 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) | |||
| 525 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, | 587 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, |
| 526 | PCIE_ATU_VIEWPORT); | 588 | PCIE_ATU_VIEWPORT); |
| 527 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); | 589 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); |
| 528 | dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE); | 590 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE); |
| 529 | dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE); | 591 | dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 530 | dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1, | 592 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->config.cfg1_size - 1, |
| 531 | PCIE_ATU_LIMIT); | 593 | PCIE_ATU_LIMIT); |
| 532 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 594 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
| 533 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 595 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
| @@ -540,9 +602,9 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) | |||
| 540 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, | 602 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, |
| 541 | PCIE_ATU_VIEWPORT); | 603 | PCIE_ATU_VIEWPORT); |
| 542 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); | 604 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); |
| 543 | dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE); | 605 | dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE); |
| 544 | dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE); | 606 | dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 545 | dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1, | 607 | dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->config.mem_size - 1, |
| 546 | PCIE_ATU_LIMIT); | 608 | PCIE_ATU_LIMIT); |
| 547 | dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); | 609 | dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); |
| 548 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), | 610 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), |
| @@ -556,9 +618,9 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) | |||
| 556 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, | 618 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, |
| 557 | PCIE_ATU_VIEWPORT); | 619 | PCIE_ATU_VIEWPORT); |
| 558 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); | 620 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); |
| 559 | dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE); | 621 | dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE); |
| 560 | dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE); | 622 | dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 561 | dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1, | 623 | dw_pcie_writel_rc(pp, pp->io_mod_base + pp->config.io_size - 1, |
| 562 | PCIE_ATU_LIMIT); | 624 | PCIE_ATU_LIMIT); |
| 563 | dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); | 625 | dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); |
| 564 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), | 626 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), |
| @@ -656,7 +718,11 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, | |||
| 656 | } | 718 | } |
| 657 | 719 | ||
| 658 | if (bus->number != pp->root_bus_nr) | 720 | if (bus->number != pp->root_bus_nr) |
| 659 | ret = dw_pcie_rd_other_conf(pp, bus, devfn, | 721 | if (pp->ops->rd_other_conf) |
| 722 | ret = pp->ops->rd_other_conf(pp, bus, devfn, | ||
| 723 | where, size, val); | ||
| 724 | else | ||
| 725 | ret = dw_pcie_rd_other_conf(pp, bus, devfn, | ||
| 660 | where, size, val); | 726 | where, size, val); |
| 661 | else | 727 | else |
| 662 | ret = dw_pcie_rd_own_conf(pp, where, size, val); | 728 | ret = dw_pcie_rd_own_conf(pp, where, size, val); |
| @@ -679,7 +745,11 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | |||
| 679 | return PCIBIOS_DEVICE_NOT_FOUND; | 745 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 680 | 746 | ||
| 681 | if (bus->number != pp->root_bus_nr) | 747 | if (bus->number != pp->root_bus_nr) |
| 682 | ret = dw_pcie_wr_other_conf(pp, bus, devfn, | 748 | if (pp->ops->wr_other_conf) |
| 749 | ret = pp->ops->wr_other_conf(pp, bus, devfn, | ||
| 750 | where, size, val); | ||
| 751 | else | ||
| 752 | ret = dw_pcie_wr_other_conf(pp, bus, devfn, | ||
| 683 | where, size, val); | 753 | where, size, val); |
| 684 | else | 754 | else |
| 685 | ret = dw_pcie_wr_own_conf(pp, where, size, val); | 755 | ret = dw_pcie_wr_own_conf(pp, where, size, val); |
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index 77f592faa7bf..daf81f922cda 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h | |||
| @@ -36,11 +36,15 @@ struct pcie_port { | |||
| 36 | u8 root_bus_nr; | 36 | u8 root_bus_nr; |
| 37 | void __iomem *dbi_base; | 37 | void __iomem *dbi_base; |
| 38 | u64 cfg0_base; | 38 | u64 cfg0_base; |
| 39 | u64 cfg0_mod_base; | ||
| 39 | void __iomem *va_cfg0_base; | 40 | void __iomem *va_cfg0_base; |
| 40 | u64 cfg1_base; | 41 | u64 cfg1_base; |
| 42 | u64 cfg1_mod_base; | ||
| 41 | void __iomem *va_cfg1_base; | 43 | void __iomem *va_cfg1_base; |
| 42 | u64 io_base; | 44 | u64 io_base; |
| 45 | u64 io_mod_base; | ||
| 43 | u64 mem_base; | 46 | u64 mem_base; |
| 47 | u64 mem_mod_base; | ||
| 44 | struct resource cfg; | 48 | struct resource cfg; |
| 45 | struct resource io; | 49 | struct resource io; |
| 46 | struct resource mem; | 50 | struct resource mem; |
| @@ -61,8 +65,15 @@ struct pcie_host_ops { | |||
| 61 | u32 val, void __iomem *dbi_base); | 65 | u32 val, void __iomem *dbi_base); |
| 62 | int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val); | 66 | int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val); |
| 63 | int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val); | 67 | int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val); |
| 68 | int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | ||
| 69 | unsigned int devfn, int where, int size, u32 *val); | ||
| 70 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | ||
| 71 | unsigned int devfn, int where, int size, u32 val); | ||
| 64 | int (*link_up)(struct pcie_port *pp); | 72 | int (*link_up)(struct pcie_port *pp); |
| 65 | void (*host_init)(struct pcie_port *pp); | 73 | void (*host_init)(struct pcie_port *pp); |
| 74 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | ||
| 75 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | ||
| 76 | u32 (*get_msi_data)(struct pcie_port *pp); | ||
| 66 | }; | 77 | }; |
| 67 | 78 | ||
| 68 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); | 79 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 0dd742719154..4ff8cbb620d3 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
| @@ -41,9 +41,9 @@ config PHY_MVEBU_SATA | |||
| 41 | config PHY_MIPHY365X | 41 | config PHY_MIPHY365X |
| 42 | tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" | 42 | tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" |
| 43 | depends on ARCH_STI | 43 | depends on ARCH_STI |
| 44 | depends on GENERIC_PHY | ||
| 45 | depends on HAS_IOMEM | 44 | depends on HAS_IOMEM |
| 46 | depends on OF | 45 | depends on OF |
| 46 | select GENERIC_PHY | ||
| 47 | help | 47 | help |
| 48 | Enable this to support the miphy transceiver (for SATA/PCIE) | 48 | Enable this to support the miphy transceiver (for SATA/PCIE) |
| 49 | that is part of STMicroelectronics STiH41x SoC series. | 49 | that is part of STMicroelectronics STiH41x SoC series. |
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index b05302b09c9f..392101c8d6b0 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c | |||
| @@ -542,6 +542,7 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { | |||
| 542 | }, | 542 | }, |
| 543 | { }, | 543 | { }, |
| 544 | }; | 544 | }; |
| 545 | MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match); | ||
| 545 | 546 | ||
| 546 | static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) | 547 | static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) |
| 547 | { | 548 | { |
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index e1a6623d4696..9cd33a4bcfb1 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 35 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
| 36 | #include <linux/phy/phy.h> | 36 | #include <linux/phy/phy.h> |
| 37 | #include <linux/pm_runtime.h> | ||
| 37 | #include <linux/usb/musb-omap.h> | 38 | #include <linux/usb/musb-omap.h> |
| 38 | #include <linux/usb/ulpi.h> | 39 | #include <linux/usb/ulpi.h> |
| 39 | #include <linux/i2c/twl.h> | 40 | #include <linux/i2c/twl.h> |
| @@ -422,37 +423,55 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
| 422 | } | 423 | } |
| 423 | } | 424 | } |
| 424 | 425 | ||
| 425 | static int twl4030_phy_power_off(struct phy *phy) | 426 | static int twl4030_usb_runtime_suspend(struct device *dev) |
| 426 | { | 427 | { |
| 427 | struct twl4030_usb *twl = phy_get_drvdata(phy); | 428 | struct twl4030_usb *twl = dev_get_drvdata(dev); |
| 428 | 429 | ||
| 430 | dev_dbg(twl->dev, "%s\n", __func__); | ||
| 429 | if (twl->asleep) | 431 | if (twl->asleep) |
| 430 | return 0; | 432 | return 0; |
| 431 | 433 | ||
| 432 | twl4030_phy_power(twl, 0); | 434 | twl4030_phy_power(twl, 0); |
| 433 | twl->asleep = 1; | 435 | twl->asleep = 1; |
| 434 | dev_dbg(twl->dev, "%s\n", __func__); | 436 | |
| 435 | return 0; | 437 | return 0; |
| 436 | } | 438 | } |
| 437 | 439 | ||
| 438 | static void __twl4030_phy_power_on(struct twl4030_usb *twl) | 440 | static int twl4030_usb_runtime_resume(struct device *dev) |
| 439 | { | 441 | { |
| 442 | struct twl4030_usb *twl = dev_get_drvdata(dev); | ||
| 443 | |||
| 444 | dev_dbg(twl->dev, "%s\n", __func__); | ||
| 445 | if (!twl->asleep) | ||
| 446 | return 0; | ||
| 447 | |||
| 440 | twl4030_phy_power(twl, 1); | 448 | twl4030_phy_power(twl, 1); |
| 441 | twl4030_i2c_access(twl, 1); | 449 | twl->asleep = 0; |
| 442 | twl4030_usb_set_mode(twl, twl->usb_mode); | 450 | |
| 443 | if (twl->usb_mode == T2_USB_MODE_ULPI) | 451 | return 0; |
| 444 | twl4030_i2c_access(twl, 0); | 452 | } |
| 453 | |||
| 454 | static int twl4030_phy_power_off(struct phy *phy) | ||
| 455 | { | ||
| 456 | struct twl4030_usb *twl = phy_get_drvdata(phy); | ||
| 457 | |||
| 458 | dev_dbg(twl->dev, "%s\n", __func__); | ||
| 459 | pm_runtime_mark_last_busy(twl->dev); | ||
| 460 | pm_runtime_put_autosuspend(twl->dev); | ||
| 461 | |||
| 462 | return 0; | ||
| 445 | } | 463 | } |
| 446 | 464 | ||
| 447 | static int twl4030_phy_power_on(struct phy *phy) | 465 | static int twl4030_phy_power_on(struct phy *phy) |
| 448 | { | 466 | { |
| 449 | struct twl4030_usb *twl = phy_get_drvdata(phy); | 467 | struct twl4030_usb *twl = phy_get_drvdata(phy); |
| 450 | 468 | ||
| 451 | if (!twl->asleep) | ||
| 452 | return 0; | ||
| 453 | __twl4030_phy_power_on(twl); | ||
| 454 | twl->asleep = 0; | ||
| 455 | dev_dbg(twl->dev, "%s\n", __func__); | 469 | dev_dbg(twl->dev, "%s\n", __func__); |
| 470 | pm_runtime_get_sync(twl->dev); | ||
| 471 | twl4030_i2c_access(twl, 1); | ||
| 472 | twl4030_usb_set_mode(twl, twl->usb_mode); | ||
| 473 | if (twl->usb_mode == T2_USB_MODE_ULPI) | ||
| 474 | twl4030_i2c_access(twl, 0); | ||
| 456 | 475 | ||
| 457 | /* | 476 | /* |
| 458 | * XXX When VBUS gets driven after musb goes to A mode, | 477 | * XXX When VBUS gets driven after musb goes to A mode, |
| @@ -558,9 +577,27 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
| 558 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 577 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
| 559 | * starts to handle softconnect right. | 578 | * starts to handle softconnect right. |
| 560 | */ | 579 | */ |
| 580 | if ((status == OMAP_MUSB_VBUS_VALID) || | ||
| 581 | (status == OMAP_MUSB_ID_GROUND)) { | ||
| 582 | if (twl->asleep) | ||
| 583 | pm_runtime_get_sync(twl->dev); | ||
| 584 | } else { | ||
| 585 | if (!twl->asleep) { | ||
| 586 | pm_runtime_mark_last_busy(twl->dev); | ||
| 587 | pm_runtime_put_autosuspend(twl->dev); | ||
| 588 | } | ||
| 589 | } | ||
| 561 | omap_musb_mailbox(status); | 590 | omap_musb_mailbox(status); |
| 562 | } | 591 | } |
| 563 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 592 | |
| 593 | /* don't schedule during sleep - irq works right then */ | ||
| 594 | if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { | ||
| 595 | cancel_delayed_work(&twl->id_workaround_work); | ||
| 596 | schedule_delayed_work(&twl->id_workaround_work, HZ); | ||
| 597 | } | ||
| 598 | |||
| 599 | if (irq) | ||
| 600 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | ||
| 564 | 601 | ||
| 565 | return IRQ_HANDLED; | 602 | return IRQ_HANDLED; |
| 566 | } | 603 | } |
| @@ -569,29 +606,8 @@ static void twl4030_id_workaround_work(struct work_struct *work) | |||
| 569 | { | 606 | { |
| 570 | struct twl4030_usb *twl = container_of(work, struct twl4030_usb, | 607 | struct twl4030_usb *twl = container_of(work, struct twl4030_usb, |
| 571 | id_workaround_work.work); | 608 | id_workaround_work.work); |
| 572 | enum omap_musb_vbus_id_status status; | ||
| 573 | bool status_changed = false; | ||
| 574 | |||
| 575 | status = twl4030_usb_linkstat(twl); | ||
| 576 | |||
| 577 | spin_lock_irq(&twl->lock); | ||
| 578 | if (status >= 0 && status != twl->linkstat) { | ||
| 579 | twl->linkstat = status; | ||
| 580 | status_changed = true; | ||
| 581 | } | ||
| 582 | spin_unlock_irq(&twl->lock); | ||
| 583 | |||
| 584 | if (status_changed) { | ||
| 585 | dev_dbg(twl->dev, "handle missing status change to %d\n", | ||
| 586 | status); | ||
| 587 | omap_musb_mailbox(status); | ||
| 588 | } | ||
| 589 | 609 | ||
| 590 | /* don't schedule during sleep - irq works right then */ | 610 | twl4030_usb_irq(0, twl); |
| 591 | if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { | ||
| 592 | cancel_delayed_work(&twl->id_workaround_work); | ||
| 593 | schedule_delayed_work(&twl->id_workaround_work, HZ); | ||
| 594 | } | ||
| 595 | } | 611 | } |
| 596 | 612 | ||
| 597 | static int twl4030_phy_init(struct phy *phy) | 613 | static int twl4030_phy_init(struct phy *phy) |
| @@ -599,22 +615,17 @@ static int twl4030_phy_init(struct phy *phy) | |||
| 599 | struct twl4030_usb *twl = phy_get_drvdata(phy); | 615 | struct twl4030_usb *twl = phy_get_drvdata(phy); |
| 600 | enum omap_musb_vbus_id_status status; | 616 | enum omap_musb_vbus_id_status status; |
| 601 | 617 | ||
| 602 | /* | 618 | pm_runtime_get_sync(twl->dev); |
| 603 | * Start in sleep state, we'll get called through set_suspend() | ||
| 604 | * callback when musb is runtime resumed and it's time to start. | ||
| 605 | */ | ||
| 606 | __twl4030_phy_power(twl, 0); | ||
| 607 | twl->asleep = 1; | ||
| 608 | |||
| 609 | status = twl4030_usb_linkstat(twl); | 619 | status = twl4030_usb_linkstat(twl); |
| 610 | twl->linkstat = status; | 620 | twl->linkstat = status; |
| 611 | 621 | ||
| 612 | if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { | 622 | if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) |
| 613 | omap_musb_mailbox(twl->linkstat); | 623 | omap_musb_mailbox(twl->linkstat); |
| 614 | twl4030_phy_power_on(phy); | ||
| 615 | } | ||
| 616 | 624 | ||
| 617 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 625 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
| 626 | pm_runtime_mark_last_busy(twl->dev); | ||
| 627 | pm_runtime_put_autosuspend(twl->dev); | ||
| 628 | |||
| 618 | return 0; | 629 | return 0; |
| 619 | } | 630 | } |
| 620 | 631 | ||
| @@ -650,6 +661,11 @@ static const struct phy_ops ops = { | |||
| 650 | .owner = THIS_MODULE, | 661 | .owner = THIS_MODULE, |
| 651 | }; | 662 | }; |
| 652 | 663 | ||
| 664 | static const struct dev_pm_ops twl4030_usb_pm_ops = { | ||
| 665 | SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend, | ||
| 666 | twl4030_usb_runtime_resume, NULL) | ||
| 667 | }; | ||
| 668 | |||
| 653 | static int twl4030_usb_probe(struct platform_device *pdev) | 669 | static int twl4030_usb_probe(struct platform_device *pdev) |
| 654 | { | 670 | { |
| 655 | struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); | 671 | struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); |
| @@ -726,6 +742,11 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
| 726 | 742 | ||
| 727 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); | 743 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); |
| 728 | 744 | ||
| 745 | pm_runtime_use_autosuspend(&pdev->dev); | ||
| 746 | pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); | ||
| 747 | pm_runtime_enable(&pdev->dev); | ||
| 748 | pm_runtime_get_sync(&pdev->dev); | ||
| 749 | |||
| 729 | /* Our job is to use irqs and status from the power module | 750 | /* Our job is to use irqs and status from the power module |
| 730 | * to keep the transceiver disabled when nothing's connected. | 751 | * to keep the transceiver disabled when nothing's connected. |
| 731 | * | 752 | * |
| @@ -744,6 +765,9 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
| 744 | return status; | 765 | return status; |
| 745 | } | 766 | } |
| 746 | 767 | ||
| 768 | pm_runtime_mark_last_busy(&pdev->dev); | ||
| 769 | pm_runtime_put_autosuspend(twl->dev); | ||
| 770 | |||
| 747 | dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); | 771 | dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); |
| 748 | return 0; | 772 | return 0; |
| 749 | } | 773 | } |
| @@ -753,6 +777,7 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
| 753 | struct twl4030_usb *twl = platform_get_drvdata(pdev); | 777 | struct twl4030_usb *twl = platform_get_drvdata(pdev); |
| 754 | int val; | 778 | int val; |
| 755 | 779 | ||
| 780 | pm_runtime_get_sync(twl->dev); | ||
| 756 | cancel_delayed_work(&twl->id_workaround_work); | 781 | cancel_delayed_work(&twl->id_workaround_work); |
| 757 | device_remove_file(twl->dev, &dev_attr_vbus); | 782 | device_remove_file(twl->dev, &dev_attr_vbus); |
| 758 | 783 | ||
| @@ -772,9 +797,8 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
| 772 | 797 | ||
| 773 | /* disable complete OTG block */ | 798 | /* disable complete OTG block */ |
| 774 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 799 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
| 775 | 800 | pm_runtime_mark_last_busy(twl->dev); | |
| 776 | if (!twl->asleep) | 801 | pm_runtime_put(twl->dev); |
| 777 | twl4030_phy_power(twl, 0); | ||
| 778 | 802 | ||
| 779 | return 0; | 803 | return 0; |
| 780 | } | 804 | } |
| @@ -792,6 +816,7 @@ static struct platform_driver twl4030_usb_driver = { | |||
| 792 | .remove = twl4030_usb_remove, | 816 | .remove = twl4030_usb_remove, |
| 793 | .driver = { | 817 | .driver = { |
| 794 | .name = "twl4030_usb", | 818 | .name = "twl4030_usb", |
| 819 | .pm = &twl4030_usb_pm_ops, | ||
| 795 | .owner = THIS_MODULE, | 820 | .owner = THIS_MODULE, |
| 796 | .of_match_table = of_match_ptr(twl4030_usb_id_table), | 821 | .of_match_table = of_match_ptr(twl4030_usb_id_table), |
| 797 | }, | 822 | }, |
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index a53a689a2bfa..8c6fd8d4dd3c 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c | |||
| @@ -620,8 +620,7 @@ static void abx500_gpio_dbg_show_one(struct seq_file *s, | |||
| 620 | } else | 620 | } else |
| 621 | seq_printf(s, " %-9s", chip->get(chip, offset) ? "hi" : "lo"); | 621 | seq_printf(s, " %-9s", chip->get(chip, offset) ? "hi" : "lo"); |
| 622 | 622 | ||
| 623 | if (pctldev) | 623 | mode = abx500_get_mode(pctldev, chip, offset); |
| 624 | mode = abx500_get_mode(pctldev, chip, offset); | ||
| 625 | 624 | ||
| 626 | seq_printf(s, " %s", (mode < 0) ? "unknown" : modes[mode]); | 625 | seq_printf(s, " %s", (mode < 0) ? "unknown" : modes[mode]); |
| 627 | 626 | ||
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index af1ba4fc150d..60464a2648aa 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
| @@ -497,10 +497,10 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = { | |||
| 497 | static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) | 497 | static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) |
| 498 | { | 498 | { |
| 499 | if (pin->mux) { | 499 | if (pin->mux) { |
| 500 | dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n", | 500 | dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lx\n", |
| 501 | pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf); | 501 | pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf); |
| 502 | } else { | 502 | } else { |
| 503 | dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n", | 503 | dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lx\n", |
| 504 | pin->bank + 'A', pin->pin, pin->conf); | 504 | pin->bank + 'A', pin->pin, pin->conf); |
| 505 | } | 505 | } |
| 506 | } | 506 | } |
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index 9ca59a018743..e12e5b07f6d7 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c | |||
| @@ -461,6 +461,7 @@ static struct irq_chip byt_irqchip = { | |||
| 461 | .irq_mask = byt_irq_mask, | 461 | .irq_mask = byt_irq_mask, |
| 462 | .irq_unmask = byt_irq_unmask, | 462 | .irq_unmask = byt_irq_unmask, |
| 463 | .irq_set_type = byt_irq_type, | 463 | .irq_set_type = byt_irq_type, |
| 464 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
| 464 | }; | 465 | }; |
| 465 | 466 | ||
| 466 | static void byt_gpio_irq_init_hw(struct byt_gpio *vg) | 467 | static void byt_gpio_irq_init_hw(struct byt_gpio *vg) |
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 5e8b2e04cd7a..0c372a300cb8 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
| @@ -438,7 +438,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
| 438 | int reg, ret, mask; | 438 | int reg, ret, mask; |
| 439 | unsigned long flags; | 439 | unsigned long flags; |
| 440 | u8 bit; | 440 | u8 bit; |
| 441 | u32 data; | 441 | u32 data, rmask; |
| 442 | 442 | ||
| 443 | if (iomux_num > 3) | 443 | if (iomux_num > 3) |
| 444 | return -EINVAL; | 444 | return -EINVAL; |
| @@ -478,8 +478,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
| 478 | spin_lock_irqsave(&bank->slock, flags); | 478 | spin_lock_irqsave(&bank->slock, flags); |
| 479 | 479 | ||
| 480 | data = (mask << (bit + 16)); | 480 | data = (mask << (bit + 16)); |
| 481 | rmask = data | (data >> 16); | ||
| 481 | data |= (mux & mask) << bit; | 482 | data |= (mux & mask) << bit; |
| 482 | ret = regmap_write(regmap, reg, data); | 483 | ret = regmap_update_bits(regmap, reg, rmask, data); |
| 483 | 484 | ||
| 484 | spin_unlock_irqrestore(&bank->slock, flags); | 485 | spin_unlock_irqrestore(&bank->slock, flags); |
| 485 | 486 | ||
| @@ -634,7 +635,7 @@ static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, | |||
| 634 | struct regmap *regmap; | 635 | struct regmap *regmap; |
| 635 | unsigned long flags; | 636 | unsigned long flags; |
| 636 | int reg, ret, i; | 637 | int reg, ret, i; |
| 637 | u32 data; | 638 | u32 data, rmask; |
| 638 | u8 bit; | 639 | u8 bit; |
| 639 | 640 | ||
| 640 | rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); | 641 | rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); |
| @@ -657,9 +658,10 @@ static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, | |||
| 657 | 658 | ||
| 658 | /* enable the write to the equivalent lower bits */ | 659 | /* enable the write to the equivalent lower bits */ |
| 659 | data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16); | 660 | data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16); |
| 661 | rmask = data | (data >> 16); | ||
| 660 | data |= (ret << bit); | 662 | data |= (ret << bit); |
| 661 | 663 | ||
| 662 | ret = regmap_write(regmap, reg, data); | 664 | ret = regmap_update_bits(regmap, reg, rmask, data); |
| 663 | spin_unlock_irqrestore(&bank->slock, flags); | 665 | spin_unlock_irqrestore(&bank->slock, flags); |
| 664 | 666 | ||
| 665 | return ret; | 667 | return ret; |
| @@ -722,7 +724,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
| 722 | int reg, ret; | 724 | int reg, ret; |
| 723 | unsigned long flags; | 725 | unsigned long flags; |
| 724 | u8 bit; | 726 | u8 bit; |
| 725 | u32 data; | 727 | u32 data, rmask; |
| 726 | 728 | ||
| 727 | dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", | 729 | dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", |
| 728 | bank->bank_num, pin_num, pull); | 730 | bank->bank_num, pin_num, pull); |
| @@ -750,6 +752,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
| 750 | 752 | ||
| 751 | /* enable the write to the equivalent lower bits */ | 753 | /* enable the write to the equivalent lower bits */ |
| 752 | data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); | 754 | data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); |
| 755 | rmask = data | (data >> 16); | ||
| 753 | 756 | ||
| 754 | switch (pull) { | 757 | switch (pull) { |
| 755 | case PIN_CONFIG_BIAS_DISABLE: | 758 | case PIN_CONFIG_BIAS_DISABLE: |
| @@ -770,7 +773,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
| 770 | return -EINVAL; | 773 | return -EINVAL; |
| 771 | } | 774 | } |
| 772 | 775 | ||
| 773 | ret = regmap_write(regmap, reg, data); | 776 | ret = regmap_update_bits(regmap, reg, rmask, data); |
| 774 | 777 | ||
| 775 | spin_unlock_irqrestore(&bank->slock, flags); | 778 | spin_unlock_irqrestore(&bank->slock, flags); |
| 776 | break; | 779 | break; |
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c index a06620474845..e641b4226c42 100644 --- a/drivers/pinctrl/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/pinctrl-tegra-xusb.c | |||
| @@ -680,7 +680,7 @@ static struct phy *tegra_xusb_padctl_xlate(struct device *dev, | |||
| 680 | if (args->args_count <= 0) | 680 | if (args->args_count <= 0) |
| 681 | return ERR_PTR(-EINVAL); | 681 | return ERR_PTR(-EINVAL); |
| 682 | 682 | ||
| 683 | if (index > ARRAY_SIZE(padctl->phys)) | 683 | if (index >= ARRAY_SIZE(padctl->phys)) |
| 684 | return ERR_PTR(-EINVAL); | 684 | return ERR_PTR(-EINVAL); |
| 685 | 685 | ||
| 686 | return padctl->phys[index]; | 686 | return padctl->phys[index]; |
| @@ -930,7 +930,8 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) | |||
| 930 | 930 | ||
| 931 | padctl->provider = devm_of_phy_provider_register(&pdev->dev, | 931 | padctl->provider = devm_of_phy_provider_register(&pdev->dev, |
| 932 | tegra_xusb_padctl_xlate); | 932 | tegra_xusb_padctl_xlate); |
| 933 | if (err < 0) { | 933 | if (IS_ERR(padctl->provider)) { |
| 934 | err = PTR_ERR(padctl->provider); | ||
| 934 | dev_err(&pdev->dev, "failed to register PHYs: %d\n", err); | 935 | dev_err(&pdev->dev, "failed to register PHYs: %d\n", err); |
| 935 | goto unregister; | 936 | goto unregister; |
| 936 | } | 937 | } |
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 003bfd874a61..d7154ed0b0eb 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c | |||
| @@ -127,14 +127,10 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
| 127 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | 127 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); |
| 128 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); | 128 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); |
| 129 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | 129 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
| 130 | struct samsung_pin_bank_type *bank_type = bank->type; | ||
| 131 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | 130 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
| 132 | unsigned int pin = irqd->hwirq; | 131 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; |
| 133 | unsigned int shift = EXYNOS_EINT_CON_LEN * pin; | ||
| 134 | unsigned int con, trig_type; | 132 | unsigned int con, trig_type; |
| 135 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; | 133 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; |
| 136 | unsigned long flags; | ||
| 137 | unsigned int mask; | ||
| 138 | 134 | ||
| 139 | switch (type) { | 135 | switch (type) { |
| 140 | case IRQ_TYPE_EDGE_RISING: | 136 | case IRQ_TYPE_EDGE_RISING: |
| @@ -167,8 +163,32 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
| 167 | con |= trig_type << shift; | 163 | con |= trig_type << shift; |
| 168 | writel(con, d->virt_base + reg_con); | 164 | writel(con, d->virt_base + reg_con); |
| 169 | 165 | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int exynos_irq_request_resources(struct irq_data *irqd) | ||
| 170 | { | ||
| 171 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | ||
| 172 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); | ||
| 173 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | ||
| 174 | struct samsung_pin_bank_type *bank_type = bank->type; | ||
| 175 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | ||
| 176 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; | ||
| 177 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; | ||
| 178 | unsigned long flags; | ||
| 179 | unsigned int mask; | ||
| 180 | unsigned int con; | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | ret = gpio_lock_as_irq(&bank->gpio_chip, irqd->hwirq); | ||
| 184 | if (ret) { | ||
| 185 | dev_err(bank->gpio_chip.dev, "unable to lock pin %s-%lu IRQ\n", | ||
| 186 | bank->name, irqd->hwirq); | ||
| 187 | return ret; | ||
| 188 | } | ||
| 189 | |||
| 170 | reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; | 190 | reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; |
| 171 | shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; | 191 | shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; |
| 172 | mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; | 192 | mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; |
| 173 | 193 | ||
| 174 | spin_lock_irqsave(&bank->slock, flags); | 194 | spin_lock_irqsave(&bank->slock, flags); |
| @@ -180,9 +200,42 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
| 180 | 200 | ||
| 181 | spin_unlock_irqrestore(&bank->slock, flags); | 201 | spin_unlock_irqrestore(&bank->slock, flags); |
| 182 | 202 | ||
| 203 | exynos_irq_unmask(irqd); | ||
| 204 | |||
| 183 | return 0; | 205 | return 0; |
| 184 | } | 206 | } |
| 185 | 207 | ||
| 208 | static void exynos_irq_release_resources(struct irq_data *irqd) | ||
| 209 | { | ||
| 210 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); | ||
| 211 | struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); | ||
| 212 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); | ||
| 213 | struct samsung_pin_bank_type *bank_type = bank->type; | ||
| 214 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | ||
| 215 | unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; | ||
| 216 | unsigned long reg_con = our_chip->eint_con + bank->eint_offset; | ||
| 217 | unsigned long flags; | ||
| 218 | unsigned int mask; | ||
| 219 | unsigned int con; | ||
| 220 | |||
| 221 | reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; | ||
| 222 | shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; | ||
| 223 | mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; | ||
| 224 | |||
| 225 | exynos_irq_mask(irqd); | ||
| 226 | |||
| 227 | spin_lock_irqsave(&bank->slock, flags); | ||
| 228 | |||
| 229 | con = readl(d->virt_base + reg_con); | ||
| 230 | con &= ~(mask << shift); | ||
| 231 | con |= FUNC_INPUT << shift; | ||
| 232 | writel(con, d->virt_base + reg_con); | ||
| 233 | |||
| 234 | spin_unlock_irqrestore(&bank->slock, flags); | ||
| 235 | |||
| 236 | gpio_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); | ||
| 237 | } | ||
| 238 | |||
| 186 | /* | 239 | /* |
| 187 | * irq_chip for gpio interrupts. | 240 | * irq_chip for gpio interrupts. |
| 188 | */ | 241 | */ |
| @@ -193,6 +246,8 @@ static struct exynos_irq_chip exynos_gpio_irq_chip = { | |||
| 193 | .irq_mask = exynos_irq_mask, | 246 | .irq_mask = exynos_irq_mask, |
| 194 | .irq_ack = exynos_irq_ack, | 247 | .irq_ack = exynos_irq_ack, |
| 195 | .irq_set_type = exynos_irq_set_type, | 248 | .irq_set_type = exynos_irq_set_type, |
| 249 | .irq_request_resources = exynos_irq_request_resources, | ||
| 250 | .irq_release_resources = exynos_irq_release_resources, | ||
| 196 | }, | 251 | }, |
| 197 | .eint_con = EXYNOS_GPIO_ECON_OFFSET, | 252 | .eint_con = EXYNOS_GPIO_ECON_OFFSET, |
| 198 | .eint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 253 | .eint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
| @@ -336,6 +391,8 @@ static struct exynos_irq_chip exynos_wkup_irq_chip = { | |||
| 336 | .irq_ack = exynos_irq_ack, | 391 | .irq_ack = exynos_irq_ack, |
| 337 | .irq_set_type = exynos_irq_set_type, | 392 | .irq_set_type = exynos_irq_set_type, |
| 338 | .irq_set_wake = exynos_wkup_irq_set_wake, | 393 | .irq_set_wake = exynos_wkup_irq_set_wake, |
| 394 | .irq_request_resources = exynos_irq_request_resources, | ||
| 395 | .irq_release_resources = exynos_irq_release_resources, | ||
| 339 | }, | 396 | }, |
| 340 | .eint_con = EXYNOS_WKUP_ECON_OFFSET, | 397 | .eint_con = EXYNOS_WKUP_ECON_OFFSET, |
| 341 | .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, | 398 | .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 2b882320e8e9..5cedc9d26390 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| 27 | 27 | ||
| 28 | /* pinmux function number for pin as gpio output line */ | 28 | /* pinmux function number for pin as gpio output line */ |
| 29 | #define FUNC_INPUT 0x0 | ||
| 29 | #define FUNC_OUTPUT 0x1 | 30 | #define FUNC_OUTPUT 0x1 |
| 30 | 31 | ||
| 31 | /** | 32 | /** |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 576d41b459e9..c6e5deba238e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c | |||
| @@ -4509,24 +4509,24 @@ static const char * const audio_clk_groups[] = { | |||
| 4509 | }; | 4509 | }; |
| 4510 | 4510 | ||
| 4511 | static const char * const can0_groups[] = { | 4511 | static const char * const can0_groups[] = { |
| 4512 | "can0_data_a", | 4512 | "can0_data", |
| 4513 | "can0_data_b", | 4513 | "can0_data_b", |
| 4514 | "can0_data_c", | 4514 | "can0_data_c", |
| 4515 | "can0_data_d", | 4515 | "can0_data_d", |
| 4516 | "can0_data_e", | 4516 | "can0_data_e", |
| 4517 | "can0_data_f", | 4517 | "can0_data_f", |
| 4518 | "can_clk_a", | 4518 | "can_clk", |
| 4519 | "can_clk_b", | 4519 | "can_clk_b", |
| 4520 | "can_clk_c", | 4520 | "can_clk_c", |
| 4521 | "can_clk_d", | 4521 | "can_clk_d", |
| 4522 | }; | 4522 | }; |
| 4523 | 4523 | ||
| 4524 | static const char * const can1_groups[] = { | 4524 | static const char * const can1_groups[] = { |
| 4525 | "can1_data_a", | 4525 | "can1_data", |
| 4526 | "can1_data_b", | 4526 | "can1_data_b", |
| 4527 | "can1_data_c", | 4527 | "can1_data_c", |
| 4528 | "can1_data_d", | 4528 | "can1_data_d", |
| 4529 | "can_clk_a", | 4529 | "can_clk", |
| 4530 | "can_clk_b", | 4530 | "can_clk_b", |
| 4531 | "can_clk_c", | 4531 | "can_clk_c", |
| 4532 | "can_clk_d", | 4532 | "can_clk_d", |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index fc468a3d95ce..02152de135b5 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
| @@ -88,7 +88,6 @@ struct ideapad_private { | |||
| 88 | struct dentry *debug; | 88 | struct dentry *debug; |
| 89 | unsigned long cfg; | 89 | unsigned long cfg; |
| 90 | bool has_hw_rfkill_switch; | 90 | bool has_hw_rfkill_switch; |
| 91 | bool has_touchpad_control; | ||
| 92 | }; | 91 | }; |
| 93 | 92 | ||
| 94 | static bool no_bt_rfkill; | 93 | static bool no_bt_rfkill; |
| @@ -456,7 +455,7 @@ struct ideapad_rfk_data { | |||
| 456 | int type; | 455 | int type; |
| 457 | }; | 456 | }; |
| 458 | 457 | ||
| 459 | const const struct ideapad_rfk_data ideapad_rfk_data[] = { | 458 | static const struct ideapad_rfk_data ideapad_rfk_data[] = { |
| 460 | { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, | 459 | { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, |
| 461 | { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, | 460 | { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, |
| 462 | { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, | 461 | { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, |
| @@ -767,9 +766,6 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) | |||
| 767 | { | 766 | { |
| 768 | unsigned long value; | 767 | unsigned long value; |
| 769 | 768 | ||
| 770 | if (!priv->has_touchpad_control) | ||
| 771 | return; | ||
| 772 | |||
| 773 | /* Without reading from EC touchpad LED doesn't switch state */ | 769 | /* Without reading from EC touchpad LED doesn't switch state */ |
| 774 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { | 770 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { |
| 775 | /* Some IdeaPads don't really turn off touchpad - they only | 771 | /* Some IdeaPads don't really turn off touchpad - they only |
| @@ -833,29 +829,7 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) | |||
| 833 | * always results in 0 on these models, causing ideapad_laptop to wrongly | 829 | * always results in 0 on these models, causing ideapad_laptop to wrongly |
| 834 | * report all radios as hardware-blocked. | 830 | * report all radios as hardware-blocked. |
| 835 | */ | 831 | */ |
| 836 | static struct dmi_system_id no_hw_rfkill_list[] = { | 832 | static const struct dmi_system_id no_hw_rfkill_list[] = { |
| 837 | { | ||
| 838 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", | ||
| 839 | .matches = { | ||
| 840 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 841 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), | ||
| 842 | }, | ||
| 843 | }, | ||
| 844 | {} | ||
| 845 | }; | ||
| 846 | |||
| 847 | /* | ||
| 848 | * Some models don't offer touchpad ctrl through the ideapad interface, causing | ||
| 849 | * ideapad_sync_touchpad_state to send wrong touchpad enable/disable events. | ||
| 850 | */ | ||
| 851 | static struct dmi_system_id no_touchpad_ctrl_list[] = { | ||
| 852 | { | ||
| 853 | .ident = "Lenovo Yoga 1 series", | ||
| 854 | .matches = { | ||
| 855 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 856 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga"), | ||
| 857 | }, | ||
| 858 | }, | ||
| 859 | { | 833 | { |
| 860 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", | 834 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", |
| 861 | .matches = { | 835 | .matches = { |
| @@ -889,7 +863,6 @@ static int ideapad_acpi_add(struct platform_device *pdev) | |||
| 889 | priv->adev = adev; | 863 | priv->adev = adev; |
| 890 | priv->platform_device = pdev; | 864 | priv->platform_device = pdev; |
| 891 | priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); | 865 | priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); |
| 892 | priv->has_touchpad_control = !dmi_check_system(no_touchpad_ctrl_list); | ||
| 893 | 866 | ||
| 894 | ret = ideapad_sysfs_init(priv); | 867 | ret = ideapad_sysfs_init(priv); |
| 895 | if (ret) | 868 | if (ret) |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index e4da61bcbf8b..d0dce734b2ed 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
| @@ -1255,10 +1255,15 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | |||
| 1255 | const char *buf, size_t count) | 1255 | const char *buf, size_t count) |
| 1256 | { | 1256 | { |
| 1257 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1257 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1258 | int mode = -1; | 1258 | int mode; |
| 1259 | int time = -1; | 1259 | int time; |
| 1260 | int ret; | ||
| 1260 | 1261 | ||
| 1261 | if (sscanf(buf, "%i", &mode) != 1 || (mode != 2 || mode != 1)) | 1262 | |
| 1263 | ret = kstrtoint(buf, 0, &mode); | ||
| 1264 | if (ret) | ||
| 1265 | return ret; | ||
| 1266 | if (mode != SCI_KBD_MODE_FNZ && mode != SCI_KBD_MODE_AUTO) | ||
| 1262 | return -EINVAL; | 1267 | return -EINVAL; |
| 1263 | 1268 | ||
| 1264 | /* Set the Keyboard Backlight Mode where: | 1269 | /* Set the Keyboard Backlight Mode where: |
| @@ -1266,11 +1271,12 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | |||
| 1266 | * Auto - KBD backlight turns off automatically in given time | 1271 | * Auto - KBD backlight turns off automatically in given time |
| 1267 | * FN-Z - KBD backlight "toggles" when hotkey pressed | 1272 | * FN-Z - KBD backlight "toggles" when hotkey pressed |
| 1268 | */ | 1273 | */ |
| 1269 | if (mode != -1 && toshiba->kbd_mode != mode) { | 1274 | if (toshiba->kbd_mode != mode) { |
| 1270 | time = toshiba->kbd_time << HCI_MISC_SHIFT; | 1275 | time = toshiba->kbd_time << HCI_MISC_SHIFT; |
| 1271 | time = time + toshiba->kbd_mode; | 1276 | time = time + toshiba->kbd_mode; |
| 1272 | if (toshiba_kbd_illum_status_set(toshiba, time) < 0) | 1277 | ret = toshiba_kbd_illum_status_set(toshiba, time); |
| 1273 | return -EIO; | 1278 | if (ret) |
| 1279 | return ret; | ||
| 1274 | toshiba->kbd_mode = mode; | 1280 | toshiba->kbd_mode = mode; |
| 1275 | } | 1281 | } |
| 1276 | 1282 | ||
| @@ -1857,9 +1863,16 @@ static int toshiba_acpi_resume(struct device *device) | |||
| 1857 | { | 1863 | { |
| 1858 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); | 1864 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); |
| 1859 | u32 result; | 1865 | u32 result; |
| 1866 | acpi_status status; | ||
| 1867 | |||
| 1868 | if (dev->hotkey_dev) { | ||
| 1869 | status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", | ||
| 1870 | NULL, NULL); | ||
| 1871 | if (ACPI_FAILURE(status)) | ||
| 1872 | pr_info("Unable to re-enable hotkeys\n"); | ||
| 1860 | 1873 | ||
| 1861 | if (dev->hotkey_dev) | ||
| 1862 | hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result); | 1874 | hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result); |
| 1875 | } | ||
| 1863 | 1876 | ||
| 1864 | return 0; | 1877 | return 0; |
| 1865 | } | 1878 | } |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index b1cda6ffdbcc..45e05b32f9b6 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
| @@ -953,6 +953,7 @@ static const struct x86_cpu_id rapl_ids[] = { | |||
| 953 | { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ | 953 | { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ |
| 954 | { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ | 954 | { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ |
| 955 | { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ | 955 | { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ |
| 956 | { X86_VENDOR_INTEL, 6, 0x3f},/* Haswell */ | ||
| 956 | { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ | 957 | { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ |
| 957 | /* TODO: Add more CPU IDs after testing */ | 958 | /* TODO: Add more CPU IDs after testing */ |
| 958 | {} | 959 | {} |
| @@ -1166,11 +1167,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) | |||
| 1166 | 1167 | ||
| 1167 | for (i = 0; i < RAPL_DOMAIN_MAX; i++) { | 1168 | for (i = 0; i < RAPL_DOMAIN_MAX; i++) { |
| 1168 | /* use physical package id to read counters */ | 1169 | /* use physical package id to read counters */ |
| 1169 | if (!rapl_check_domain(cpu, i)) | 1170 | if (!rapl_check_domain(cpu, i)) { |
| 1170 | rp->domain_map |= 1 << i; | 1171 | rp->domain_map |= 1 << i; |
| 1171 | else | 1172 | pr_info("Found RAPL domain %s\n", rapl_domain_names[i]); |
| 1172 | pr_warn("RAPL domain %s detection failed\n", | 1173 | } |
| 1173 | rapl_domain_names[i]); | ||
| 1174 | } | 1174 | } |
| 1175 | rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); | 1175 | rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); |
| 1176 | if (!rp->nr_domains) { | 1176 | if (!rp->nr_domains) { |
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 4b66bf09ee55..d2c35920ff08 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
| @@ -606,6 +606,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
| 606 | unsigned int best = 0; | 606 | unsigned int best = 0; |
| 607 | struct pwm_lookup *p; | 607 | struct pwm_lookup *p; |
| 608 | unsigned int match; | 608 | unsigned int match; |
| 609 | unsigned int period; | ||
| 610 | enum pwm_polarity polarity; | ||
| 609 | 611 | ||
| 610 | /* look up via DT first */ | 612 | /* look up via DT first */ |
| 611 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) | 613 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) |
| @@ -653,6 +655,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
| 653 | if (match > best) { | 655 | if (match > best) { |
| 654 | chip = pwmchip_find_by_name(p->provider); | 656 | chip = pwmchip_find_by_name(p->provider); |
| 655 | index = p->index; | 657 | index = p->index; |
| 658 | period = p->period; | ||
| 659 | polarity = p->polarity; | ||
| 656 | 660 | ||
| 657 | if (match != 3) | 661 | if (match != 3) |
| 658 | best = match; | 662 | best = match; |
| @@ -668,8 +672,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
| 668 | if (IS_ERR(pwm)) | 672 | if (IS_ERR(pwm)) |
| 669 | return pwm; | 673 | return pwm; |
| 670 | 674 | ||
| 671 | pwm_set_period(pwm, p->period); | 675 | pwm_set_period(pwm, period); |
| 672 | pwm_set_polarity(pwm, p->polarity); | 676 | pwm_set_polarity(pwm, polarity); |
| 673 | 677 | ||
| 674 | 678 | ||
| 675 | return pwm; | 679 | return pwm; |
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 8f06250a0389..8754c33361e8 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c | |||
| @@ -717,12 +717,14 @@ static int s5m_rtc_probe(struct platform_device *pdev) | |||
| 717 | info->device_type = s5m87xx->device_type; | 717 | info->device_type = s5m87xx->device_type; |
| 718 | info->wtsr_smpl = s5m87xx->wtsr_smpl; | 718 | info->wtsr_smpl = s5m87xx->wtsr_smpl; |
| 719 | 719 | ||
| 720 | info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); | 720 | if (s5m87xx->irq_data) { |
| 721 | if (info->irq <= 0) { | 721 | info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); |
| 722 | ret = -EINVAL; | 722 | if (info->irq <= 0) { |
| 723 | dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", | 723 | ret = -EINVAL; |
| 724 | dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", | ||
| 724 | alarm_irq); | 725 | alarm_irq); |
| 725 | goto err; | 726 | goto err; |
| 727 | } | ||
| 726 | } | 728 | } |
| 727 | 729 | ||
| 728 | platform_set_drvdata(pdev, info); | 730 | platform_set_drvdata(pdev, info); |
| @@ -744,6 +746,11 @@ static int s5m_rtc_probe(struct platform_device *pdev) | |||
| 744 | goto err; | 746 | goto err; |
| 745 | } | 747 | } |
| 746 | 748 | ||
| 749 | if (!info->irq) { | ||
| 750 | dev_info(&pdev->dev, "Alarm IRQ not available\n"); | ||
| 751 | return 0; | ||
| 752 | } | ||
| 753 | |||
| 747 | ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, | 754 | ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, |
| 748 | s5m_rtc_alarm_irq, 0, "rtc-alarm0", | 755 | s5m_rtc_alarm_irq, 0, "rtc-alarm0", |
| 749 | info); | 756 | info); |
| @@ -802,7 +809,7 @@ static int s5m_rtc_resume(struct device *dev) | |||
| 802 | struct s5m_rtc_info *info = dev_get_drvdata(dev); | 809 | struct s5m_rtc_info *info = dev_get_drvdata(dev); |
| 803 | int ret = 0; | 810 | int ret = 0; |
| 804 | 811 | ||
| 805 | if (device_may_wakeup(dev)) | 812 | if (info->irq && device_may_wakeup(dev)) |
| 806 | ret = disable_irq_wake(info->irq); | 813 | ret = disable_irq_wake(info->irq); |
| 807 | 814 | ||
| 808 | return ret; | 815 | return ret; |
| @@ -813,7 +820,7 @@ static int s5m_rtc_suspend(struct device *dev) | |||
| 813 | struct s5m_rtc_info *info = dev_get_drvdata(dev); | 820 | struct s5m_rtc_info *info = dev_get_drvdata(dev); |
| 814 | int ret = 0; | 821 | int ret = 0; |
| 815 | 822 | ||
| 816 | if (device_may_wakeup(dev)) | 823 | if (info->irq && device_may_wakeup(dev)) |
| 817 | ret = enable_irq_wake(info->irq); | 824 | ret = enable_irq_wake(info->irq); |
| 818 | 825 | ||
| 819 | return ret; | 826 | return ret; |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 2ead7e78c456..14ba80bfa571 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
| @@ -77,7 +77,7 @@ EXPORT_SYMBOL_GPL(dasd_nofcx); | |||
| 77 | * strings when running as a module. | 77 | * strings when running as a module. |
| 78 | */ | 78 | */ |
| 79 | static char *dasd[256]; | 79 | static char *dasd[256]; |
| 80 | module_param_array(dasd, charp, NULL, 0); | 80 | module_param_array(dasd, charp, NULL, S_IRUGO); |
| 81 | 81 | ||
| 82 | /* | 82 | /* |
| 83 | * Single spinlock to protect devmap and servermap structures and lists. | 83 | * Single spinlock to protect devmap and servermap structures and lists. |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index a6d47e5eee9e..c43aca69fb30 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -1035,12 +1035,26 @@ static int tty3215_write(struct tty_struct * tty, | |||
| 1035 | const unsigned char *buf, int count) | 1035 | const unsigned char *buf, int count) |
| 1036 | { | 1036 | { |
| 1037 | struct raw3215_info *raw; | 1037 | struct raw3215_info *raw; |
| 1038 | int i, written; | ||
| 1038 | 1039 | ||
| 1039 | if (!tty) | 1040 | if (!tty) |
| 1040 | return 0; | 1041 | return 0; |
| 1041 | raw = (struct raw3215_info *) tty->driver_data; | 1042 | raw = (struct raw3215_info *) tty->driver_data; |
| 1042 | raw3215_write(raw, buf, count); | 1043 | written = count; |
| 1043 | return count; | 1044 | while (count > 0) { |
| 1045 | for (i = 0; i < count; i++) | ||
| 1046 | if (buf[i] == '\t' || buf[i] == '\n') | ||
| 1047 | break; | ||
| 1048 | raw3215_write(raw, buf, i); | ||
| 1049 | count -= i; | ||
| 1050 | buf += i; | ||
| 1051 | if (count > 0) { | ||
| 1052 | raw3215_putchar(raw, *buf); | ||
| 1053 | count--; | ||
| 1054 | buf++; | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | return written; | ||
| 1044 | } | 1058 | } |
| 1045 | 1059 | ||
| 1046 | /* | 1060 | /* |
| @@ -1188,7 +1202,7 @@ static int __init tty3215_init(void) | |||
| 1188 | driver->subtype = SYSTEM_TYPE_TTY; | 1202 | driver->subtype = SYSTEM_TYPE_TTY; |
| 1189 | driver->init_termios = tty_std_termios; | 1203 | driver->init_termios = tty_std_termios; |
| 1190 | driver->init_termios.c_iflag = IGNBRK | IGNPAR; | 1204 | driver->init_termios.c_iflag = IGNBRK | IGNPAR; |
| 1191 | driver->init_termios.c_oflag = ONLCR | XTABS; | 1205 | driver->init_termios.c_oflag = ONLCR; |
| 1192 | driver->init_termios.c_lflag = ISIG; | 1206 | driver->init_termios.c_lflag = ISIG; |
| 1193 | driver->flags = TTY_DRIVER_REAL_RAW; | 1207 | driver->flags = TTY_DRIVER_REAL_RAW; |
| 1194 | tty_set_operations(driver, &tty3215_ops); | 1208 | tty_set_operations(driver, &tty3215_ops); |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 7ed7a5987816..003663288e29 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
| @@ -559,7 +559,7 @@ sclp_tty_init(void) | |||
| 559 | driver->subtype = SYSTEM_TYPE_TTY; | 559 | driver->subtype = SYSTEM_TYPE_TTY; |
| 560 | driver->init_termios = tty_std_termios; | 560 | driver->init_termios = tty_std_termios; |
| 561 | driver->init_termios.c_iflag = IGNBRK | IGNPAR; | 561 | driver->init_termios.c_iflag = IGNBRK | IGNPAR; |
| 562 | driver->init_termios.c_oflag = ONLCR | XTABS; | 562 | driver->init_termios.c_oflag = ONLCR; |
| 563 | driver->init_termios.c_lflag = ISIG | ECHO; | 563 | driver->init_termios.c_lflag = ISIG | ECHO; |
| 564 | driver->flags = TTY_DRIVER_REAL_RAW; | 564 | driver->flags = TTY_DRIVER_REAL_RAW; |
| 565 | tty_set_operations(driver, &sclp_ops); | 565 | tty_set_operations(driver, &sclp_ops); |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 97ef37b51068..e7646ce3d659 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
| @@ -889,6 +889,7 @@ extern const struct attribute_group *qeth_generic_attr_groups[]; | |||
| 889 | extern const struct attribute_group *qeth_osn_attr_groups[]; | 889 | extern const struct attribute_group *qeth_osn_attr_groups[]; |
| 890 | extern struct workqueue_struct *qeth_wq; | 890 | extern struct workqueue_struct *qeth_wq; |
| 891 | 891 | ||
| 892 | int qeth_card_hw_is_reachable(struct qeth_card *); | ||
| 892 | const char *qeth_get_cardname_short(struct qeth_card *); | 893 | const char *qeth_get_cardname_short(struct qeth_card *); |
| 893 | int qeth_realloc_buffer_pool(struct qeth_card *, int); | 894 | int qeth_realloc_buffer_pool(struct qeth_card *, int); |
| 894 | int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); | 895 | int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c0d6ba8655c7..fd22c811cbe1 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -73,6 +73,13 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); | |||
| 73 | struct workqueue_struct *qeth_wq; | 73 | struct workqueue_struct *qeth_wq; |
| 74 | EXPORT_SYMBOL_GPL(qeth_wq); | 74 | EXPORT_SYMBOL_GPL(qeth_wq); |
| 75 | 75 | ||
| 76 | int qeth_card_hw_is_reachable(struct qeth_card *card) | ||
| 77 | { | ||
| 78 | return (card->state == CARD_STATE_SOFTSETUP) || | ||
| 79 | (card->state == CARD_STATE_UP); | ||
| 80 | } | ||
| 81 | EXPORT_SYMBOL_GPL(qeth_card_hw_is_reachable); | ||
| 82 | |||
| 76 | static void qeth_close_dev_handler(struct work_struct *work) | 83 | static void qeth_close_dev_handler(struct work_struct *work) |
| 77 | { | 84 | { |
| 78 | struct qeth_card *card; | 85 | struct qeth_card *card; |
| @@ -5790,6 +5797,7 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, | |||
| 5790 | struct qeth_card *card = netdev->ml_priv; | 5797 | struct qeth_card *card = netdev->ml_priv; |
| 5791 | enum qeth_link_types link_type; | 5798 | enum qeth_link_types link_type; |
| 5792 | struct carrier_info carrier_info; | 5799 | struct carrier_info carrier_info; |
| 5800 | int rc; | ||
| 5793 | u32 speed; | 5801 | u32 speed; |
| 5794 | 5802 | ||
| 5795 | if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) | 5803 | if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) |
| @@ -5832,8 +5840,14 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, | |||
| 5832 | /* Check if we can obtain more accurate information. */ | 5840 | /* Check if we can obtain more accurate information. */ |
| 5833 | /* If QUERY_CARD_INFO command is not supported or fails, */ | 5841 | /* If QUERY_CARD_INFO command is not supported or fails, */ |
| 5834 | /* just return the heuristics that was filled above. */ | 5842 | /* just return the heuristics that was filled above. */ |
| 5835 | if (qeth_query_card_info(card, &carrier_info) != 0) | 5843 | if (!qeth_card_hw_is_reachable(card)) |
| 5844 | return -ENODEV; | ||
| 5845 | rc = qeth_query_card_info(card, &carrier_info); | ||
| 5846 | if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */ | ||
| 5836 | return 0; | 5847 | return 0; |
| 5848 | if (rc) /* report error from the hardware operation */ | ||
| 5849 | return rc; | ||
| 5850 | /* on success, fill in the information got from the hardware */ | ||
| 5837 | 5851 | ||
| 5838 | netdev_dbg(netdev, | 5852 | netdev_dbg(netdev, |
| 5839 | "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n", | 5853 | "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n", |
diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c index ae1bc04b8653..59e3aa538b4d 100644 --- a/drivers/s390/net/qeth_l2_sys.c +++ b/drivers/s390/net/qeth_l2_sys.c | |||
| @@ -5,17 +5,12 @@ | |||
| 5 | 5 | ||
| 6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
| 7 | #include <asm/ebcdic.h> | 7 | #include <asm/ebcdic.h> |
| 8 | #include "qeth_core.h" | ||
| 8 | #include "qeth_l2.h" | 9 | #include "qeth_l2.h" |
| 9 | 10 | ||
| 10 | #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ | 11 | #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ |
| 11 | struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) | 12 | struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) |
| 12 | 13 | ||
| 13 | static int qeth_card_hw_is_reachable(struct qeth_card *card) | ||
| 14 | { | ||
| 15 | return (card->state == CARD_STATE_SOFTSETUP) || | ||
| 16 | (card->state == CARD_STATE_UP); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ssize_t qeth_bridge_port_role_state_show(struct device *dev, | 14 | static ssize_t qeth_bridge_port_role_state_show(struct device *dev, |
| 20 | struct device_attribute *attr, char *buf, | 15 | struct device_attribute *attr, char *buf, |
| 21 | int show_state) | 16 | int show_state) |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index df3306019a7e..d81f3cc43ff1 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -377,6 +377,10 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost) | |||
| 377 | pool->slab_flags |= SLAB_CACHE_DMA; | 377 | pool->slab_flags |= SLAB_CACHE_DMA; |
| 378 | pool->gfp_mask = __GFP_DMA; | 378 | pool->gfp_mask = __GFP_DMA; |
| 379 | } | 379 | } |
| 380 | |||
| 381 | if (hostt->cmd_size) | ||
| 382 | hostt->cmd_pool = pool; | ||
| 383 | |||
| 380 | return pool; | 384 | return pool; |
| 381 | } | 385 | } |
| 382 | 386 | ||
| @@ -421,8 +425,10 @@ out: | |||
| 421 | out_free_slab: | 425 | out_free_slab: |
| 422 | kmem_cache_destroy(pool->cmd_slab); | 426 | kmem_cache_destroy(pool->cmd_slab); |
| 423 | out_free_pool: | 427 | out_free_pool: |
| 424 | if (hostt->cmd_size) | 428 | if (hostt->cmd_size) { |
| 425 | scsi_free_host_cmd_pool(pool); | 429 | scsi_free_host_cmd_pool(pool); |
| 430 | hostt->cmd_pool = NULL; | ||
| 431 | } | ||
| 426 | goto out; | 432 | goto out; |
| 427 | } | 433 | } |
| 428 | 434 | ||
| @@ -444,8 +450,10 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost) | |||
| 444 | if (!--pool->users) { | 450 | if (!--pool->users) { |
| 445 | kmem_cache_destroy(pool->cmd_slab); | 451 | kmem_cache_destroy(pool->cmd_slab); |
| 446 | kmem_cache_destroy(pool->sense_slab); | 452 | kmem_cache_destroy(pool->sense_slab); |
| 447 | if (hostt->cmd_size) | 453 | if (hostt->cmd_size) { |
| 448 | scsi_free_host_cmd_pool(pool); | 454 | scsi_free_host_cmd_pool(pool); |
| 455 | hostt->cmd_pool = NULL; | ||
| 456 | } | ||
| 449 | } | 457 | } |
| 450 | mutex_unlock(&host_cmd_pool_mutex); | 458 | mutex_unlock(&host_cmd_pool_mutex); |
| 451 | } | 459 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9c44392b748f..d837dc180522 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1774,7 +1774,7 @@ static void scsi_request_fn(struct request_queue *q) | |||
| 1774 | blk_requeue_request(q, req); | 1774 | blk_requeue_request(q, req); |
| 1775 | atomic_dec(&sdev->device_busy); | 1775 | atomic_dec(&sdev->device_busy); |
| 1776 | out_delay: | 1776 | out_delay: |
| 1777 | if (atomic_read(&sdev->device_busy) && !scsi_device_blocked(sdev)) | 1777 | if (!atomic_read(&sdev->device_busy) && !scsi_device_blocked(sdev)) |
| 1778 | blk_delay_queue(q, SCSI_QUEUE_DELAY); | 1778 | blk_delay_queue(q, SCSI_QUEUE_DELAY); |
| 1779 | } | 1779 | } |
| 1780 | 1780 | ||
| @@ -1808,7 +1808,6 @@ static int scsi_mq_prep_fn(struct request *req) | |||
| 1808 | 1808 | ||
| 1809 | cmd->tag = req->tag; | 1809 | cmd->tag = req->tag; |
| 1810 | 1810 | ||
| 1811 | req->cmd = req->__cmd; | ||
| 1812 | cmd->cmnd = req->cmd; | 1811 | cmd->cmnd = req->cmd; |
| 1813 | cmd->prot_op = SCSI_PROT_NORMAL; | 1812 | cmd->prot_op = SCSI_PROT_NORMAL; |
| 1814 | 1813 | ||
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 788ed9b59b4e..114203f32843 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for the SuperH specific drivers. | 2 | # Makefile for the SuperH specific drivers. |
| 3 | # | 3 | # |
| 4 | obj-$(CONFIG_SUPERH) += intc/ | 4 | obj-$(CONFIG_SH_INTC) += intc/ |
| 5 | obj-$(CONFIG_ARCH_SHMOBILE_LEGACY) += intc/ | ||
| 6 | ifneq ($(CONFIG_COMMON_CLK),y) | 5 | ifneq ($(CONFIG_COMMON_CLK),y) |
| 7 | obj-$(CONFIG_HAVE_CLK) += clk/ | 6 | obj-$(CONFIG_HAVE_CLK) += clk/ |
| 8 | endif | 7 | endif |
diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig index 60228fae943f..6a1b05ddc8c9 100644 --- a/drivers/sh/intc/Kconfig +++ b/drivers/sh/intc/Kconfig | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | config SH_INTC | 1 | config SH_INTC |
| 2 | def_bool y | 2 | bool |
| 3 | select IRQ_DOMAIN | 3 | select IRQ_DOMAIN |
| 4 | 4 | ||
| 5 | if SH_INTC | ||
| 6 | |||
| 5 | comment "Interrupt controller options" | 7 | comment "Interrupt controller options" |
| 6 | 8 | ||
| 7 | config INTC_USERIMASK | 9 | config INTC_USERIMASK |
| @@ -37,3 +39,5 @@ config INTC_MAPPING_DEBUG | |||
| 37 | between system IRQs and the per-controller id tables. | 39 | between system IRQs and the per-controller id tables. |
| 38 | 40 | ||
| 39 | If in doubt, say N. | 41 | If in doubt, say N. |
| 42 | |||
| 43 | endif | ||
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 40c3d43c9292..f40b34cdf2fc 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c | |||
| @@ -945,7 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev) | |||
| 945 | spi_bitbang_stop(&hw->bitbang); | 945 | spi_bitbang_stop(&hw->bitbang); |
| 946 | free_irq(hw->irq, hw); | 946 | free_irq(hw->irq, hw); |
| 947 | iounmap((void __iomem *)hw->regs); | 947 | iounmap((void __iomem *)hw->regs); |
| 948 | release_mem_region(r->start, sizeof(psc_spi_t)); | 948 | release_mem_region(hw->ioarea->start, sizeof(psc_spi_t)); |
| 949 | 949 | ||
| 950 | if (hw->usedma) { | 950 | if (hw->usedma) { |
| 951 | au1550_spi_dma_rxtmp_free(hw); | 951 | au1550_spi_dma_rxtmp_free(hw); |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 276a3884fb3c..48f1d26e6ad9 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
| @@ -417,16 +417,16 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
| 417 | flags, dev_name(&spi->dev)); | 417 | flags, dev_name(&spi->dev)); |
| 418 | internal_cs = false; | 418 | internal_cs = false; |
| 419 | } | 419 | } |
| 420 | } | ||
| 421 | 420 | ||
| 422 | if (retval) { | 421 | if (retval) { |
| 423 | dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", | 422 | dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", |
| 424 | spi->cs_gpio, retval); | 423 | spi->cs_gpio, retval); |
| 425 | return retval; | 424 | return retval; |
| 426 | } | 425 | } |
| 427 | 426 | ||
| 428 | if (internal_cs) | 427 | if (internal_cs) |
| 429 | set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); | 428 | set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); |
| 429 | } | ||
| 430 | 430 | ||
| 431 | if (spi->mode & SPI_READY) | 431 | if (spi->mode & SPI_READY) |
| 432 | set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK); | 432 | set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK); |
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 3f3dc1226edf..e14960470d8d 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c | |||
| @@ -62,6 +62,8 @@ static int spi_pci_probe(struct pci_dev *pdev, | |||
| 62 | if (ret) | 62 | if (ret) |
| 63 | return ret; | 63 | return ret; |
| 64 | 64 | ||
| 65 | dws->regs = pcim_iomap_table(pdev)[pci_bar]; | ||
| 66 | |||
| 65 | dws->bus_num = 0; | 67 | dws->bus_num = 0; |
| 66 | dws->num_cs = 4; | 68 | dws->num_cs = 4; |
| 67 | dws->irq = pdev->irq; | 69 | dws->irq = pdev->irq; |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 29f33143b795..670f0627f3bf 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -271,7 +271,7 @@ static void giveback(struct dw_spi *dws) | |||
| 271 | transfer_list); | 271 | transfer_list); |
| 272 | 272 | ||
| 273 | if (!last_transfer->cs_change) | 273 | if (!last_transfer->cs_change) |
| 274 | spi_chip_sel(dws, dws->cur_msg->spi, 0); | 274 | spi_chip_sel(dws, msg->spi, 0); |
| 275 | 275 | ||
| 276 | spi_finalize_current_message(dws->master); | 276 | spi_finalize_current_message(dws->master); |
| 277 | } | 277 | } |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 68441fa448de..352eed7463ac 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -329,7 +329,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, | |||
| 329 | disable_fifo: | 329 | disable_fifo: |
| 330 | if (t->rx_buf != NULL) | 330 | if (t->rx_buf != NULL) |
| 331 | chconf &= ~OMAP2_MCSPI_CHCONF_FFER; | 331 | chconf &= ~OMAP2_MCSPI_CHCONF_FFER; |
| 332 | else | 332 | |
| 333 | if (t->tx_buf != NULL) | ||
| 333 | chconf &= ~OMAP2_MCSPI_CHCONF_FFET; | 334 | chconf &= ~OMAP2_MCSPI_CHCONF_FFET; |
| 334 | 335 | ||
| 335 | mcspi_write_chconf0(spi, chconf); | 336 | mcspi_write_chconf0(spi, chconf); |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index fe792106bdc5..46f45ca2c694 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
| @@ -1074,6 +1074,7 @@ static struct acpi_device_id pxa2xx_spi_acpi_match[] = { | |||
| 1074 | { "INT3430", 0 }, | 1074 | { "INT3430", 0 }, |
| 1075 | { "INT3431", 0 }, | 1075 | { "INT3431", 0 }, |
| 1076 | { "80860F0E", 0 }, | 1076 | { "80860F0E", 0 }, |
| 1077 | { "8086228E", 0 }, | ||
| 1077 | { }, | 1078 | { }, |
| 1078 | }; | 1079 | }; |
| 1079 | MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); | 1080 | MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); |
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index c0743604b906..cd0e08b0c9f6 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c | |||
| @@ -499,7 +499,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs) | |||
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | /* div doesn't support odd number */ | 501 | /* div doesn't support odd number */ |
| 502 | div = rs->max_freq / rs->speed; | 502 | div = max_t(u32, rs->max_freq / rs->speed, 1); |
| 503 | div = (div + 1) & 0xfffe; | 503 | div = (div + 1) & 0xfffe; |
| 504 | 504 | ||
| 505 | spi_enable_chip(rs, 0); | 505 | spi_enable_chip(rs, 0); |
| @@ -678,7 +678,7 @@ static int rockchip_spi_probe(struct platform_device *pdev) | |||
| 678 | rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); | 678 | rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); |
| 679 | rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); | 679 | rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); |
| 680 | rs->dma_tx.direction = DMA_MEM_TO_DEV; | 680 | rs->dma_tx.direction = DMA_MEM_TO_DEV; |
| 681 | rs->dma_tx.direction = DMA_DEV_TO_MEM; | 681 | rs->dma_rx.direction = DMA_DEV_TO_MEM; |
| 682 | 682 | ||
| 683 | master->can_dma = rockchip_spi_can_dma; | 683 | master->can_dma = rockchip_spi_can_dma; |
| 684 | master->dma_tx = rs->dma_tx.ch; | 684 | master->dma_tx = rs->dma_tx.ch; |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index c850dfdfa9e3..ad87a98f8f68 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -472,25 +472,52 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, | |||
| 472 | dma_cookie_t cookie; | 472 | dma_cookie_t cookie; |
| 473 | int ret; | 473 | int ret; |
| 474 | 474 | ||
| 475 | if (tx) { | 475 | /* First prepare and submit the DMA request(s), as this may fail */ |
| 476 | desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, | ||
| 477 | tx->sgl, tx->nents, DMA_TO_DEVICE, | ||
| 478 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 479 | if (!desc_tx) | ||
| 480 | goto no_dma; | ||
| 481 | |||
| 482 | irq_mask |= SPCR_SPTIE; | ||
| 483 | } | ||
| 484 | if (rx) { | 476 | if (rx) { |
| 485 | desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, | 477 | desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, |
| 486 | rx->sgl, rx->nents, DMA_FROM_DEVICE, | 478 | rx->sgl, rx->nents, DMA_FROM_DEVICE, |
| 487 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 479 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 488 | if (!desc_rx) | 480 | if (!desc_rx) { |
| 489 | goto no_dma; | 481 | ret = -EAGAIN; |
| 482 | goto no_dma_rx; | ||
| 483 | } | ||
| 484 | |||
| 485 | desc_rx->callback = rspi_dma_complete; | ||
| 486 | desc_rx->callback_param = rspi; | ||
| 487 | cookie = dmaengine_submit(desc_rx); | ||
| 488 | if (dma_submit_error(cookie)) { | ||
| 489 | ret = cookie; | ||
| 490 | goto no_dma_rx; | ||
| 491 | } | ||
| 490 | 492 | ||
| 491 | irq_mask |= SPCR_SPRIE; | 493 | irq_mask |= SPCR_SPRIE; |
| 492 | } | 494 | } |
| 493 | 495 | ||
| 496 | if (tx) { | ||
| 497 | desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, | ||
| 498 | tx->sgl, tx->nents, DMA_TO_DEVICE, | ||
| 499 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 500 | if (!desc_tx) { | ||
| 501 | ret = -EAGAIN; | ||
| 502 | goto no_dma_tx; | ||
| 503 | } | ||
| 504 | |||
| 505 | if (rx) { | ||
| 506 | /* No callback */ | ||
| 507 | desc_tx->callback = NULL; | ||
| 508 | } else { | ||
| 509 | desc_tx->callback = rspi_dma_complete; | ||
| 510 | desc_tx->callback_param = rspi; | ||
| 511 | } | ||
| 512 | cookie = dmaengine_submit(desc_tx); | ||
| 513 | if (dma_submit_error(cookie)) { | ||
| 514 | ret = cookie; | ||
| 515 | goto no_dma_tx; | ||
| 516 | } | ||
| 517 | |||
| 518 | irq_mask |= SPCR_SPTIE; | ||
| 519 | } | ||
| 520 | |||
| 494 | /* | 521 | /* |
| 495 | * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be | 522 | * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be |
| 496 | * called. So, this driver disables the IRQ while DMA transfer. | 523 | * called. So, this driver disables the IRQ while DMA transfer. |
| @@ -503,34 +530,24 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, | |||
| 503 | rspi_enable_irq(rspi, irq_mask); | 530 | rspi_enable_irq(rspi, irq_mask); |
| 504 | rspi->dma_callbacked = 0; | 531 | rspi->dma_callbacked = 0; |
| 505 | 532 | ||
| 506 | if (rx) { | 533 | /* Now start DMA */ |
| 507 | desc_rx->callback = rspi_dma_complete; | 534 | if (rx) |
| 508 | desc_rx->callback_param = rspi; | ||
| 509 | cookie = dmaengine_submit(desc_rx); | ||
| 510 | if (dma_submit_error(cookie)) | ||
| 511 | return cookie; | ||
| 512 | dma_async_issue_pending(rspi->master->dma_rx); | 535 | dma_async_issue_pending(rspi->master->dma_rx); |
| 513 | } | 536 | if (tx) |
| 514 | if (tx) { | ||
| 515 | if (rx) { | ||
| 516 | /* No callback */ | ||
| 517 | desc_tx->callback = NULL; | ||
| 518 | } else { | ||
| 519 | desc_tx->callback = rspi_dma_complete; | ||
| 520 | desc_tx->callback_param = rspi; | ||
| 521 | } | ||
| 522 | cookie = dmaengine_submit(desc_tx); | ||
| 523 | if (dma_submit_error(cookie)) | ||
| 524 | return cookie; | ||
| 525 | dma_async_issue_pending(rspi->master->dma_tx); | 537 | dma_async_issue_pending(rspi->master->dma_tx); |
| 526 | } | ||
| 527 | 538 | ||
| 528 | ret = wait_event_interruptible_timeout(rspi->wait, | 539 | ret = wait_event_interruptible_timeout(rspi->wait, |
| 529 | rspi->dma_callbacked, HZ); | 540 | rspi->dma_callbacked, HZ); |
| 530 | if (ret > 0 && rspi->dma_callbacked) | 541 | if (ret > 0 && rspi->dma_callbacked) |
| 531 | ret = 0; | 542 | ret = 0; |
| 532 | else if (!ret) | 543 | else if (!ret) { |
| 544 | dev_err(&rspi->master->dev, "DMA timeout\n"); | ||
| 533 | ret = -ETIMEDOUT; | 545 | ret = -ETIMEDOUT; |
| 546 | if (tx) | ||
| 547 | dmaengine_terminate_all(rspi->master->dma_tx); | ||
| 548 | if (rx) | ||
| 549 | dmaengine_terminate_all(rspi->master->dma_rx); | ||
| 550 | } | ||
| 534 | 551 | ||
| 535 | rspi_disable_irq(rspi, irq_mask); | 552 | rspi_disable_irq(rspi, irq_mask); |
| 536 | 553 | ||
| @@ -541,11 +558,16 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, | |||
| 541 | 558 | ||
| 542 | return ret; | 559 | return ret; |
| 543 | 560 | ||
| 544 | no_dma: | 561 | no_dma_tx: |
| 545 | pr_warn_once("%s %s: DMA not available, falling back to PIO\n", | 562 | if (rx) |
| 546 | dev_driver_string(&rspi->master->dev), | 563 | dmaengine_terminate_all(rspi->master->dma_rx); |
| 547 | dev_name(&rspi->master->dev)); | 564 | no_dma_rx: |
| 548 | return -EAGAIN; | 565 | if (ret == -EAGAIN) { |
| 566 | pr_warn_once("%s %s: DMA not available, falling back to PIO\n", | ||
| 567 | dev_driver_string(&rspi->master->dev), | ||
| 568 | dev_name(&rspi->master->dev)); | ||
| 569 | } | ||
| 570 | return ret; | ||
| 549 | } | 571 | } |
| 550 | 572 | ||
| 551 | static void rspi_receive_init(const struct rspi_data *rspi) | 573 | static void rspi_receive_init(const struct rspi_data *rspi) |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 2a4354dcd661..543075b80f16 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -636,48 +636,38 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
| 636 | dma_cookie_t cookie; | 636 | dma_cookie_t cookie; |
| 637 | int ret; | 637 | int ret; |
| 638 | 638 | ||
| 639 | if (tx) { | 639 | /* First prepare and submit the DMA request(s), as this may fail */ |
| 640 | ier_bits |= IER_TDREQE | IER_TDMAE; | ||
| 641 | dma_sync_single_for_device(p->master->dma_tx->device->dev, | ||
| 642 | p->tx_dma_addr, len, DMA_TO_DEVICE); | ||
| 643 | desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, | ||
| 644 | p->tx_dma_addr, len, DMA_TO_DEVICE, | ||
| 645 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 646 | if (!desc_tx) | ||
| 647 | return -EAGAIN; | ||
| 648 | } | ||
| 649 | |||
| 650 | if (rx) { | 640 | if (rx) { |
| 651 | ier_bits |= IER_RDREQE | IER_RDMAE; | 641 | ier_bits |= IER_RDREQE | IER_RDMAE; |
| 652 | desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, | 642 | desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, |
| 653 | p->rx_dma_addr, len, DMA_FROM_DEVICE, | 643 | p->rx_dma_addr, len, DMA_FROM_DEVICE, |
| 654 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 644 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 655 | if (!desc_rx) | 645 | if (!desc_rx) { |
| 656 | return -EAGAIN; | 646 | ret = -EAGAIN; |
| 657 | } | 647 | goto no_dma_rx; |
| 658 | 648 | } | |
| 659 | /* 1 stage FIFO watermarks for DMA */ | ||
| 660 | sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1); | ||
| 661 | |||
| 662 | /* setup msiof transfer mode registers (32-bit words) */ | ||
| 663 | sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4); | ||
| 664 | |||
| 665 | sh_msiof_write(p, IER, ier_bits); | ||
| 666 | |||
| 667 | reinit_completion(&p->done); | ||
| 668 | 649 | ||
| 669 | if (rx) { | ||
| 670 | desc_rx->callback = sh_msiof_dma_complete; | 650 | desc_rx->callback = sh_msiof_dma_complete; |
| 671 | desc_rx->callback_param = p; | 651 | desc_rx->callback_param = p; |
| 672 | cookie = dmaengine_submit(desc_rx); | 652 | cookie = dmaengine_submit(desc_rx); |
| 673 | if (dma_submit_error(cookie)) { | 653 | if (dma_submit_error(cookie)) { |
| 674 | ret = cookie; | 654 | ret = cookie; |
| 675 | goto stop_ier; | 655 | goto no_dma_rx; |
| 676 | } | 656 | } |
| 677 | dma_async_issue_pending(p->master->dma_rx); | ||
| 678 | } | 657 | } |
| 679 | 658 | ||
| 680 | if (tx) { | 659 | if (tx) { |
| 660 | ier_bits |= IER_TDREQE | IER_TDMAE; | ||
| 661 | dma_sync_single_for_device(p->master->dma_tx->device->dev, | ||
| 662 | p->tx_dma_addr, len, DMA_TO_DEVICE); | ||
| 663 | desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, | ||
| 664 | p->tx_dma_addr, len, DMA_TO_DEVICE, | ||
| 665 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 666 | if (!desc_tx) { | ||
| 667 | ret = -EAGAIN; | ||
| 668 | goto no_dma_tx; | ||
| 669 | } | ||
| 670 | |||
| 681 | if (rx) { | 671 | if (rx) { |
| 682 | /* No callback */ | 672 | /* No callback */ |
| 683 | desc_tx->callback = NULL; | 673 | desc_tx->callback = NULL; |
| @@ -688,15 +678,30 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
| 688 | cookie = dmaengine_submit(desc_tx); | 678 | cookie = dmaengine_submit(desc_tx); |
| 689 | if (dma_submit_error(cookie)) { | 679 | if (dma_submit_error(cookie)) { |
| 690 | ret = cookie; | 680 | ret = cookie; |
| 691 | goto stop_rx; | 681 | goto no_dma_tx; |
| 692 | } | 682 | } |
| 693 | dma_async_issue_pending(p->master->dma_tx); | ||
| 694 | } | 683 | } |
| 695 | 684 | ||
| 685 | /* 1 stage FIFO watermarks for DMA */ | ||
| 686 | sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1); | ||
| 687 | |||
| 688 | /* setup msiof transfer mode registers (32-bit words) */ | ||
| 689 | sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4); | ||
| 690 | |||
| 691 | sh_msiof_write(p, IER, ier_bits); | ||
| 692 | |||
| 693 | reinit_completion(&p->done); | ||
| 694 | |||
| 695 | /* Now start DMA */ | ||
| 696 | if (rx) | ||
| 697 | dma_async_issue_pending(p->master->dma_rx); | ||
| 698 | if (tx) | ||
| 699 | dma_async_issue_pending(p->master->dma_tx); | ||
| 700 | |||
| 696 | ret = sh_msiof_spi_start(p, rx); | 701 | ret = sh_msiof_spi_start(p, rx); |
| 697 | if (ret) { | 702 | if (ret) { |
| 698 | dev_err(&p->pdev->dev, "failed to start hardware\n"); | 703 | dev_err(&p->pdev->dev, "failed to start hardware\n"); |
| 699 | goto stop_tx; | 704 | goto stop_dma; |
| 700 | } | 705 | } |
| 701 | 706 | ||
| 702 | /* wait for tx fifo to be emptied / rx fifo to be filled */ | 707 | /* wait for tx fifo to be emptied / rx fifo to be filled */ |
| @@ -726,14 +731,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
| 726 | stop_reset: | 731 | stop_reset: |
| 727 | sh_msiof_reset_str(p); | 732 | sh_msiof_reset_str(p); |
| 728 | sh_msiof_spi_stop(p, rx); | 733 | sh_msiof_spi_stop(p, rx); |
| 729 | stop_tx: | 734 | stop_dma: |
| 730 | if (tx) | 735 | if (tx) |
| 731 | dmaengine_terminate_all(p->master->dma_tx); | 736 | dmaengine_terminate_all(p->master->dma_tx); |
| 732 | stop_rx: | 737 | no_dma_tx: |
| 733 | if (rx) | 738 | if (rx) |
| 734 | dmaengine_terminate_all(p->master->dma_rx); | 739 | dmaengine_terminate_all(p->master->dma_rx); |
| 735 | stop_ier: | ||
| 736 | sh_msiof_write(p, IER, 0); | 740 | sh_msiof_write(p, IER, 0); |
| 741 | no_dma_rx: | ||
| 737 | return ret; | 742 | return ret; |
| 738 | } | 743 | } |
| 739 | 744 | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e0531baf2782..ca935df80c88 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -848,6 +848,7 @@ out: | |||
| 848 | 848 | ||
| 849 | /** | 849 | /** |
| 850 | * spi_finalize_current_transfer - report completion of a transfer | 850 | * spi_finalize_current_transfer - report completion of a transfer |
| 851 | * @master: the master reporting completion | ||
| 851 | * | 852 | * |
| 852 | * Called by SPI drivers using the core transfer_one_message() | 853 | * Called by SPI drivers using the core transfer_one_message() |
| 853 | * implementation to notify it that the current interrupt driven | 854 | * implementation to notify it that the current interrupt driven |
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index 19396dc4ee47..bed2fedeb057 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c | |||
| @@ -38,6 +38,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { | |||
| 38 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, | 38 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, |
| 39 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, | 39 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, |
| 40 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) }, | 40 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) }, |
| 41 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4351) }, | ||
| 41 | { 0, }, | 42 | { 0, }, |
| 42 | }; | 43 | }; |
| 43 | MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); | 44 | MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2c486ea6236b..35b494f5667f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
| @@ -28,8 +28,6 @@ source "drivers/staging/et131x/Kconfig" | |||
| 28 | 28 | ||
| 29 | source "drivers/staging/slicoss/Kconfig" | 29 | source "drivers/staging/slicoss/Kconfig" |
| 30 | 30 | ||
| 31 | source "drivers/staging/usbip/Kconfig" | ||
| 32 | |||
| 33 | source "drivers/staging/wlan-ng/Kconfig" | 31 | source "drivers/staging/wlan-ng/Kconfig" |
| 34 | 32 | ||
| 35 | source "drivers/staging/comedi/Kconfig" | 33 | source "drivers/staging/comedi/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 1e1a3a10faf7..e66a5dbd9b02 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
| @@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o | |||
| 6 | obj-y += media/ | 6 | obj-y += media/ |
| 7 | obj-$(CONFIG_ET131X) += et131x/ | 7 | obj-$(CONFIG_ET131X) += et131x/ |
| 8 | obj-$(CONFIG_SLICOSS) += slicoss/ | 8 | obj-$(CONFIG_SLICOSS) += slicoss/ |
| 9 | obj-$(CONFIG_USBIP_CORE) += usbip/ | ||
| 10 | obj-$(CONFIG_PRISM2_USB) += wlan-ng/ | 9 | obj-$(CONFIG_PRISM2_USB) += wlan-ng/ |
| 11 | obj-$(CONFIG_COMEDI) += comedi/ | 10 | obj-$(CONFIG_COMEDI) += comedi/ |
| 12 | obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ | 11 | obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ |
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 9b47e66599a3..0bf0d24d12d5 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c | |||
| @@ -790,7 +790,7 @@ static int __init create_log(char *log_name, int size) | |||
| 790 | if (unlikely(ret)) { | 790 | if (unlikely(ret)) { |
| 791 | pr_err("failed to register misc device for log '%s'!\n", | 791 | pr_err("failed to register misc device for log '%s'!\n", |
| 792 | log->misc.name); | 792 | log->misc.name); |
| 793 | goto out_free_log; | 793 | goto out_free_misc_name; |
| 794 | } | 794 | } |
| 795 | 795 | ||
| 796 | pr_info("created %luK log '%s'\n", | 796 | pr_info("created %luK log '%s'\n", |
| @@ -798,6 +798,9 @@ static int __init create_log(char *log_name, int size) | |||
| 798 | 798 | ||
| 799 | return 0; | 799 | return 0; |
| 800 | 800 | ||
| 801 | out_free_misc_name: | ||
| 802 | kfree(log->misc.name); | ||
| 803 | |||
| 801 | out_free_log: | 804 | out_free_log: |
| 802 | kfree(log); | 805 | kfree(log); |
| 803 | 806 | ||
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index e7b2e0234196..69139ce7420d 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c | |||
| @@ -199,7 +199,6 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) | |||
| 199 | fence->num_fences = 1; | 199 | fence->num_fences = 1; |
| 200 | atomic_set(&fence->status, 1); | 200 | atomic_set(&fence->status, 1); |
| 201 | 201 | ||
| 202 | fence_get(&pt->base); | ||
| 203 | fence->cbs[0].sync_pt = &pt->base; | 202 | fence->cbs[0].sync_pt = &pt->base; |
| 204 | fence->cbs[0].fence = fence; | 203 | fence->cbs[0].fence = fence; |
| 205 | if (fence_add_callback(&pt->base, &fence->cbs[0].cb, | 204 | if (fence_add_callback(&pt->base, &fence->cbs[0].cb, |
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 8bf1eb485163..831b7c6fe494 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c | |||
| @@ -1421,22 +1421,16 @@ static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value) | |||
| 1421 | * @reg: the register to read | 1421 | * @reg: the register to read |
| 1422 | * @value: 16-bit value to write | 1422 | * @value: 16-bit value to write |
| 1423 | */ | 1423 | */ |
| 1424 | static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) | 1424 | static int et131x_mii_write(struct et131x_adapter *adapter, u8 addr, u8 reg, |
| 1425 | u16 value) | ||
| 1425 | { | 1426 | { |
| 1426 | struct mac_regs __iomem *mac = &adapter->regs->mac; | 1427 | struct mac_regs __iomem *mac = &adapter->regs->mac; |
| 1427 | struct phy_device *phydev = adapter->phydev; | ||
| 1428 | int status = 0; | 1428 | int status = 0; |
| 1429 | u8 addr; | ||
| 1430 | u32 delay = 0; | 1429 | u32 delay = 0; |
| 1431 | u32 mii_addr; | 1430 | u32 mii_addr; |
| 1432 | u32 mii_cmd; | 1431 | u32 mii_cmd; |
| 1433 | u32 mii_indicator; | 1432 | u32 mii_indicator; |
| 1434 | 1433 | ||
| 1435 | if (!phydev) | ||
| 1436 | return -EIO; | ||
| 1437 | |||
| 1438 | addr = phydev->addr; | ||
| 1439 | |||
| 1440 | /* Save a local copy of the registers we are dealing with so we can | 1434 | /* Save a local copy of the registers we are dealing with so we can |
| 1441 | * set them back | 1435 | * set them back |
| 1442 | */ | 1436 | */ |
| @@ -1631,17 +1625,7 @@ static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, | |||
| 1631 | struct net_device *netdev = bus->priv; | 1625 | struct net_device *netdev = bus->priv; |
| 1632 | struct et131x_adapter *adapter = netdev_priv(netdev); | 1626 | struct et131x_adapter *adapter = netdev_priv(netdev); |
| 1633 | 1627 | ||
| 1634 | return et131x_mii_write(adapter, reg, value); | 1628 | return et131x_mii_write(adapter, phy_addr, reg, value); |
| 1635 | } | ||
| 1636 | |||
| 1637 | static int et131x_mdio_reset(struct mii_bus *bus) | ||
| 1638 | { | ||
| 1639 | struct net_device *netdev = bus->priv; | ||
| 1640 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
| 1641 | |||
| 1642 | et131x_mii_write(adapter, MII_BMCR, BMCR_RESET); | ||
| 1643 | |||
| 1644 | return 0; | ||
| 1645 | } | 1629 | } |
| 1646 | 1630 | ||
| 1647 | /* et1310_phy_power_switch - PHY power control | 1631 | /* et1310_phy_power_switch - PHY power control |
| @@ -1656,18 +1640,20 @@ static int et131x_mdio_reset(struct mii_bus *bus) | |||
| 1656 | static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) | 1640 | static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) |
| 1657 | { | 1641 | { |
| 1658 | u16 data; | 1642 | u16 data; |
| 1643 | struct phy_device *phydev = adapter->phydev; | ||
| 1659 | 1644 | ||
| 1660 | et131x_mii_read(adapter, MII_BMCR, &data); | 1645 | et131x_mii_read(adapter, MII_BMCR, &data); |
| 1661 | data &= ~BMCR_PDOWN; | 1646 | data &= ~BMCR_PDOWN; |
| 1662 | if (down) | 1647 | if (down) |
| 1663 | data |= BMCR_PDOWN; | 1648 | data |= BMCR_PDOWN; |
| 1664 | et131x_mii_write(adapter, MII_BMCR, data); | 1649 | et131x_mii_write(adapter, phydev->addr, MII_BMCR, data); |
| 1665 | } | 1650 | } |
| 1666 | 1651 | ||
| 1667 | /* et131x_xcvr_init - Init the phy if we are setting it into force mode */ | 1652 | /* et131x_xcvr_init - Init the phy if we are setting it into force mode */ |
| 1668 | static void et131x_xcvr_init(struct et131x_adapter *adapter) | 1653 | static void et131x_xcvr_init(struct et131x_adapter *adapter) |
| 1669 | { | 1654 | { |
| 1670 | u16 lcr2; | 1655 | u16 lcr2; |
| 1656 | struct phy_device *phydev = adapter->phydev; | ||
| 1671 | 1657 | ||
| 1672 | /* Set the LED behavior such that LED 1 indicates speed (off = | 1658 | /* Set the LED behavior such that LED 1 indicates speed (off = |
| 1673 | * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates | 1659 | * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates |
| @@ -1688,7 +1674,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) | |||
| 1688 | else | 1674 | else |
| 1689 | lcr2 |= (LED_VAL_LINKON << LED_TXRX_SHIFT); | 1675 | lcr2 |= (LED_VAL_LINKON << LED_TXRX_SHIFT); |
| 1690 | 1676 | ||
| 1691 | et131x_mii_write(adapter, PHY_LED_2, lcr2); | 1677 | et131x_mii_write(adapter, phydev->addr, PHY_LED_2, lcr2); |
| 1692 | } | 1678 | } |
| 1693 | } | 1679 | } |
| 1694 | 1680 | ||
| @@ -3643,14 +3629,14 @@ static void et131x_adjust_link(struct net_device *netdev) | |||
| 3643 | 3629 | ||
| 3644 | et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, | 3630 | et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, |
| 3645 | ®ister18); | 3631 | ®ister18); |
| 3646 | et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, | 3632 | et131x_mii_write(adapter, phydev->addr, |
| 3647 | register18 | 0x4); | 3633 | PHY_MPHY_CONTROL_REG, register18 | 0x4); |
| 3648 | et131x_mii_write(adapter, PHY_INDEX_REG, | 3634 | et131x_mii_write(adapter, phydev->addr, PHY_INDEX_REG, |
| 3649 | register18 | 0x8402); | 3635 | register18 | 0x8402); |
| 3650 | et131x_mii_write(adapter, PHY_DATA_REG, | 3636 | et131x_mii_write(adapter, phydev->addr, PHY_DATA_REG, |
| 3651 | register18 | 511); | 3637 | register18 | 511); |
| 3652 | et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, | 3638 | et131x_mii_write(adapter, phydev->addr, |
| 3653 | register18); | 3639 | PHY_MPHY_CONTROL_REG, register18); |
| 3654 | } | 3640 | } |
| 3655 | 3641 | ||
| 3656 | et1310_config_flow_control(adapter); | 3642 | et1310_config_flow_control(adapter); |
| @@ -3662,7 +3648,8 @@ static void et131x_adjust_link(struct net_device *netdev) | |||
| 3662 | et131x_mii_read(adapter, PHY_CONFIG, ®); | 3648 | et131x_mii_read(adapter, PHY_CONFIG, ®); |
| 3663 | reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; | 3649 | reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; |
| 3664 | reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; | 3650 | reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; |
| 3665 | et131x_mii_write(adapter, PHY_CONFIG, reg); | 3651 | et131x_mii_write(adapter, phydev->addr, PHY_CONFIG, |
| 3652 | reg); | ||
| 3666 | } | 3653 | } |
| 3667 | 3654 | ||
| 3668 | et131x_set_rx_dma_timer(adapter); | 3655 | et131x_set_rx_dma_timer(adapter); |
| @@ -3675,14 +3662,14 @@ static void et131x_adjust_link(struct net_device *netdev) | |||
| 3675 | 3662 | ||
| 3676 | et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, | 3663 | et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, |
| 3677 | ®ister18); | 3664 | ®ister18); |
| 3678 | et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, | 3665 | et131x_mii_write(adapter, phydev->addr, |
| 3679 | register18 | 0x4); | 3666 | PHY_MPHY_CONTROL_REG, register18 | 0x4); |
| 3680 | et131x_mii_write(adapter, PHY_INDEX_REG, | 3667 | et131x_mii_write(adapter, phydev->addr, |
| 3681 | register18 | 0x8402); | 3668 | PHY_INDEX_REG, register18 | 0x8402); |
| 3682 | et131x_mii_write(adapter, PHY_DATA_REG, | 3669 | et131x_mii_write(adapter, phydev->addr, |
| 3683 | register18 | 511); | 3670 | PHY_DATA_REG, register18 | 511); |
| 3684 | et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, | 3671 | et131x_mii_write(adapter, phydev->addr, |
| 3685 | register18); | 3672 | PHY_MPHY_CONTROL_REG, register18); |
| 3686 | } | 3673 | } |
| 3687 | 3674 | ||
| 3688 | /* Free the packets being actively sent & stopped */ | 3675 | /* Free the packets being actively sent & stopped */ |
| @@ -4644,10 +4631,6 @@ static int et131x_pci_setup(struct pci_dev *pdev, | |||
| 4644 | /* Copy address into the net_device struct */ | 4631 | /* Copy address into the net_device struct */ |
| 4645 | memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); | 4632 | memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); |
| 4646 | 4633 | ||
| 4647 | /* Init variable for counting how long we do not have link status */ | ||
| 4648 | adapter->boot_coma = 0; | ||
| 4649 | et1310_disable_phy_coma(adapter); | ||
| 4650 | |||
| 4651 | rc = -ENOMEM; | 4634 | rc = -ENOMEM; |
| 4652 | 4635 | ||
| 4653 | /* Setup the mii_bus struct */ | 4636 | /* Setup the mii_bus struct */ |
| @@ -4663,7 +4646,6 @@ static int et131x_pci_setup(struct pci_dev *pdev, | |||
| 4663 | adapter->mii_bus->priv = netdev; | 4646 | adapter->mii_bus->priv = netdev; |
| 4664 | adapter->mii_bus->read = et131x_mdio_read; | 4647 | adapter->mii_bus->read = et131x_mdio_read; |
| 4665 | adapter->mii_bus->write = et131x_mdio_write; | 4648 | adapter->mii_bus->write = et131x_mdio_write; |
| 4666 | adapter->mii_bus->reset = et131x_mdio_reset; | ||
| 4667 | adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), | 4649 | adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), |
| 4668 | GFP_KERNEL); | 4650 | GFP_KERNEL); |
| 4669 | if (!adapter->mii_bus->irq) | 4651 | if (!adapter->mii_bus->irq) |
| @@ -4687,6 +4669,10 @@ static int et131x_pci_setup(struct pci_dev *pdev, | |||
| 4687 | /* Setup et1310 as per the documentation */ | 4669 | /* Setup et1310 as per the documentation */ |
| 4688 | et131x_adapter_setup(adapter); | 4670 | et131x_adapter_setup(adapter); |
| 4689 | 4671 | ||
| 4672 | /* Init variable for counting how long we do not have link status */ | ||
| 4673 | adapter->boot_coma = 0; | ||
| 4674 | et1310_disable_phy_coma(adapter); | ||
| 4675 | |||
| 4690 | /* We can enable interrupts now | 4676 | /* We can enable interrupts now |
| 4691 | * | 4677 | * |
| 4692 | * NOTE - Because registration of interrupt handler is done in the | 4678 | * NOTE - Because registration of interrupt handler is done in the |
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 7e3f019d7e72..4662e00b456a 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c | |||
| @@ -574,6 +574,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, | |||
| 574 | for (i = 0; i < 2; i++) { | 574 | for (i = 0; i < 2; i++) { |
| 575 | struct imx_ldb_channel *channel = &imx_ldb->channel[i]; | 575 | struct imx_ldb_channel *channel = &imx_ldb->channel[i]; |
| 576 | 576 | ||
| 577 | if (!channel->connector.funcs) | ||
| 578 | continue; | ||
| 579 | |||
| 577 | channel->connector.funcs->destroy(&channel->connector); | 580 | channel->connector.funcs->destroy(&channel->connector); |
| 578 | channel->encoder.funcs->destroy(&channel->encoder); | 581 | channel->encoder.funcs->destroy(&channel->encoder); |
| 579 | } | 582 | } |
diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 6f393a11f44d..50de10a550e9 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c | |||
| @@ -281,7 +281,8 @@ static void ipu_plane_dpms(struct ipu_plane *ipu_plane, int mode) | |||
| 281 | 281 | ||
| 282 | ipu_idmac_put(ipu_plane->ipu_ch); | 282 | ipu_idmac_put(ipu_plane->ipu_ch); |
| 283 | ipu_dmfc_put(ipu_plane->dmfc); | 283 | ipu_dmfc_put(ipu_plane->dmfc); |
| 284 | ipu_dp_put(ipu_plane->dp); | 284 | if (ipu_plane->dp) |
| 285 | ipu_dp_put(ipu_plane->dp); | ||
| 285 | } | 286 | } |
| 286 | } | 287 | } |
| 287 | 288 | ||
diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 65629579bd7d..03ab9e046784 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c | |||
| @@ -365,6 +365,7 @@ cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, | |||
| 365 | return -ENOMEM; | 365 | return -ENOMEM; |
| 366 | 366 | ||
| 367 | strncpy(sched->ws_name, name, CFS_WS_NAME_LEN); | 367 | strncpy(sched->ws_name, name, CFS_WS_NAME_LEN); |
| 368 | sched->ws_name[CFS_WS_NAME_LEN - 1] = '\0'; | ||
| 368 | sched->ws_cptab = cptab; | 369 | sched->ws_cptab = cptab; |
| 369 | sched->ws_cpt = cpt; | 370 | sched->ws_cpt = cpt; |
| 370 | 371 | ||
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 0367f5a2cfe4..0c59e26c0805 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c | |||
| @@ -568,7 +568,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, | |||
| 568 | if (sb->s_root == NULL) { | 568 | if (sb->s_root == NULL) { |
| 569 | CERROR("%s: can't make root dentry\n", | 569 | CERROR("%s: can't make root dentry\n", |
| 570 | ll_get_fsname(sb, NULL, 0)); | 570 | ll_get_fsname(sb, NULL, 0)); |
| 571 | GOTO(out_root, err = -ENOMEM); | 571 | GOTO(out_lock_cn_cb, err = -ENOMEM); |
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | sbi->ll_sdev_orig = sb->s_dev; | 574 | sbi->ll_sdev_orig = sb->s_dev; |
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 8b19f3caa68f..701c6a776524 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #define DEBUG_SUBSYSTEM S_CLASS | 37 | #define DEBUG_SUBSYSTEM S_CLASS |
| 38 | # include <asm/atomic.h> | 38 | # include <linux/atomic.h> |
| 39 | 39 | ||
| 40 | #include "../include/obd_support.h" | 40 | #include "../include/obd_support.h" |
| 41 | #include "../include/obd_class.h" | 41 | #include "../include/obd_class.h" |
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index b8676ac77b0c..407a318b09db 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c | |||
| @@ -43,9 +43,11 @@ static struct usb_device_id rtw_usb_id_tbl[] = { | |||
| 43 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ | 43 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ |
| 44 | /*=== Customer ID ===*/ | 44 | /*=== Customer ID ===*/ |
| 45 | /****** 8188EUS ********/ | 45 | /****** 8188EUS ********/ |
| 46 | {USB_DEVICE(0x056e, 0x4008)}, /* Elecom WDC-150SU2M */ | ||
| 46 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ | 47 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ |
| 47 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ | 48 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ |
| 48 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ | 49 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ |
| 50 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ | ||
| 49 | {} /* Terminating entry */ | 51 | {} /* Terminating entry */ |
| 50 | }; | 52 | }; |
| 51 | 53 | ||
diff --git a/drivers/staging/usbip/uapi/usbip.h b/drivers/staging/usbip/uapi/usbip.h deleted file mode 100644 index fa5db30ede36..000000000000 --- a/drivers/staging/usbip/uapi/usbip.h +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * usbip.h | ||
| 3 | * | ||
| 4 | * USBIP uapi defines and function prototypes etc. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef _UAPI_LINUX_USBIP_H | ||
| 8 | #define _UAPI_LINUX_USBIP_H | ||
| 9 | |||
| 10 | /* usbip device status - exported in usbip device sysfs status */ | ||
| 11 | enum usbip_device_status { | ||
| 12 | /* sdev is available. */ | ||
| 13 | SDEV_ST_AVAILABLE = 0x01, | ||
| 14 | /* sdev is now used. */ | ||
| 15 | SDEV_ST_USED, | ||
| 16 | /* sdev is unusable because of a fatal error. */ | ||
| 17 | SDEV_ST_ERROR, | ||
| 18 | |||
| 19 | /* vdev does not connect a remote device. */ | ||
| 20 | VDEV_ST_NULL, | ||
| 21 | /* vdev is used, but the USB address is not assigned yet */ | ||
| 22 | VDEV_ST_NOTASSIGNED, | ||
| 23 | VDEV_ST_USED, | ||
| 24 | VDEV_ST_ERROR | ||
| 25 | }; | ||
| 26 | #endif /* _UAPI_LINUX_USBIP_H */ | ||
diff --git a/drivers/staging/usbip/userspace/.gitignore b/drivers/staging/usbip/userspace/.gitignore deleted file mode 100644 index 9aad9e30a8ba..000000000000 --- a/drivers/staging/usbip/userspace/.gitignore +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | Makefile | ||
| 2 | Makefile.in | ||
| 3 | aclocal.m4 | ||
| 4 | autom4te.cache/ | ||
| 5 | config.guess | ||
| 6 | config.h | ||
| 7 | config.h.in | ||
| 8 | config.log | ||
| 9 | config.status | ||
| 10 | config.sub | ||
| 11 | configure | ||
| 12 | depcomp | ||
| 13 | install-sh | ||
| 14 | libsrc/Makefile | ||
| 15 | libsrc/Makefile.in | ||
| 16 | libtool | ||
| 17 | ltmain.sh | ||
| 18 | missing | ||
| 19 | src/Makefile | ||
| 20 | src/Makefile.in | ||
| 21 | stamp-h1 | ||
| 22 | libsrc/libusbip.la | ||
| 23 | libsrc/libusbip_la-names.lo | ||
| 24 | libsrc/libusbip_la-usbip_common.lo | ||
| 25 | libsrc/libusbip_la-usbip_host_driver.lo | ||
| 26 | libsrc/libusbip_la-vhci_driver.lo | ||
| 27 | src/usbip | ||
| 28 | src/usbipd | ||
diff --git a/drivers/staging/usbip/userspace/AUTHORS b/drivers/staging/usbip/userspace/AUTHORS deleted file mode 100644 index a27ea8d03aec..000000000000 --- a/drivers/staging/usbip/userspace/AUTHORS +++ /dev/null | |||
| @@ -1,3 +0,0 @@ | |||
| 1 | Takahiro Hirofuchi | ||
| 2 | Robert Leibl | ||
| 3 | matt mooney <mfm@muteddisk.com> | ||
diff --git a/drivers/staging/usbip/userspace/COPYING b/drivers/staging/usbip/userspace/COPYING deleted file mode 100644 index c5611e48a8e1..000000000000 --- a/drivers/staging/usbip/userspace/COPYING +++ /dev/null | |||
| @@ -1,340 +0,0 @@ | |||
| 1 | GNU GENERAL PUBLIC LICENSE | ||
| 2 | Version 2, June 1991 | ||
| 3 | |||
| 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||
| 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 6 | Everyone is permitted to copy and distribute verbatim copies | ||
| 7 | of this license document, but changing it is not allowed. | ||
| 8 | |||
| 9 | Preamble | ||
| 10 | |||
| 11 | The licenses for most software are designed to take away your | ||
| 12 | freedom to share and change it. By contrast, the GNU General Public | ||
| 13 | License is intended to guarantee your freedom to share and change free | ||
| 14 | software--to make sure the software is free for all its users. This | ||
| 15 | General Public License applies to most of the Free Software | ||
| 16 | Foundation's software and to any other program whose authors commit to | ||
| 17 | using it. (Some other Free Software Foundation software is covered by | ||
| 18 | the GNU Library General Public License instead.) You can apply it to | ||
| 19 | your programs, too. | ||
| 20 | |||
| 21 | When we speak of free software, we are referring to freedom, not | ||
| 22 | price. Our General Public Licenses are designed to make sure that you | ||
| 23 | have the freedom to distribute copies of free software (and charge for | ||
| 24 | this service if you wish), that you receive source code or can get it | ||
| 25 | if you want it, that you can change the software or use pieces of it | ||
| 26 | in new free programs; and that you know you can do these things. | ||
| 27 | |||
| 28 | To protect your rights, we need to make restrictions that forbid | ||
| 29 | anyone to deny you these rights or to ask you to surrender the rights. | ||
| 30 | These restrictions translate to certain responsibilities for you if you | ||
| 31 | distribute copies of the software, or if you modify it. | ||
| 32 | |||
| 33 | For example, if you distribute copies of such a program, whether | ||
| 34 | gratis or for a fee, you must give the recipients all the rights that | ||
| 35 | you have. You must make sure that they, too, receive or can get the | ||
| 36 | source code. And you must show them these terms so they know their | ||
| 37 | rights. | ||
| 38 | |||
| 39 | We protect your rights with two steps: (1) copyright the software, and | ||
| 40 | (2) offer you this license which gives you legal permission to copy, | ||
| 41 | distribute and/or modify the software. | ||
| 42 | |||
| 43 | Also, for each author's protection and ours, we want to make certain | ||
| 44 | that everyone understands that there is no warranty for this free | ||
| 45 | software. If the software is modified by someone else and passed on, we | ||
| 46 | want its recipients to know that what they have is not the original, so | ||
| 47 | that any problems introduced by others will not reflect on the original | ||
| 48 | authors' reputations. | ||
| 49 | |||
| 50 | Finally, any free program is threatened constantly by software | ||
| 51 | patents. We wish to avoid the danger that redistributors of a free | ||
| 52 | program will individually obtain patent licenses, in effect making the | ||
| 53 | program proprietary. To prevent this, we have made it clear that any | ||
| 54 | patent must be licensed for everyone's free use or not licensed at all. | ||
| 55 | |||
| 56 | The precise terms and conditions for copying, distribution and | ||
| 57 | modification follow. | ||
| 58 | |||
| 59 | GNU GENERAL PUBLIC LICENSE | ||
| 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
| 61 | |||
| 62 | 0. This License applies to any program or other work which contains | ||
| 63 | a notice placed by the copyright holder saying it may be distributed | ||
| 64 | under the terms of this General Public License. The "Program", below, | ||
| 65 | refers to any such program or work, and a "work based on the Program" | ||
| 66 | means either the Program or any derivative work under copyright law: | ||
| 67 | that is to say, a work containing the Program or a portion of it, | ||
| 68 | either verbatim or with modifications and/or translated into another | ||
| 69 | language. (Hereinafter, translation is included without limitation in | ||
| 70 | the term "modification".) Each licensee is addressed as "you". | ||
| 71 | |||
| 72 | Activities other than copying, distribution and modification are not | ||
| 73 | covered by this License; they are outside its scope. The act of | ||
| 74 | running the Program is not restricted, and the output from the Program | ||
| 75 | is covered only if its contents constitute a work based on the | ||
| 76 | Program (independent of having been made by running the Program). | ||
| 77 | Whether that is true depends on what the Program does. | ||
| 78 | |||
| 79 | 1. You may copy and distribute verbatim copies of the Program's | ||
| 80 | source code as you receive it, in any medium, provided that you | ||
| 81 | conspicuously and appropriately publish on each copy an appropriate | ||
| 82 | copyright notice and disclaimer of warranty; keep intact all the | ||
| 83 | notices that refer to this License and to the absence of any warranty; | ||
| 84 | and give any other recipients of the Program a copy of this License | ||
| 85 | along with the Program. | ||
| 86 | |||
| 87 | You may charge a fee for the physical act of transferring a copy, and | ||
| 88 | you may at your option offer warranty protection in exchange for a fee. | ||
| 89 | |||
| 90 | 2. You may modify your copy or copies of the Program or any portion | ||
| 91 | of it, thus forming a work based on the Program, and copy and | ||
| 92 | distribute such modifications or work under the terms of Section 1 | ||
| 93 | above, provided that you also meet all of these conditions: | ||
| 94 | |||
| 95 | a) You must cause the modified files to carry prominent notices | ||
| 96 | stating that you changed the files and the date of any change. | ||
| 97 | |||
| 98 | b) You must cause any work that you distribute or publish, that in | ||
| 99 | whole or in part contains or is derived from the Program or any | ||
| 100 | part thereof, to be licensed as a whole at no charge to all third | ||
| 101 | parties under the terms of this License. | ||
| 102 | |||
| 103 | c) If the modified program normally reads commands interactively | ||
| 104 | when run, you must cause it, when started running for such | ||
| 105 | interactive use in the most ordinary way, to print or display an | ||
| 106 | announcement including an appropriate copyright notice and a | ||
| 107 | notice that there is no warranty (or else, saying that you provide | ||
| 108 | a warranty) and that users may redistribute the program under | ||
| 109 | these conditions, and telling the user how to view a copy of this | ||
| 110 | License. (Exception: if the Program itself is interactive but | ||
| 111 | does not normally print such an announcement, your work based on | ||
| 112 | the Program is not required to print an announcement.) | ||
| 113 | |||
| 114 | These requirements apply to the modified work as a whole. If | ||
| 115 | identifiable sections of that work are not derived from the Program, | ||
| 116 | and can be reasonably considered independent and separate works in | ||
| 117 | themselves, then this License, and its terms, do not apply to those | ||
| 118 | sections when you distribute them as separate works. But when you | ||
| 119 | distribute the same sections as part of a whole which is a work based | ||
| 120 | on the Program, the distribution of the whole must be on the terms of | ||
| 121 | this License, whose permissions for other licensees extend to the | ||
| 122 | entire whole, and thus to each and every part regardless of who wrote it. | ||
| 123 | |||
| 124 | Thus, it is not the intent of this section to claim rights or contest | ||
| 125 | your rights to work written entirely by you; rather, the intent is to | ||
| 126 | exercise the right to control the distribution of derivative or | ||
| 127 | collective works based on the Program. | ||
| 128 | |||
| 129 | In addition, mere aggregation of another work not based on the Program | ||
| 130 | with the Program (or with a work based on the Program) on a volume of | ||
| 131 | a storage or distribution medium does not bring the other work under | ||
| 132 | the scope of this License. | ||
| 133 | |||
| 134 | 3. You may copy and distribute the Program (or a work based on it, | ||
| 135 | under Section 2) in object code or executable form under the terms of | ||
| 136 | Sections 1 and 2 above provided that you also do one of the following: | ||
| 137 | |||
| 138 | a) Accompany it with the complete corresponding machine-readable | ||
| 139 | source code, which must be distributed under the terms of Sections | ||
| 140 | 1 and 2 above on a medium customarily used for software interchange; or, | ||
| 141 | |||
| 142 | b) Accompany it with a written offer, valid for at least three | ||
| 143 | years, to give any third party, for a charge no more than your | ||
| 144 | cost of physically performing source distribution, a complete | ||
| 145 | machine-readable copy of the corresponding source code, to be | ||
| 146 | distributed under the terms of Sections 1 and 2 above on a medium | ||
| 147 | customarily used for software interchange; or, | ||
| 148 | |||
| 149 | c) Accompany it with the information you received as to the offer | ||
| 150 | to distribute corresponding source code. (This alternative is | ||
| 151 | allowed only for noncommercial distribution and only if you | ||
| 152 | received the program in object code or executable form with such | ||
| 153 | an offer, in accord with Subsection b above.) | ||
| 154 | |||
| 155 | The source code for a work means the preferred form of the work for | ||
| 156 | making modifications to it. For an executable work, complete source | ||
| 157 | code means all the source code for all modules it contains, plus any | ||
| 158 | associated interface definition files, plus the scripts used to | ||
| 159 | control compilation and installation of the executable. However, as a | ||
| 160 | special exception, the source code distributed need not include | ||
| 161 | anything that is normally distributed (in either source or binary | ||
| 162 | form) with the major components (compiler, kernel, and so on) of the | ||
| 163 | operating system on which the executable runs, unless that component | ||
| 164 | itself accompanies the executable. | ||
| 165 | |||
| 166 | If distribution of executable or object code is made by offering | ||
| 167 | access to copy from a designated place, then offering equivalent | ||
| 168 | access to copy the source code from the same place counts as | ||
| 169 | distribution of the source code, even though third parties are not | ||
| 170 | compelled to copy the source along with the object code. | ||
| 171 | |||
| 172 | 4. You may not copy, modify, sublicense, or distribute the Program | ||
| 173 | except as expressly provided under this License. Any attempt | ||
| 174 | otherwise to copy, modify, sublicense or distribute the Program is | ||
| 175 | void, and will automatically terminate your rights under this License. | ||
| 176 | However, parties who have received copies, or rights, from you under | ||
| 177 | this License will not have their licenses terminated so long as such | ||
| 178 | parties remain in full compliance. | ||
| 179 | |||
| 180 | 5. You are not required to accept this License, since you have not | ||
| 181 | signed it. However, nothing else grants you permission to modify or | ||
| 182 | distribute the Program or its derivative works. These actions are | ||
| 183 | prohibited by law if you do not accept this License. Therefore, by | ||
| 184 | modifying or distributing the Program (or any work based on the | ||
| 185 | Program), you indicate your acceptance of this License to do so, and | ||
| 186 | all its terms and conditions for copying, distributing or modifying | ||
| 187 | the Program or works based on it. | ||
| 188 | |||
| 189 | 6. Each time you redistribute the Program (or any work based on the | ||
| 190 | Program), the recipient automatically receives a license from the | ||
| 191 | original licensor to copy, distribute or modify the Program subject to | ||
| 192 | these terms and conditions. You may not impose any further | ||
| 193 | restrictions on the recipients' exercise of the rights granted herein. | ||
| 194 | You are not responsible for enforcing compliance by third parties to | ||
| 195 | this License. | ||
| 196 | |||
| 197 | 7. If, as a consequence of a court judgment or allegation of patent | ||
| 198 | infringement or for any other reason (not limited to patent issues), | ||
| 199 | conditions are imposed on you (whether by court order, agreement or | ||
| 200 | otherwise) that contradict the conditions of this License, they do not | ||
| 201 | excuse you from the conditions of this License. If you cannot | ||
| 202 | distribute so as to satisfy simultaneously your obligations under this | ||
| 203 | License and any other pertinent obligations, then as a consequence you | ||
| 204 | may not distribute the Program at all. For example, if a patent | ||
| 205 | license would not permit royalty-free redistribution of the Program by | ||
| 206 | all those who receive copies directly or indirectly through you, then | ||
| 207 | the only way you could satisfy both it and this License would be to | ||
| 208 | refrain entirely from distribution of the Program. | ||
| 209 | |||
| 210 | If any portion of this section is held invalid or unenforceable under | ||
| 211 | any particular circumstance, the balance of the section is intended to | ||
| 212 | apply and the section as a whole is intended to apply in other | ||
| 213 | circumstances. | ||
| 214 | |||
| 215 | It is not the purpose of this section to induce you to infringe any | ||
| 216 | patents or other property right claims or to contest validity of any | ||
| 217 | such claims; this section has the sole purpose of protecting the | ||
| 218 | integrity of the free software distribution system, which is | ||
| 219 | implemented by public license practices. Many people have made | ||
| 220 | generous contributions to the wide range of software distributed | ||
| 221 | through that system in reliance on consistent application of that | ||
| 222 | system; it is up to the author/donor to decide if he or she is willing | ||
| 223 | to distribute software through any other system and a licensee cannot | ||
| 224 | impose that choice. | ||
| 225 | |||
| 226 | This section is intended to make thoroughly clear what is believed to | ||
| 227 | be a consequence of the rest of this License. | ||
| 228 | |||
| 229 | 8. If the distribution and/or use of the Program is restricted in | ||
| 230 | certain countries either by patents or by copyrighted interfaces, the | ||
| 231 | original copyright holder who places the Program under this License | ||
| 232 | may add an explicit geographical distribution limitation excluding | ||
| 233 | those countries, so that distribution is permitted only in or among | ||
| 234 | countries not thus excluded. In such case, this License incorporates | ||
| 235 | the limitation as if written in the body of this License. | ||
| 236 | |||
| 237 | 9. The Free Software Foundation may publish revised and/or new versions | ||
| 238 | of the General Public License from time to time. Such new versions will | ||
| 239 | be similar in spirit to the present version, but may differ in detail to | ||
| 240 | address new problems or concerns. | ||
| 241 | |||
| 242 | Each version is given a distinguishing version number. If the Program | ||
| 243 | specifies a version number of this License which applies to it and "any | ||
| 244 | later version", you have the option of following the terms and conditions | ||
| 245 | either of that version or of any later version published by the Free | ||
| 246 | Software Foundation. If the Program does not specify a version number of | ||
| 247 | this License, you may choose any version ever published by the Free Software | ||
| 248 | Foundation. | ||
| 249 | |||
| 250 | 10. If you wish to incorporate parts of the Program into other free | ||
| 251 | programs whose distribution conditions are different, write to the author | ||
| 252 | to ask for permission. For software which is copyrighted by the Free | ||
| 253 | Software Foundation, write to the Free Software Foundation; we sometimes | ||
| 254 | make exceptions for this. Our decision will be guided by the two goals | ||
| 255 | of preserving the free status of all derivatives of our free software and | ||
| 256 | of promoting the sharing and reuse of software generally. | ||
| 257 | |||
| 258 | NO WARRANTY | ||
| 259 | |||
| 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||
| 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
| 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
| 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
| 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||
| 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | ||
| 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||
| 268 | REPAIR OR CORRECTION. | ||
| 269 | |||
| 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
| 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
| 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
| 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
| 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||
| 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||
| 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
| 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
| 278 | POSSIBILITY OF SUCH DAMAGES. | ||
| 279 | |||
| 280 | END OF TERMS AND CONDITIONS | ||
| 281 | |||
| 282 | How to Apply These Terms to Your New Programs | ||
| 283 | |||
| 284 | If you develop a new program, and you want it to be of the greatest | ||
| 285 | possible use to the public, the best way to achieve this is to make it | ||
| 286 | free software which everyone can redistribute and change under these terms. | ||
| 287 | |||
| 288 | To do so, attach the following notices to the program. It is safest | ||
| 289 | to attach them to the start of each source file to most effectively | ||
| 290 | convey the exclusion of warranty; and each file should have at least | ||
| 291 | the "copyright" line and a pointer to where the full notice is found. | ||
| 292 | |||
| 293 | <one line to give the program's name and a brief idea of what it does.> | ||
| 294 | Copyright (C) <year> <name of author> | ||
| 295 | |||
| 296 | This program is free software; you can redistribute it and/or modify | ||
| 297 | it under the terms of the GNU General Public License as published by | ||
| 298 | the Free Software Foundation; either version 2 of the License, or | ||
| 299 | (at your option) any later version. | ||
| 300 | |||
| 301 | This program is distributed in the hope that it will be useful, | ||
| 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 304 | GNU General Public License for more details. | ||
| 305 | |||
| 306 | You should have received a copy of the GNU General Public License | ||
| 307 | along with this program; if not, write to the Free Software | ||
| 308 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 309 | |||
| 310 | |||
| 311 | Also add information on how to contact you by electronic and paper mail. | ||
| 312 | |||
| 313 | If the program is interactive, make it output a short notice like this | ||
| 314 | when it starts in an interactive mode: | ||
| 315 | |||
| 316 | Gnomovision version 69, Copyright (C) year name of author | ||
| 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
| 318 | This is free software, and you are welcome to redistribute it | ||
| 319 | under certain conditions; type `show c' for details. | ||
| 320 | |||
| 321 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
| 322 | parts of the General Public License. Of course, the commands you use may | ||
| 323 | be called something other than `show w' and `show c'; they could even be | ||
| 324 | mouse-clicks or menu items--whatever suits your program. | ||
| 325 | |||
| 326 | You should also get your employer (if you work as a programmer) or your | ||
| 327 | school, if any, to sign a "copyright disclaimer" for the program, if | ||
| 328 | necessary. Here is a sample; alter the names: | ||
| 329 | |||
| 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||
| 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||
| 332 | |||
| 333 | <signature of Ty Coon>, 1 April 1989 | ||
| 334 | Ty Coon, President of Vice | ||
| 335 | |||
| 336 | This General Public License does not permit incorporating your program into | ||
| 337 | proprietary programs. If your program is a subroutine library, you may | ||
| 338 | consider it more useful to permit linking proprietary applications with the | ||
| 339 | library. If this is what you want to do, use the GNU Library General | ||
| 340 | Public License instead of this License. | ||
diff --git a/drivers/staging/usbip/userspace/INSTALL b/drivers/staging/usbip/userspace/INSTALL deleted file mode 100644 index d3c5b40a9409..000000000000 --- a/drivers/staging/usbip/userspace/INSTALL +++ /dev/null | |||
| @@ -1,237 +0,0 @@ | |||
| 1 | Installation Instructions | ||
| 2 | ************************* | ||
| 3 | |||
| 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, | ||
| 5 | 2006, 2007 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free documentation; the Free Software Foundation gives | ||
| 8 | unlimited permission to copy, distribute and modify it. | ||
| 9 | |||
| 10 | Basic Installation | ||
| 11 | ================== | ||
| 12 | |||
| 13 | Briefly, the shell commands `./configure; make; make install' should | ||
| 14 | configure, build, and install this package. The following | ||
| 15 | more-detailed instructions are generic; see the `README' file for | ||
| 16 | instructions specific to this package. | ||
| 17 | |||
| 18 | The `configure' shell script attempts to guess correct values for | ||
| 19 | various system-dependent variables used during compilation. It uses | ||
| 20 | those values to create a `Makefile' in each directory of the package. | ||
| 21 | It may also create one or more `.h' files containing system-dependent | ||
| 22 | definitions. Finally, it creates a shell script `config.status' that | ||
| 23 | you can run in the future to recreate the current configuration, and a | ||
| 24 | file `config.log' containing compiler output (useful mainly for | ||
| 25 | debugging `configure'). | ||
| 26 | |||
| 27 | It can also use an optional file (typically called `config.cache' | ||
| 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves | ||
| 29 | the results of its tests to speed up reconfiguring. Caching is | ||
| 30 | disabled by default to prevent problems with accidental use of stale | ||
| 31 | cache files. | ||
| 32 | |||
| 33 | If you need to do unusual things to compile the package, please try | ||
| 34 | to figure out how `configure' could check whether to do them, and mail | ||
| 35 | diffs or instructions to the address given in the `README' so they can | ||
| 36 | be considered for the next release. If you are using the cache, and at | ||
| 37 | some point `config.cache' contains results you don't want to keep, you | ||
| 38 | may remove or edit it. | ||
| 39 | |||
| 40 | The file `configure.ac' (or `configure.in') is used to create | ||
| 41 | `configure' by a program called `autoconf'. You need `configure.ac' if | ||
| 42 | you want to change it or regenerate `configure' using a newer version | ||
| 43 | of `autoconf'. | ||
| 44 | |||
| 45 | The simplest way to compile this package is: | ||
| 46 | |||
| 47 | 1. `cd' to the directory containing the package's source code and type | ||
| 48 | `./configure' to configure the package for your system. | ||
| 49 | |||
| 50 | Running `configure' might take a while. While running, it prints | ||
| 51 | some messages telling which features it is checking for. | ||
| 52 | |||
| 53 | 2. Type `make' to compile the package. | ||
| 54 | |||
| 55 | 3. Optionally, type `make check' to run any self-tests that come with | ||
| 56 | the package. | ||
| 57 | |||
| 58 | 4. Type `make install' to install the programs and any data files and | ||
| 59 | documentation. | ||
| 60 | |||
| 61 | 5. You can remove the program binaries and object files from the | ||
| 62 | source code directory by typing `make clean'. To also remove the | ||
| 63 | files that `configure' created (so you can compile the package for | ||
| 64 | a different kind of computer), type `make distclean'. There is | ||
| 65 | also a `make maintainer-clean' target, but that is intended mainly | ||
| 66 | for the package's developers. If you use it, you may have to get | ||
| 67 | all sorts of other programs in order to regenerate files that came | ||
| 68 | with the distribution. | ||
| 69 | |||
| 70 | 6. Often, you can also type `make uninstall' to remove the installed | ||
| 71 | files again. | ||
| 72 | |||
| 73 | Compilers and Options | ||
| 74 | ===================== | ||
| 75 | |||
| 76 | Some systems require unusual options for compilation or linking that the | ||
| 77 | `configure' script does not know about. Run `./configure --help' for | ||
| 78 | details on some of the pertinent environment variables. | ||
| 79 | |||
| 80 | You can give `configure' initial values for configuration parameters | ||
| 81 | by setting variables in the command line or in the environment. Here | ||
| 82 | is an example: | ||
| 83 | |||
| 84 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix | ||
| 85 | |||
| 86 | *Note Defining Variables::, for more details. | ||
| 87 | |||
| 88 | Compiling For Multiple Architectures | ||
| 89 | ==================================== | ||
| 90 | |||
| 91 | You can compile the package for more than one kind of computer at the | ||
| 92 | same time, by placing the object files for each architecture in their | ||
| 93 | own directory. To do this, you can use GNU `make'. `cd' to the | ||
| 94 | directory where you want the object files and executables to go and run | ||
| 95 | the `configure' script. `configure' automatically checks for the | ||
| 96 | source code in the directory that `configure' is in and in `..'. | ||
| 97 | |||
| 98 | With a non-GNU `make', it is safer to compile the package for one | ||
| 99 | architecture at a time in the source code directory. After you have | ||
| 100 | installed the package for one architecture, use `make distclean' before | ||
| 101 | reconfiguring for another architecture. | ||
| 102 | |||
| 103 | Installation Names | ||
| 104 | ================== | ||
| 105 | |||
| 106 | By default, `make install' installs the package's commands under | ||
| 107 | `/usr/local/bin', include files under `/usr/local/include', etc. You | ||
| 108 | can specify an installation prefix other than `/usr/local' by giving | ||
| 109 | `configure' the option `--prefix=PREFIX'. | ||
| 110 | |||
| 111 | You can specify separate installation prefixes for | ||
| 112 | architecture-specific files and architecture-independent files. If you | ||
| 113 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses | ||
| 114 | PREFIX as the prefix for installing programs and libraries. | ||
| 115 | Documentation and other data files still use the regular prefix. | ||
| 116 | |||
| 117 | In addition, if you use an unusual directory layout you can give | ||
| 118 | options like `--bindir=DIR' to specify different values for particular | ||
| 119 | kinds of files. Run `configure --help' for a list of the directories | ||
| 120 | you can set and what kinds of files go in them. | ||
| 121 | |||
| 122 | If the package supports it, you can cause programs to be installed | ||
| 123 | with an extra prefix or suffix on their names by giving `configure' the | ||
| 124 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. | ||
| 125 | |||
| 126 | Optional Features | ||
| 127 | ================= | ||
| 128 | |||
| 129 | Some packages pay attention to `--enable-FEATURE' options to | ||
| 130 | `configure', where FEATURE indicates an optional part of the package. | ||
| 131 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE | ||
| 132 | is something like `gnu-as' or `x' (for the X Window System). The | ||
| 133 | `README' should mention any `--enable-' and `--with-' options that the | ||
| 134 | package recognizes. | ||
| 135 | |||
| 136 | For packages that use the X Window System, `configure' can usually | ||
| 137 | find the X include and library files automatically, but if it doesn't, | ||
| 138 | you can use the `configure' options `--x-includes=DIR' and | ||
| 139 | `--x-libraries=DIR' to specify their locations. | ||
| 140 | |||
| 141 | Specifying the System Type | ||
| 142 | ========================== | ||
| 143 | |||
| 144 | There may be some features `configure' cannot figure out automatically, | ||
| 145 | but needs to determine by the type of machine the package will run on. | ||
| 146 | Usually, assuming the package is built to be run on the _same_ | ||
| 147 | architectures, `configure' can figure that out, but if it prints a | ||
| 148 | message saying it cannot guess the machine type, give it the | ||
| 149 | `--build=TYPE' option. TYPE can either be a short name for the system | ||
| 150 | type, such as `sun4', or a canonical name which has the form: | ||
| 151 | |||
| 152 | CPU-COMPANY-SYSTEM | ||
| 153 | |||
| 154 | where SYSTEM can have one of these forms: | ||
| 155 | |||
| 156 | OS KERNEL-OS | ||
| 157 | |||
| 158 | See the file `config.sub' for the possible values of each field. If | ||
| 159 | `config.sub' isn't included in this package, then this package doesn't | ||
| 160 | need to know the machine type. | ||
| 161 | |||
| 162 | If you are _building_ compiler tools for cross-compiling, you should | ||
| 163 | use the option `--target=TYPE' to select the type of system they will | ||
| 164 | produce code for. | ||
| 165 | |||
| 166 | If you want to _use_ a cross compiler, that generates code for a | ||
| 167 | platform different from the build platform, you should specify the | ||
| 168 | "host" platform (i.e., that on which the generated programs will | ||
| 169 | eventually be run) with `--host=TYPE'. | ||
| 170 | |||
| 171 | Sharing Defaults | ||
| 172 | ================ | ||
| 173 | |||
| 174 | If you want to set default values for `configure' scripts to share, you | ||
| 175 | can create a site shell script called `config.site' that gives default | ||
| 176 | values for variables like `CC', `cache_file', and `prefix'. | ||
| 177 | `configure' looks for `PREFIX/share/config.site' if it exists, then | ||
| 178 | `PREFIX/etc/config.site' if it exists. Or, you can set the | ||
| 179 | `CONFIG_SITE' environment variable to the location of the site script. | ||
| 180 | A warning: not all `configure' scripts look for a site script. | ||
| 181 | |||
| 182 | Defining Variables | ||
| 183 | ================== | ||
| 184 | |||
| 185 | Variables not defined in a site shell script can be set in the | ||
| 186 | environment passed to `configure'. However, some packages may run | ||
| 187 | configure again during the build, and the customized values of these | ||
| 188 | variables may be lost. In order to avoid this problem, you should set | ||
| 189 | them in the `configure' command line, using `VAR=value'. For example: | ||
| 190 | |||
| 191 | ./configure CC=/usr/local2/bin/gcc | ||
| 192 | |||
| 193 | causes the specified `gcc' to be used as the C compiler (unless it is | ||
| 194 | overridden in the site shell script). | ||
| 195 | |||
| 196 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to | ||
| 197 | an Autoconf bug. Until the bug is fixed you can use this workaround: | ||
| 198 | |||
| 199 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash | ||
| 200 | |||
| 201 | `configure' Invocation | ||
| 202 | ====================== | ||
| 203 | |||
| 204 | `configure' recognizes the following options to control how it operates. | ||
| 205 | |||
| 206 | `--help' | ||
| 207 | `-h' | ||
| 208 | Print a summary of the options to `configure', and exit. | ||
| 209 | |||
| 210 | `--version' | ||
| 211 | `-V' | ||
| 212 | Print the version of Autoconf used to generate the `configure' | ||
| 213 | script, and exit. | ||
| 214 | |||
| 215 | `--cache-file=FILE' | ||
| 216 | Enable the cache: use and save the results of the tests in FILE, | ||
| 217 | traditionally `config.cache'. FILE defaults to `/dev/null' to | ||
| 218 | disable caching. | ||
| 219 | |||
| 220 | `--config-cache' | ||
| 221 | `-C' | ||
| 222 | Alias for `--cache-file=config.cache'. | ||
| 223 | |||
| 224 | `--quiet' | ||
| 225 | `--silent' | ||
| 226 | `-q' | ||
| 227 | Do not print messages saying which checks are being made. To | ||
| 228 | suppress all normal output, redirect it to `/dev/null' (any error | ||
| 229 | messages will still be shown). | ||
| 230 | |||
| 231 | `--srcdir=DIR' | ||
| 232 | Look for the package's source code in directory DIR. Usually | ||
| 233 | `configure' can determine that directory automatically. | ||
| 234 | |||
| 235 | `configure' also accepts some other, not widely useful, options. Run | ||
| 236 | `configure --help' for more details. | ||
| 237 | |||
diff --git a/drivers/staging/usbip/userspace/Makefile.am b/drivers/staging/usbip/userspace/Makefile.am deleted file mode 100644 index 66f8bf038c9f..000000000000 --- a/drivers/staging/usbip/userspace/Makefile.am +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | SUBDIRS := libsrc src | ||
| 2 | includedir = @includedir@/usbip | ||
| 3 | include_HEADERS := $(addprefix libsrc/, \ | ||
| 4 | usbip_common.h vhci_driver.h usbip_host_driver.h) | ||
| 5 | |||
| 6 | dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) | ||
diff --git a/drivers/staging/usbip/userspace/README b/drivers/staging/usbip/userspace/README deleted file mode 100644 index 831f49fea3ce..000000000000 --- a/drivers/staging/usbip/userspace/README +++ /dev/null | |||
| @@ -1,202 +0,0 @@ | |||
| 1 | # | ||
| 2 | # README for usbip-utils | ||
| 3 | # | ||
| 4 | # Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 5 | # 2005-2008 Takahiro Hirofuchi | ||
| 6 | |||
| 7 | |||
| 8 | [Requirements] | ||
| 9 | - USB/IP device drivers | ||
| 10 | Found in the staging directory of the Linux kernel. | ||
| 11 | |||
| 12 | - libudev >= 2.0 | ||
| 13 | libudev library | ||
| 14 | |||
| 15 | - libwrap0-dev | ||
| 16 | tcp wrapper library | ||
| 17 | |||
| 18 | - gcc >= 4.0 | ||
| 19 | |||
| 20 | - libtool, automake >= 1.9, autoconf >= 2.5.0, pkg-config | ||
| 21 | |||
| 22 | [Optional] | ||
| 23 | - hwdata | ||
| 24 | Contains USB device identification data. | ||
| 25 | |||
| 26 | |||
| 27 | [Install] | ||
| 28 | 0. Generate configuration scripts. | ||
| 29 | $ ./autogen.sh | ||
| 30 | |||
| 31 | 1. Compile & install the userspace utilities. | ||
| 32 | $ ./configure [--with-tcp-wrappers=no] [--with-usbids-dir=<dir>] | ||
| 33 | $ make install | ||
| 34 | |||
| 35 | 2. Compile & install USB/IP drivers. | ||
| 36 | |||
| 37 | |||
| 38 | [Usage] | ||
| 39 | server:# (Physically attach your USB device.) | ||
| 40 | |||
| 41 | server:# insmod usbip-core.ko | ||
| 42 | server:# insmod usbip-host.ko | ||
| 43 | |||
| 44 | server:# usbipd -D | ||
| 45 | - Start usbip daemon. | ||
| 46 | |||
| 47 | server:# usbip list -l | ||
| 48 | - List driver assignments for USB devices. | ||
| 49 | |||
| 50 | server:# usbip bind --busid 1-2 | ||
| 51 | - Bind usbip-host.ko to the device with busid 1-2. | ||
| 52 | - The USB device 1-2 is now exportable to other hosts! | ||
| 53 | - Use `usbip unbind --busid 1-2' to stop exporting the device. | ||
| 54 | |||
| 55 | client:# insmod usbip-core.ko | ||
| 56 | client:# insmod vhci-hcd.ko | ||
| 57 | |||
| 58 | client:# usbip list --remote <host> | ||
| 59 | - List exported USB devices on the <host>. | ||
| 60 | |||
| 61 | client:# usbip attach --remote <host> --busid 1-2 | ||
| 62 | - Connect the remote USB device. | ||
| 63 | |||
| 64 | client:# usbip port | ||
| 65 | - Show virtual port status. | ||
| 66 | |||
| 67 | client:# usbip detach --port <port> | ||
| 68 | - Detach the USB device. | ||
| 69 | |||
| 70 | |||
| 71 | [Example] | ||
| 72 | --------------------------- | ||
| 73 | SERVER SIDE | ||
| 74 | --------------------------- | ||
| 75 | Physically attach your USB devices to this host. | ||
| 76 | |||
| 77 | trois:# insmod path/to/usbip-core.ko | ||
| 78 | trois:# insmod path/to/usbip-host.ko | ||
| 79 | trois:# usbipd -D | ||
| 80 | |||
| 81 | In another terminal, let's look up what USB devices are physically | ||
| 82 | attached to this host. | ||
| 83 | |||
| 84 | trois:# usbip list -l | ||
| 85 | Local USB devices | ||
| 86 | ================= | ||
| 87 | - busid 1-1 (05a9:a511) | ||
| 88 | 1-1:1.0 -> ov511 | ||
| 89 | |||
| 90 | - busid 3-2 (0711:0902) | ||
| 91 | 3-2:1.0 -> none | ||
| 92 | |||
| 93 | - busid 3-3.1 (08bb:2702) | ||
| 94 | 3-3.1:1.0 -> snd-usb-audio | ||
| 95 | 3-3.1:1.1 -> snd-usb-audio | ||
| 96 | |||
| 97 | - busid 3-3.2 (04bb:0206) | ||
| 98 | 3-3.2:1.0 -> usb-storage | ||
| 99 | |||
| 100 | - busid 3-3 (0409:0058) | ||
| 101 | 3-3:1.0 -> hub | ||
| 102 | |||
| 103 | - busid 4-1 (046d:08b2) | ||
| 104 | 4-1:1.0 -> none | ||
| 105 | 4-1:1.1 -> none | ||
| 106 | 4-1:1.2 -> none | ||
| 107 | |||
| 108 | - busid 5-2 (058f:9254) | ||
| 109 | 5-2:1.0 -> hub | ||
| 110 | |||
| 111 | A USB storage device of busid 3-3.2 is now bound to the usb-storage | ||
| 112 | driver. To export this device, we first mark the device as | ||
| 113 | "exportable"; the device is bound to the usbip-host driver. Please | ||
| 114 | remember you can not export a USB hub. | ||
| 115 | |||
| 116 | Mark the device of busid 3-3.2 as exportable: | ||
| 117 | |||
| 118 | trois:# usbip --debug bind --busid 3-3.2 | ||
| 119 | ... | ||
| 120 | usbip debug: usbip_bind.c:162:[unbind_other] 3-3.2:1.0 -> usb-storage | ||
| 121 | ... | ||
| 122 | bind device on busid 3-3.2: complete | ||
| 123 | |||
| 124 | trois:# usbip list -l | ||
| 125 | Local USB devices | ||
| 126 | ================= | ||
| 127 | ... | ||
| 128 | |||
| 129 | - busid 3-3.2 (04bb:0206) | ||
| 130 | 3-3.2:1.0 -> usbip-host | ||
| 131 | ... | ||
| 132 | |||
| 133 | --------------------------- | ||
| 134 | CLIENT SIDE | ||
| 135 | --------------------------- | ||
| 136 | First, let's list available remote devices that are marked as | ||
| 137 | exportable on the host. | ||
| 138 | |||
| 139 | deux:# insmod path/to/usbip-core.ko | ||
| 140 | deux:# insmod path/to/vhci-hcd.ko | ||
| 141 | |||
| 142 | deux:# usbip list --remote 10.0.0.3 | ||
| 143 | Exportable USB devices | ||
| 144 | ====================== | ||
| 145 | - 10.0.0.3 | ||
| 146 | 1-1: Prolific Technology, Inc. : unknown product (067b:3507) | ||
| 147 | : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-1 | ||
| 148 | : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) | ||
| 149 | : 0 - Mass Storage / SCSI / Bulk (Zip) (08/06/50) | ||
| 150 | |||
| 151 | 1-2.2.1: Apple Computer, Inc. : unknown product (05ac:0203) | ||
| 152 | : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.1 | ||
| 153 | : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) | ||
| 154 | : 0 - Human Interface Devices / Boot Interface Subclass / Keyboard (03/01/01) | ||
| 155 | |||
| 156 | 1-2.2.3: OmniVision Technologies, Inc. : OV511+ WebCam (05a9:a511) | ||
| 157 | : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.3 | ||
| 158 | : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) | ||
| 159 | : 0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00) | ||
| 160 | |||
| 161 | 3-1: Logitech, Inc. : QuickCam Pro 4000 (046d:08b2) | ||
| 162 | : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.0/usb3/3-1 | ||
| 163 | : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) | ||
| 164 | : 0 - Data / unknown subclass / unknown protocol (0a/ff/00) | ||
| 165 | : 1 - Audio / Control Device / unknown protocol (01/01/00) | ||
| 166 | : 2 - Audio / Streaming / unknown protocol (01/02/00) | ||
| 167 | |||
| 168 | Attach a remote USB device: | ||
| 169 | |||
| 170 | deux:# usbip attach --remote 10.0.0.3 --busid 1-1 | ||
| 171 | port 0 attached | ||
| 172 | |||
| 173 | Show the devices attached to this client: | ||
| 174 | |||
| 175 | deux:# usbip port | ||
| 176 | Port 00: <Port in Use> at Full Speed(12Mbps) | ||
| 177 | Prolific Technology, Inc. : unknown product (067b:3507) | ||
| 178 | 6-1 -> usbip://10.0.0.3:3240/1-1 (remote bus/dev 001/004) | ||
| 179 | 6-1:1.0 used by usb-storage | ||
| 180 | /sys/class/scsi_device/0:0:0:0/device | ||
| 181 | /sys/class/scsi_host/host0/device | ||
| 182 | /sys/block/sda/device | ||
| 183 | |||
| 184 | Detach the imported device: | ||
| 185 | |||
| 186 | deux:# usbip detach --port 0 | ||
| 187 | port 0 detached | ||
| 188 | |||
| 189 | |||
| 190 | [Checklist] | ||
| 191 | - See 'Debug Tips' on the project wiki. | ||
| 192 | - http://usbip.wiki.sourceforge.net/how-to-debug-usbip | ||
| 193 | - usbip-host.ko must be bound to the target device. | ||
| 194 | - See /proc/bus/usb/devices and find "Driver=..." lines of the device. | ||
| 195 | - Shutdown firewall. | ||
| 196 | - usbip now uses TCP port 3240. | ||
| 197 | - Disable SELinux. | ||
| 198 | - Check the kernel and daemon messages. | ||
| 199 | |||
| 200 | |||
| 201 | [Contact] | ||
| 202 | Mailing List: linux-usb@vger.kernel.org | ||
diff --git a/drivers/staging/usbip/userspace/autogen.sh b/drivers/staging/usbip/userspace/autogen.sh deleted file mode 100755 index e1112d3fcbf6..000000000000 --- a/drivers/staging/usbip/userspace/autogen.sh +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | #!/bin/sh -x | ||
| 2 | |||
| 3 | #aclocal | ||
| 4 | #autoheader | ||
| 5 | #libtoolize --copy --force | ||
| 6 | #automake-1.9 -acf | ||
| 7 | #autoconf | ||
| 8 | |||
| 9 | autoreconf -i -f -v | ||
diff --git a/drivers/staging/usbip/userspace/cleanup.sh b/drivers/staging/usbip/userspace/cleanup.sh deleted file mode 100755 index 955c3ccb729a..000000000000 --- a/drivers/staging/usbip/userspace/cleanup.sh +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | if [ -r Makefile ]; then | ||
| 4 | make distclean | ||
| 5 | fi | ||
| 6 | |||
| 7 | FILES="aclocal.m4 autom4te.cache compile config.guess config.h.in config.log \ | ||
| 8 | config.status config.sub configure cscope.out depcomp install-sh \ | ||
| 9 | libsrc/Makefile libsrc/Makefile.in libtool ltmain.sh Makefile \ | ||
| 10 | Makefile.in missing src/Makefile src/Makefile.in" | ||
| 11 | |||
| 12 | rm -vRf $FILES | ||
diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac deleted file mode 100644 index 607d05c5ccfd..000000000000 --- a/drivers/staging/usbip/userspace/configure.ac +++ /dev/null | |||
| @@ -1,111 +0,0 @@ | |||
| 1 | dnl Process this file with autoconf to produce a configure script. | ||
| 2 | |||
| 3 | AC_PREREQ(2.59) | ||
| 4 | AC_INIT([usbip-utils], [2.0], [linux-usb@vger.kernel.org]) | ||
| 5 | AC_DEFINE([USBIP_VERSION], [0x00000111], [binary-coded decimal version number]) | ||
| 6 | |||
| 7 | CURRENT=0 | ||
| 8 | REVISION=1 | ||
| 9 | AGE=0 | ||
| 10 | AC_SUBST([LIBUSBIP_VERSION], [$CURRENT:$REVISION:$AGE], [library version]) | ||
| 11 | |||
| 12 | AC_CONFIG_SRCDIR([src/usbipd.c]) | ||
| 13 | AC_CONFIG_HEADERS([config.h]) | ||
| 14 | |||
| 15 | AM_INIT_AUTOMAKE([foreign]) | ||
| 16 | LT_INIT | ||
| 17 | |||
| 18 | # Silent build for automake >= 1.11 | ||
| 19 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) | ||
| 20 | |||
| 21 | AC_SUBST([EXTRA_CFLAGS], ["-Wall -Werror -Wextra -std=gnu99"]) | ||
| 22 | |||
| 23 | # Checks for programs. | ||
| 24 | AC_PROG_CC | ||
| 25 | AC_PROG_INSTALL | ||
| 26 | AC_PROG_MAKE_SET | ||
| 27 | |||
| 28 | # Checks for header files. | ||
| 29 | AC_HEADER_DIRENT | ||
| 30 | AC_HEADER_STDC | ||
| 31 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h dnl | ||
| 32 | string.h sys/socket.h syslog.h unistd.h]) | ||
| 33 | |||
| 34 | # Checks for typedefs, structures, and compiler characteristics. | ||
| 35 | AC_TYPE_INT32_T | ||
| 36 | AC_TYPE_SIZE_T | ||
| 37 | AC_TYPE_SSIZE_T | ||
| 38 | AC_TYPE_UINT16_T | ||
| 39 | AC_TYPE_UINT32_T | ||
| 40 | AC_TYPE_UINT8_T | ||
| 41 | |||
| 42 | # Checks for library functions. | ||
| 43 | AC_FUNC_REALLOC | ||
| 44 | AC_CHECK_FUNCS([memset mkdir regcomp socket strchr strerror strstr dnl | ||
| 45 | strtoul]) | ||
| 46 | |||
| 47 | AC_CHECK_HEADER([libudev.h], | ||
| 48 | [AC_CHECK_LIB([udev], [udev_new], | ||
| 49 | [LIBS="$LIBS -ludev"], | ||
| 50 | [AC_MSG_ERROR([Missing udev library!])])], | ||
| 51 | [AC_MSG_ERROR([Missing /usr/include/libudev.h])]) | ||
| 52 | |||
| 53 | # Checks for libwrap library. | ||
| 54 | AC_MSG_CHECKING([whether to use the libwrap (TCP wrappers) library]) | ||
| 55 | AC_ARG_WITH([tcp-wrappers], | ||
| 56 | [AS_HELP_STRING([--with-tcp-wrappers], | ||
| 57 | [use the libwrap (TCP wrappers) library])], | ||
| 58 | dnl [ACTION-IF-GIVEN] | ||
| 59 | [if test "$withval" = "yes"; then | ||
| 60 | AC_MSG_RESULT([yes]) | ||
| 61 | AC_MSG_CHECKING([for hosts_access in -lwrap]) | ||
| 62 | saved_LIBS="$LIBS" | ||
| 63 | LIBS="-lwrap $saved_LIBS" | ||
| 64 | AC_TRY_LINK( | ||
| 65 | [int hosts_access(); int allow_severity, deny_severity;], | ||
| 66 | [hosts_access()], | ||
| 67 | [AC_MSG_RESULT([yes]); | ||
| 68 | AC_DEFINE([HAVE_LIBWRAP], [1], | ||
| 69 | [use tcp wrapper]) wrap_LIB="-lwrap"], | ||
| 70 | [AC_MSG_RESULT([not found]); exit 1]) | ||
| 71 | else | ||
| 72 | AC_MSG_RESULT([no]); | ||
| 73 | fi], | ||
| 74 | dnl [ACTION-IF-NOT-GIVEN] | ||
| 75 | [AC_MSG_RESULT([(default)]) | ||
| 76 | AC_MSG_CHECKING([for hosts_access in -lwrap]) | ||
| 77 | saved_LIBS="$LIBS" | ||
| 78 | LIBS="-lwrap $saved_LIBS" | ||
| 79 | AC_TRY_LINK( | ||
| 80 | [int hosts_access(); int allow_severity, deny_severity;], | ||
| 81 | [hosts_access()], | ||
| 82 | [AC_MSG_RESULT([yes]); | ||
| 83 | AC_DEFINE([HAVE_LIBWRAP], [1], [use tcp wrapper])], | ||
| 84 | [AC_MSG_RESULT([no]); LIBS="$saved_LIBS"])]) | ||
| 85 | |||
| 86 | # Sets directory containing usb.ids. | ||
| 87 | AC_ARG_WITH([usbids-dir], | ||
| 88 | [AS_HELP_STRING([--with-usbids-dir=DIR], | ||
| 89 | [where usb.ids is found (default /usr/share/hwdata/)])], | ||
| 90 | [USBIDS_DIR=$withval], [USBIDS_DIR="/usr/share/hwdata/"]) | ||
| 91 | AC_SUBST([USBIDS_DIR]) | ||
| 92 | |||
| 93 | # use _FORTIFY_SOURCE | ||
| 94 | AC_MSG_CHECKING([whether to use fortify]) | ||
| 95 | AC_ARG_WITH([fortify], | ||
| 96 | [AS_HELP_STRING([--with-fortify], | ||
| 97 | [use _FORTIFY_SROUCE option when compiling)])], | ||
| 98 | dnl [ACTION-IF-GIVEN] | ||
| 99 | [if test "$withval" = "yes"; then | ||
| 100 | AC_MSG_RESULT([yes]) | ||
| 101 | CFLAGS="$CFLAGS -D_FORTIFY_SOURCE -O" | ||
| 102 | else | ||
| 103 | AC_MSG_RESULT([no]) | ||
| 104 | CFLAGS="$CFLAGS -U_FORTIFY_SOURCE" | ||
| 105 | fi | ||
| 106 | ], | ||
| 107 | dnl [ACTION-IF-NOT-GIVEN] | ||
| 108 | [AC_MSG_RESULT([default])]) | ||
| 109 | |||
| 110 | AC_CONFIG_FILES([Makefile libsrc/Makefile src/Makefile]) | ||
| 111 | AC_OUTPUT | ||
diff --git a/drivers/staging/usbip/userspace/doc/usbip.8 b/drivers/staging/usbip/userspace/doc/usbip.8 deleted file mode 100644 index a6097be25d28..000000000000 --- a/drivers/staging/usbip/userspace/doc/usbip.8 +++ /dev/null | |||
| @@ -1,95 +0,0 @@ | |||
| 1 | .TH USBIP "8" "February 2009" "usbip" "System Administration Utilities" | ||
| 2 | .SH NAME | ||
| 3 | usbip \- manage USB/IP devices | ||
| 4 | .SH SYNOPSIS | ||
| 5 | .B usbip | ||
| 6 | [\fIoptions\fR] <\fIcommand\fR> <\fIargs\fR> | ||
| 7 | |||
| 8 | .SH DESCRIPTION | ||
| 9 | On a USB/IP server, devices can be listed, bound, and unbound using | ||
| 10 | this program. On a USB/IP client, devices exported by USB/IP servers | ||
| 11 | can be listed, attached and detached. | ||
| 12 | |||
| 13 | .SH OPTIONS | ||
| 14 | .HP | ||
| 15 | \fB\-\-debug\fR | ||
| 16 | .IP | ||
| 17 | Print debugging information. | ||
| 18 | .PP | ||
| 19 | |||
| 20 | .HP | ||
| 21 | \fB\-\-log\fR | ||
| 22 | .IP | ||
| 23 | Log to syslog. | ||
| 24 | .PP | ||
| 25 | |||
| 26 | .HP | ||
| 27 | \fB\-\-tcp-port PORT\fR | ||
| 28 | .IP | ||
| 29 | Connect to PORT on remote host (used for attach and list --remote). | ||
| 30 | .PP | ||
| 31 | |||
| 32 | .SH COMMANDS | ||
| 33 | .HP | ||
| 34 | \fBversion\fR | ||
| 35 | .IP | ||
| 36 | Show version and exit. | ||
| 37 | .PP | ||
| 38 | |||
| 39 | .HP | ||
| 40 | \fBhelp\fR [\fIcommand\fR] | ||
| 41 | .IP | ||
| 42 | Print the program help message, or help on a specific command, and | ||
| 43 | then exit. | ||
| 44 | .PP | ||
| 45 | |||
| 46 | .HP | ||
| 47 | \fBattach\fR \-\-remote=<\fIhost\fR> \-\-busid=<\fIbus_id\fR> | ||
| 48 | .IP | ||
| 49 | Attach a remote USB device. | ||
| 50 | .PP | ||
| 51 | |||
| 52 | .HP | ||
| 53 | \fBdetach\fR \-\-port=<\fIport\fR> | ||
| 54 | .IP | ||
| 55 | Detach an imported USB device. | ||
| 56 | .PP | ||
| 57 | |||
| 58 | .HP | ||
| 59 | \fBbind\fR \-\-busid=<\fIbusid\fR> | ||
| 60 | .IP | ||
| 61 | Make a device exportable. | ||
| 62 | .PP | ||
| 63 | |||
| 64 | .HP | ||
| 65 | \fBunbind\fR \-\-busid=<\fIbusid\fR> | ||
| 66 | .IP | ||
| 67 | Stop exporting a device so it can be used by a local driver. | ||
| 68 | .PP | ||
| 69 | |||
| 70 | .HP | ||
| 71 | \fBlist\fR \-\-remote=<\fIhost\fR> | ||
| 72 | .IP | ||
| 73 | List USB devices exported by a remote host. | ||
| 74 | .PP | ||
| 75 | |||
| 76 | .HP | ||
| 77 | \fBlist\fR \-\-local | ||
| 78 | .IP | ||
| 79 | List local USB devices. | ||
| 80 | .PP | ||
| 81 | |||
| 82 | |||
| 83 | .SH EXAMPLES | ||
| 84 | |||
| 85 | client:# usbip list --remote=server | ||
| 86 | - List exportable usb devices on the server. | ||
| 87 | |||
| 88 | client:# usbip attach --remote=server --busid=1-2 | ||
| 89 | - Connect the remote USB device. | ||
| 90 | |||
| 91 | client:# usbip detach --port=0 | ||
| 92 | - Detach the usb device. | ||
| 93 | |||
| 94 | .SH "SEE ALSO" | ||
| 95 | \fBusbipd\fP\fB(8)\fB\fP | ||
diff --git a/drivers/staging/usbip/userspace/doc/usbipd.8 b/drivers/staging/usbip/userspace/doc/usbipd.8 deleted file mode 100644 index ac4635db3f03..000000000000 --- a/drivers/staging/usbip/userspace/doc/usbipd.8 +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | .TH USBIP "8" "February 2009" "usbip" "System Administration Utilities" | ||
| 2 | .SH NAME | ||
| 3 | usbipd \- USB/IP server daemon | ||
| 4 | .SH SYNOPSIS | ||
| 5 | .B usbipd | ||
| 6 | [\fIoptions\fR] | ||
| 7 | |||
| 8 | .SH DESCRIPTION | ||
| 9 | .B usbipd | ||
| 10 | provides USB/IP clients access to exported USB devices. | ||
| 11 | |||
| 12 | Devices have to explicitly be exported using | ||
| 13 | .B usbip bind | ||
| 14 | before usbipd makes them available to other hosts. | ||
| 15 | |||
| 16 | The daemon accepts connections from USB/IP clients | ||
| 17 | on TCP port 3240 by default. | ||
| 18 | |||
| 19 | .SH OPTIONS | ||
| 20 | .HP | ||
| 21 | \fB\-4\fR, \fB\-\-ipv4\fR | ||
| 22 | .IP | ||
| 23 | Bind to IPv4. Default is both. | ||
| 24 | .PP | ||
| 25 | |||
| 26 | .HP | ||
| 27 | \fB\-6\fR, \fB\-\-ipv6\fR | ||
| 28 | .IP | ||
| 29 | Bind to IPv6. Default is both. | ||
| 30 | .PP | ||
| 31 | |||
| 32 | .HP | ||
| 33 | \fB\-D\fR, \fB\-\-daemon\fR | ||
| 34 | .IP | ||
| 35 | Run as a daemon process. | ||
| 36 | .PP | ||
| 37 | |||
| 38 | .HP | ||
| 39 | \fB\-d\fR, \fB\-\-debug\fR | ||
| 40 | .IP | ||
| 41 | Print debugging information. | ||
| 42 | .PP | ||
| 43 | |||
| 44 | .HP | ||
| 45 | \fB\-PFILE\fR, \fB\-\-pid FILE\fR | ||
| 46 | .IP | ||
| 47 | Write process id to FILE. | ||
| 48 | .br | ||
| 49 | If no FILE specified, use /var/run/usbipd.pid | ||
| 50 | .PP | ||
| 51 | |||
| 52 | \fB\-tPORT\fR, \fB\-\-tcp\-port PORT\fR | ||
| 53 | .IP | ||
| 54 | Listen on TCP/IP port PORT. | ||
| 55 | .PP | ||
| 56 | |||
| 57 | \fB\-h\fR, \fB\-\-help\fR | ||
| 58 | .IP | ||
| 59 | Print the program help message and exit. | ||
| 60 | .PP | ||
| 61 | |||
| 62 | .HP | ||
| 63 | \fB\-v\fR, \fB\-\-version\fR | ||
| 64 | .IP | ||
| 65 | Show version. | ||
| 66 | .PP | ||
| 67 | |||
| 68 | .SH LIMITATIONS | ||
| 69 | |||
| 70 | .B usbipd | ||
| 71 | offers no authentication or authorization for USB/IP. Any | ||
| 72 | USB/IP client can connect and use exported devices. | ||
| 73 | |||
| 74 | .SH EXAMPLES | ||
| 75 | |||
| 76 | server:# modprobe usbip | ||
| 77 | |||
| 78 | server:# usbipd -D | ||
| 79 | - Start usbip daemon. | ||
| 80 | |||
| 81 | server:# usbip list --local | ||
| 82 | - List driver assignments for usb devices. | ||
| 83 | |||
| 84 | server:# usbip bind --busid=1-2 | ||
| 85 | - Bind usbip-host.ko to the device of busid 1-2. | ||
| 86 | - A usb device 1-2 is now exportable to other hosts! | ||
| 87 | - Use 'usbip unbind --busid=1-2' when you want to shutdown exporting and use the device locally. | ||
| 88 | |||
| 89 | .SH "SEE ALSO" | ||
| 90 | \fBusbip\fP\fB(8)\fB\fP | ||
| 91 | |||
diff --git a/drivers/staging/usbip/userspace/libsrc/Makefile.am b/drivers/staging/usbip/userspace/libsrc/Makefile.am deleted file mode 100644 index 7c8f8a4d54e4..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/Makefile.am +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | libusbip_la_CPPFLAGS = -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' | ||
| 2 | libusbip_la_CFLAGS = @EXTRA_CFLAGS@ | ||
| 3 | libusbip_la_LDFLAGS = -version-info @LIBUSBIP_VERSION@ | ||
| 4 | |||
| 5 | lib_LTLIBRARIES := libusbip.la | ||
| 6 | libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \ | ||
| 7 | usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h \ | ||
| 8 | sysfs_utils.c sysfs_utils.h | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/list.h b/drivers/staging/usbip/userspace/libsrc/list.h deleted file mode 100644 index 8d0c936e184f..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/list.h +++ /dev/null | |||
| @@ -1,136 +0,0 @@ | |||
| 1 | #ifndef _LIST_H | ||
| 2 | #define _LIST_H | ||
| 3 | |||
| 4 | /* Stripped down implementation of linked list taken | ||
| 5 | * from the Linux Kernel. | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * Simple doubly linked list implementation. | ||
| 10 | * | ||
| 11 | * Some of the internal functions ("__xxx") are useful when | ||
| 12 | * manipulating whole lists rather than single entries, as | ||
| 13 | * sometimes we already know the next/prev entries and we can | ||
| 14 | * generate better code by using them directly rather than | ||
| 15 | * using the generic single-entry routines. | ||
| 16 | */ | ||
| 17 | |||
| 18 | struct list_head { | ||
| 19 | struct list_head *next, *prev; | ||
| 20 | }; | ||
| 21 | |||
| 22 | #define LIST_HEAD_INIT(name) { &(name), &(name) } | ||
| 23 | |||
| 24 | #define LIST_HEAD(name) \ | ||
| 25 | struct list_head name = LIST_HEAD_INIT(name) | ||
| 26 | |||
| 27 | static inline void INIT_LIST_HEAD(struct list_head *list) | ||
| 28 | { | ||
| 29 | list->next = list; | ||
| 30 | list->prev = list; | ||
| 31 | } | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Insert a new entry between two known consecutive entries. | ||
| 35 | * | ||
| 36 | * This is only for internal list manipulation where we know | ||
| 37 | * the prev/next entries already! | ||
| 38 | */ | ||
| 39 | static inline void __list_add(struct list_head *new, | ||
| 40 | struct list_head *prev, | ||
| 41 | struct list_head *next) | ||
| 42 | { | ||
| 43 | next->prev = new; | ||
| 44 | new->next = next; | ||
| 45 | new->prev = prev; | ||
| 46 | prev->next = new; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * list_add - add a new entry | ||
| 51 | * @new: new entry to be added | ||
| 52 | * @head: list head to add it after | ||
| 53 | * | ||
| 54 | * Insert a new entry after the specified head. | ||
| 55 | * This is good for implementing stacks. | ||
| 56 | */ | ||
| 57 | static inline void list_add(struct list_head *new, struct list_head *head) | ||
| 58 | { | ||
| 59 | __list_add(new, head, head->next); | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Delete a list entry by making the prev/next entries | ||
| 64 | * point to each other. | ||
| 65 | * | ||
| 66 | * This is only for internal list manipulation where we know | ||
| 67 | * the prev/next entries already! | ||
| 68 | */ | ||
| 69 | static inline void __list_del(struct list_head * prev, struct list_head * next) | ||
| 70 | { | ||
| 71 | next->prev = prev; | ||
| 72 | prev->next = next; | ||
| 73 | } | ||
| 74 | |||
| 75 | #define POISON_POINTER_DELTA 0 | ||
| 76 | #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) | ||
| 77 | #define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) | ||
| 78 | |||
| 79 | /** | ||
| 80 | * list_del - deletes entry from list. | ||
| 81 | * @entry: the element to delete from the list. | ||
| 82 | * Note: list_empty() on entry does not return true after this, the entry is | ||
| 83 | * in an undefined state. | ||
| 84 | */ | ||
| 85 | static inline void __list_del_entry(struct list_head *entry) | ||
| 86 | { | ||
| 87 | __list_del(entry->prev, entry->next); | ||
| 88 | } | ||
| 89 | |||
| 90 | static inline void list_del(struct list_head *entry) | ||
| 91 | { | ||
| 92 | __list_del(entry->prev, entry->next); | ||
| 93 | entry->next = LIST_POISON1; | ||
| 94 | entry->prev = LIST_POISON2; | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * list_entry - get the struct for this entry | ||
| 99 | * @ptr: the &struct list_head pointer. | ||
| 100 | * @type: the type of the struct this is embedded in. | ||
| 101 | * @member: the name of the list_struct within the struct. | ||
| 102 | */ | ||
| 103 | #define list_entry(ptr, type, member) \ | ||
| 104 | container_of(ptr, type, member) | ||
| 105 | /** | ||
| 106 | * list_for_each - iterate over a list | ||
| 107 | * @pos: the &struct list_head to use as a loop cursor. | ||
| 108 | * @head: the head for your list. | ||
| 109 | */ | ||
| 110 | #define list_for_each(pos, head) \ | ||
| 111 | for (pos = (head)->next; pos != (head); pos = pos->next) | ||
| 112 | |||
| 113 | /** | ||
| 114 | * list_for_each_safe - iterate over a list safe against removal of list entry | ||
| 115 | * @pos: the &struct list_head to use as a loop cursor. | ||
| 116 | * @n: another &struct list_head to use as temporary storage | ||
| 117 | * @head: the head for your list. | ||
| 118 | */ | ||
| 119 | #define list_for_each_safe(pos, n, head) \ | ||
| 120 | for (pos = (head)->next, n = pos->next; pos != (head); \ | ||
| 121 | pos = n, n = pos->next) | ||
| 122 | |||
| 123 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | ||
| 124 | |||
| 125 | /** | ||
| 126 | * container_of - cast a member of a structure out to the containing structure | ||
| 127 | * @ptr: the pointer to the member. | ||
| 128 | * @type: the type of the container struct this is embedded in. | ||
| 129 | * @member: the name of the member within the struct. | ||
| 130 | * | ||
| 131 | */ | ||
| 132 | #define container_of(ptr, type, member) ({ \ | ||
| 133 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
| 134 | (type *)( (char *)__mptr - offsetof(type,member) );}) | ||
| 135 | |||
| 136 | #endif | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c deleted file mode 100644 index 81ff8522405c..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ /dev/null | |||
| @@ -1,504 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * names.c -- USB name database manipulation routines | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | * | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * | ||
| 23 | * | ||
| 24 | * Copyright (C) 2005 Takahiro Hirofuchi | ||
| 25 | * - names_deinit() is added. | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <sys/stat.h> | ||
| 31 | #include <fcntl.h> | ||
| 32 | #include <dirent.h> | ||
| 33 | #include <string.h> | ||
| 34 | #include <errno.h> | ||
| 35 | #include <stdlib.h> | ||
| 36 | #include <unistd.h> | ||
| 37 | #include <stdio.h> | ||
| 38 | #include <ctype.h> | ||
| 39 | |||
| 40 | #include "names.h" | ||
| 41 | #include "usbip_common.h" | ||
| 42 | |||
| 43 | struct vendor { | ||
| 44 | struct vendor *next; | ||
| 45 | u_int16_t vendorid; | ||
| 46 | char name[1]; | ||
| 47 | }; | ||
| 48 | |||
| 49 | struct product { | ||
| 50 | struct product *next; | ||
| 51 | u_int16_t vendorid, productid; | ||
| 52 | char name[1]; | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct class { | ||
| 56 | struct class *next; | ||
| 57 | u_int8_t classid; | ||
| 58 | char name[1]; | ||
| 59 | }; | ||
| 60 | |||
| 61 | struct subclass { | ||
| 62 | struct subclass *next; | ||
| 63 | u_int8_t classid, subclassid; | ||
| 64 | char name[1]; | ||
| 65 | }; | ||
| 66 | |||
| 67 | struct protocol { | ||
| 68 | struct protocol *next; | ||
| 69 | u_int8_t classid, subclassid, protocolid; | ||
| 70 | char name[1]; | ||
| 71 | }; | ||
| 72 | |||
| 73 | struct genericstrtable { | ||
| 74 | struct genericstrtable *next; | ||
| 75 | unsigned int num; | ||
| 76 | char name[1]; | ||
| 77 | }; | ||
| 78 | |||
| 79 | |||
| 80 | #define HASH1 0x10 | ||
| 81 | #define HASH2 0x02 | ||
| 82 | #define HASHSZ 16 | ||
| 83 | |||
| 84 | static unsigned int hashnum(unsigned int num) | ||
| 85 | { | ||
| 86 | unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27; | ||
| 87 | |||
| 88 | for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1) | ||
| 89 | if (num & mask1) | ||
| 90 | num ^= mask2; | ||
| 91 | return num & (HASHSZ-1); | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | static struct vendor *vendors[HASHSZ] = { NULL, }; | ||
| 96 | static struct product *products[HASHSZ] = { NULL, }; | ||
| 97 | static struct class *classes[HASHSZ] = { NULL, }; | ||
| 98 | static struct subclass *subclasses[HASHSZ] = { NULL, }; | ||
| 99 | static struct protocol *protocols[HASHSZ] = { NULL, }; | ||
| 100 | |||
| 101 | const char *names_vendor(u_int16_t vendorid) | ||
| 102 | { | ||
| 103 | struct vendor *v; | ||
| 104 | |||
| 105 | v = vendors[hashnum(vendorid)]; | ||
| 106 | for (; v; v = v->next) | ||
| 107 | if (v->vendorid == vendorid) | ||
| 108 | return v->name; | ||
| 109 | return NULL; | ||
| 110 | } | ||
| 111 | |||
| 112 | const char *names_product(u_int16_t vendorid, u_int16_t productid) | ||
| 113 | { | ||
| 114 | struct product *p; | ||
| 115 | |||
| 116 | p = products[hashnum((vendorid << 16) | productid)]; | ||
| 117 | for (; p; p = p->next) | ||
| 118 | if (p->vendorid == vendorid && p->productid == productid) | ||
| 119 | return p->name; | ||
| 120 | return NULL; | ||
| 121 | } | ||
| 122 | |||
| 123 | const char *names_class(u_int8_t classid) | ||
| 124 | { | ||
| 125 | struct class *c; | ||
| 126 | |||
| 127 | c = classes[hashnum(classid)]; | ||
| 128 | for (; c; c = c->next) | ||
| 129 | if (c->classid == classid) | ||
| 130 | return c->name; | ||
| 131 | return NULL; | ||
| 132 | } | ||
| 133 | |||
| 134 | const char *names_subclass(u_int8_t classid, u_int8_t subclassid) | ||
| 135 | { | ||
| 136 | struct subclass *s; | ||
| 137 | |||
| 138 | s = subclasses[hashnum((classid << 8) | subclassid)]; | ||
| 139 | for (; s; s = s->next) | ||
| 140 | if (s->classid == classid && s->subclassid == subclassid) | ||
| 141 | return s->name; | ||
| 142 | return NULL; | ||
| 143 | } | ||
| 144 | |||
| 145 | const char *names_protocol(u_int8_t classid, u_int8_t subclassid, | ||
| 146 | u_int8_t protocolid) | ||
| 147 | { | ||
| 148 | struct protocol *p; | ||
| 149 | |||
| 150 | p = protocols[hashnum((classid << 16) | (subclassid << 8) | ||
| 151 | | protocolid)]; | ||
| 152 | for (; p; p = p->next) | ||
| 153 | if (p->classid == classid && p->subclassid == subclassid && | ||
| 154 | p->protocolid == protocolid) | ||
| 155 | return p->name; | ||
| 156 | return NULL; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* add a cleanup function by takahiro */ | ||
| 160 | struct pool { | ||
| 161 | struct pool *next; | ||
| 162 | void *mem; | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct pool *pool_head; | ||
| 166 | |||
| 167 | static void *my_malloc(size_t size) | ||
| 168 | { | ||
| 169 | struct pool *p; | ||
| 170 | |||
| 171 | p = calloc(1, sizeof(struct pool)); | ||
| 172 | if (!p) | ||
| 173 | return NULL; | ||
| 174 | |||
| 175 | p->mem = calloc(1, size); | ||
| 176 | if (!p->mem) { | ||
| 177 | free(p); | ||
| 178 | return NULL; | ||
| 179 | } | ||
| 180 | |||
| 181 | p->next = pool_head; | ||
| 182 | pool_head = p; | ||
| 183 | |||
| 184 | return p->mem; | ||
| 185 | } | ||
| 186 | |||
| 187 | void names_free(void) | ||
| 188 | { | ||
| 189 | struct pool *pool; | ||
| 190 | |||
| 191 | if (!pool_head) | ||
| 192 | return; | ||
| 193 | |||
| 194 | for (pool = pool_head; pool != NULL; ) { | ||
| 195 | struct pool *tmp; | ||
| 196 | |||
| 197 | if (pool->mem) | ||
| 198 | free(pool->mem); | ||
| 199 | |||
| 200 | tmp = pool; | ||
| 201 | pool = pool->next; | ||
| 202 | free(tmp); | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | static int new_vendor(const char *name, u_int16_t vendorid) | ||
| 207 | { | ||
| 208 | struct vendor *v; | ||
| 209 | unsigned int h = hashnum(vendorid); | ||
| 210 | |||
| 211 | v = vendors[h]; | ||
| 212 | for (; v; v = v->next) | ||
| 213 | if (v->vendorid == vendorid) | ||
| 214 | return -1; | ||
| 215 | v = my_malloc(sizeof(struct vendor) + strlen(name)); | ||
| 216 | if (!v) | ||
| 217 | return -1; | ||
| 218 | strcpy(v->name, name); | ||
| 219 | v->vendorid = vendorid; | ||
| 220 | v->next = vendors[h]; | ||
| 221 | vendors[h] = v; | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int new_product(const char *name, u_int16_t vendorid, | ||
| 226 | u_int16_t productid) | ||
| 227 | { | ||
| 228 | struct product *p; | ||
| 229 | unsigned int h = hashnum((vendorid << 16) | productid); | ||
| 230 | |||
| 231 | p = products[h]; | ||
| 232 | for (; p; p = p->next) | ||
| 233 | if (p->vendorid == vendorid && p->productid == productid) | ||
| 234 | return -1; | ||
| 235 | p = my_malloc(sizeof(struct product) + strlen(name)); | ||
| 236 | if (!p) | ||
| 237 | return -1; | ||
| 238 | strcpy(p->name, name); | ||
| 239 | p->vendorid = vendorid; | ||
| 240 | p->productid = productid; | ||
| 241 | p->next = products[h]; | ||
| 242 | products[h] = p; | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | static int new_class(const char *name, u_int8_t classid) | ||
| 247 | { | ||
| 248 | struct class *c; | ||
| 249 | unsigned int h = hashnum(classid); | ||
| 250 | |||
| 251 | c = classes[h]; | ||
| 252 | for (; c; c = c->next) | ||
| 253 | if (c->classid == classid) | ||
| 254 | return -1; | ||
| 255 | c = my_malloc(sizeof(struct class) + strlen(name)); | ||
| 256 | if (!c) | ||
| 257 | return -1; | ||
| 258 | strcpy(c->name, name); | ||
| 259 | c->classid = classid; | ||
| 260 | c->next = classes[h]; | ||
| 261 | classes[h] = c; | ||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | |||
| 265 | static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid) | ||
| 266 | { | ||
| 267 | struct subclass *s; | ||
| 268 | unsigned int h = hashnum((classid << 8) | subclassid); | ||
| 269 | |||
| 270 | s = subclasses[h]; | ||
| 271 | for (; s; s = s->next) | ||
| 272 | if (s->classid == classid && s->subclassid == subclassid) | ||
| 273 | return -1; | ||
| 274 | s = my_malloc(sizeof(struct subclass) + strlen(name)); | ||
| 275 | if (!s) | ||
| 276 | return -1; | ||
| 277 | strcpy(s->name, name); | ||
| 278 | s->classid = classid; | ||
| 279 | s->subclassid = subclassid; | ||
| 280 | s->next = subclasses[h]; | ||
| 281 | subclasses[h] = s; | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, | ||
| 286 | u_int8_t protocolid) | ||
| 287 | { | ||
| 288 | struct protocol *p; | ||
| 289 | unsigned int h = hashnum((classid << 16) | (subclassid << 8) | ||
| 290 | | protocolid); | ||
| 291 | |||
| 292 | p = protocols[h]; | ||
| 293 | for (; p; p = p->next) | ||
| 294 | if (p->classid == classid && p->subclassid == subclassid | ||
| 295 | && p->protocolid == protocolid) | ||
| 296 | return -1; | ||
| 297 | p = my_malloc(sizeof(struct protocol) + strlen(name)); | ||
| 298 | if (!p) | ||
| 299 | return -1; | ||
| 300 | strcpy(p->name, name); | ||
| 301 | p->classid = classid; | ||
| 302 | p->subclassid = subclassid; | ||
| 303 | p->protocolid = protocolid; | ||
| 304 | p->next = protocols[h]; | ||
| 305 | protocols[h] = p; | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | |||
| 309 | static void parse(FILE *f) | ||
| 310 | { | ||
| 311 | char buf[512], *cp; | ||
| 312 | unsigned int linectr = 0; | ||
| 313 | int lastvendor = -1; | ||
| 314 | int lastclass = -1; | ||
| 315 | int lastsubclass = -1; | ||
| 316 | int lasthut = -1; | ||
| 317 | int lastlang = -1; | ||
| 318 | unsigned int u; | ||
| 319 | |||
| 320 | while (fgets(buf, sizeof(buf), f)) { | ||
| 321 | linectr++; | ||
| 322 | /* remove line ends */ | ||
| 323 | cp = strchr(buf, '\r'); | ||
| 324 | if (cp) | ||
| 325 | *cp = 0; | ||
| 326 | cp = strchr(buf, '\n'); | ||
| 327 | if (cp) | ||
| 328 | *cp = 0; | ||
| 329 | if (buf[0] == '#' || !buf[0]) | ||
| 330 | continue; | ||
| 331 | cp = buf; | ||
| 332 | if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && | ||
| 333 | buf[3] == 'S' && buf[4] == 'D' && | ||
| 334 | buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ | ||
| 335 | buf[7] == ' ') { | ||
| 336 | continue; | ||
| 337 | } | ||
| 338 | if (buf[0] == 'P' && buf[1] == 'H' && | ||
| 339 | buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { | ||
| 340 | continue; | ||
| 341 | } | ||
| 342 | if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && | ||
| 343 | buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { | ||
| 344 | continue; | ||
| 345 | } | ||
| 346 | if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') { | ||
| 347 | lasthut = lastclass = lastvendor = lastsubclass = -1; | ||
| 348 | /* | ||
| 349 | * set 1 as pseudo-id to indicate that the parser is | ||
| 350 | * in a `L' section. | ||
| 351 | */ | ||
| 352 | lastlang = 1; | ||
| 353 | continue; | ||
| 354 | } | ||
| 355 | if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') { | ||
| 356 | /* class spec */ | ||
| 357 | cp = buf+2; | ||
| 358 | while (isspace(*cp)) | ||
| 359 | cp++; | ||
| 360 | if (!isxdigit(*cp)) { | ||
| 361 | err("Invalid class spec at line %u", linectr); | ||
| 362 | continue; | ||
| 363 | } | ||
| 364 | u = strtoul(cp, &cp, 16); | ||
| 365 | while (isspace(*cp)) | ||
| 366 | cp++; | ||
| 367 | if (!*cp) { | ||
| 368 | err("Invalid class spec at line %u", linectr); | ||
| 369 | continue; | ||
| 370 | } | ||
| 371 | if (new_class(cp, u)) | ||
| 372 | err("Duplicate class spec at line %u class %04x %s", | ||
| 373 | linectr, u, cp); | ||
| 374 | dbg("line %5u class %02x %s", linectr, u, cp); | ||
| 375 | lasthut = lastlang = lastvendor = lastsubclass = -1; | ||
| 376 | lastclass = u; | ||
| 377 | continue; | ||
| 378 | } | ||
| 379 | if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) { | ||
| 380 | /* audio terminal type spec */ | ||
| 381 | continue; | ||
| 382 | } | ||
| 383 | if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' | ||
| 384 | && isspace(buf[3])) { | ||
| 385 | /* HID Descriptor bCountryCode */ | ||
| 386 | continue; | ||
| 387 | } | ||
| 388 | if (isxdigit(*cp)) { | ||
| 389 | /* vendor */ | ||
| 390 | u = strtoul(cp, &cp, 16); | ||
| 391 | while (isspace(*cp)) | ||
| 392 | cp++; | ||
| 393 | if (!*cp) { | ||
| 394 | err("Invalid vendor spec at line %u", linectr); | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | if (new_vendor(cp, u)) | ||
| 398 | err("Duplicate vendor spec at line %u vendor %04x %s", | ||
| 399 | linectr, u, cp); | ||
| 400 | dbg("line %5u vendor %04x %s", linectr, u, cp); | ||
| 401 | lastvendor = u; | ||
| 402 | lasthut = lastlang = lastclass = lastsubclass = -1; | ||
| 403 | continue; | ||
| 404 | } | ||
| 405 | if (buf[0] == '\t' && isxdigit(buf[1])) { | ||
| 406 | /* product or subclass spec */ | ||
| 407 | u = strtoul(buf+1, &cp, 16); | ||
| 408 | while (isspace(*cp)) | ||
| 409 | cp++; | ||
| 410 | if (!*cp) { | ||
| 411 | err("Invalid product/subclass spec at line %u", | ||
| 412 | linectr); | ||
| 413 | continue; | ||
| 414 | } | ||
| 415 | if (lastvendor != -1) { | ||
| 416 | if (new_product(cp, lastvendor, u)) | ||
| 417 | err("Duplicate product spec at line %u product %04x:%04x %s", | ||
| 418 | linectr, lastvendor, u, cp); | ||
| 419 | dbg("line %5u product %04x:%04x %s", linectr, | ||
| 420 | lastvendor, u, cp); | ||
| 421 | continue; | ||
| 422 | } | ||
| 423 | if (lastclass != -1) { | ||
| 424 | if (new_subclass(cp, lastclass, u)) | ||
| 425 | err("Duplicate subclass spec at line %u class %02x:%02x %s", | ||
| 426 | linectr, lastclass, u, cp); | ||
| 427 | dbg("line %5u subclass %02x:%02x %s", linectr, | ||
| 428 | lastclass, u, cp); | ||
| 429 | lastsubclass = u; | ||
| 430 | continue; | ||
| 431 | } | ||
| 432 | if (lasthut != -1) { | ||
| 433 | /* do not store hut */ | ||
| 434 | continue; | ||
| 435 | } | ||
| 436 | if (lastlang != -1) { | ||
| 437 | /* do not store langid */ | ||
| 438 | continue; | ||
| 439 | } | ||
| 440 | err("Product/Subclass spec without prior Vendor/Class spec at line %u", | ||
| 441 | linectr); | ||
| 442 | continue; | ||
| 443 | } | ||
| 444 | if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) { | ||
| 445 | /* protocol spec */ | ||
| 446 | u = strtoul(buf+2, &cp, 16); | ||
| 447 | while (isspace(*cp)) | ||
| 448 | cp++; | ||
| 449 | if (!*cp) { | ||
| 450 | err("Invalid protocol spec at line %u", | ||
| 451 | linectr); | ||
| 452 | continue; | ||
| 453 | } | ||
| 454 | if (lastclass != -1 && lastsubclass != -1) { | ||
| 455 | if (new_protocol(cp, lastclass, lastsubclass, | ||
| 456 | u)) | ||
| 457 | err("Duplicate protocol spec at line %u class %02x:%02x:%02x %s", | ||
| 458 | linectr, lastclass, lastsubclass, | ||
| 459 | u, cp); | ||
| 460 | dbg("line %5u protocol %02x:%02x:%02x %s", | ||
| 461 | linectr, lastclass, lastsubclass, u, cp); | ||
| 462 | continue; | ||
| 463 | } | ||
| 464 | err("Protocol spec without prior Class and Subclass spec at line %u", | ||
| 465 | linectr); | ||
| 466 | continue; | ||
| 467 | } | ||
| 468 | if (buf[0] == 'H' && buf[1] == 'I' && | ||
| 469 | buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') { | ||
| 470 | continue; | ||
| 471 | } | ||
| 472 | if (buf[0] == 'H' && buf[1] == 'U' && | ||
| 473 | buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { | ||
| 474 | lastlang = lastclass = lastvendor = lastsubclass = -1; | ||
| 475 | /* | ||
| 476 | * set 1 as pseudo-id to indicate that the parser is | ||
| 477 | * in a `HUT' section. | ||
| 478 | */ | ||
| 479 | lasthut = 1; | ||
| 480 | continue; | ||
| 481 | } | ||
| 482 | if (buf[0] == 'R' && buf[1] == ' ') | ||
| 483 | continue; | ||
| 484 | |||
| 485 | if (buf[0] == 'V' && buf[1] == 'T') | ||
| 486 | continue; | ||
| 487 | |||
| 488 | err("Unknown line at line %u", linectr); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | |||
| 493 | int names_init(char *n) | ||
| 494 | { | ||
| 495 | FILE *f; | ||
| 496 | |||
| 497 | f = fopen(n, "r"); | ||
| 498 | if (!f) | ||
| 499 | return errno; | ||
| 500 | |||
| 501 | parse(f); | ||
| 502 | fclose(f); | ||
| 503 | return 0; | ||
| 504 | } | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/names.h b/drivers/staging/usbip/userspace/libsrc/names.h deleted file mode 100644 index 680926512de2..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/names.h +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * names.h -- USB name database manipulation routines | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | * | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * Copyright (C) 2005 Takahiro Hirofuchi | ||
| 23 | * - names_free() is added. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef _NAMES_H | ||
| 27 | #define _NAMES_H | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | |||
| 31 | /* used by usbip_common.c */ | ||
| 32 | extern const char *names_vendor(u_int16_t vendorid); | ||
| 33 | extern const char *names_product(u_int16_t vendorid, u_int16_t productid); | ||
| 34 | extern const char *names_class(u_int8_t classid); | ||
| 35 | extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid); | ||
| 36 | extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, | ||
| 37 | u_int8_t protocolid); | ||
| 38 | extern int names_init(char *n); | ||
| 39 | extern void names_free(void); | ||
| 40 | |||
| 41 | #endif /* _NAMES_H */ | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c deleted file mode 100644 index 36ac88ece0b8..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <sys/stat.h> | ||
| 3 | #include <fcntl.h> | ||
| 4 | #include <errno.h> | ||
| 5 | |||
| 6 | #include "sysfs_utils.h" | ||
| 7 | #include "usbip_common.h" | ||
| 8 | |||
| 9 | int write_sysfs_attribute(const char *attr_path, const char *new_value, | ||
| 10 | size_t len) | ||
| 11 | { | ||
| 12 | int fd; | ||
| 13 | int length; | ||
| 14 | |||
| 15 | fd = open(attr_path, O_WRONLY); | ||
| 16 | if (fd < 0) { | ||
| 17 | dbg("error opening attribute %s", attr_path); | ||
| 18 | return -1; | ||
| 19 | } | ||
| 20 | |||
| 21 | length = write(fd, new_value, len); | ||
| 22 | if (length < 0) { | ||
| 23 | dbg("error writing to attribute %s", attr_path); | ||
| 24 | close(fd); | ||
| 25 | return -1; | ||
| 26 | } | ||
| 27 | |||
| 28 | close(fd); | ||
| 29 | |||
| 30 | return 0; | ||
| 31 | } | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h deleted file mode 100644 index 32ac1d105d18..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | |||
| 2 | #ifndef __SYSFS_UTILS_H | ||
| 3 | #define __SYSFS_UTILS_H | ||
| 4 | |||
| 5 | int write_sysfs_attribute(const char *attr_path, const char *new_value, | ||
| 6 | size_t len); | ||
| 7 | |||
| 8 | #endif | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c deleted file mode 100644 index ac73710473de..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ /dev/null | |||
| @@ -1,285 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <libudev.h> | ||
| 6 | #include "usbip_common.h" | ||
| 7 | #include "names.h" | ||
| 8 | |||
| 9 | #undef PROGNAME | ||
| 10 | #define PROGNAME "libusbip" | ||
| 11 | |||
| 12 | int usbip_use_syslog; | ||
| 13 | int usbip_use_stderr; | ||
| 14 | int usbip_use_debug; | ||
| 15 | |||
| 16 | extern struct udev *udev_context; | ||
| 17 | |||
| 18 | struct speed_string { | ||
| 19 | int num; | ||
| 20 | char *speed; | ||
| 21 | char *desc; | ||
| 22 | }; | ||
| 23 | |||
| 24 | static const struct speed_string speed_strings[] = { | ||
| 25 | { USB_SPEED_UNKNOWN, "unknown", "Unknown Speed"}, | ||
| 26 | { USB_SPEED_LOW, "1.5", "Low Speed(1.5Mbps)" }, | ||
| 27 | { USB_SPEED_FULL, "12", "Full Speed(12Mbps)" }, | ||
| 28 | { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" }, | ||
| 29 | { USB_SPEED_WIRELESS, "53.3-480", "Wireless"}, | ||
| 30 | { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" }, | ||
| 31 | { 0, NULL, NULL } | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct portst_string { | ||
| 35 | int num; | ||
| 36 | char *desc; | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct portst_string portst_strings[] = { | ||
| 40 | { SDEV_ST_AVAILABLE, "Device Available" }, | ||
| 41 | { SDEV_ST_USED, "Device in Use" }, | ||
| 42 | { SDEV_ST_ERROR, "Device Error"}, | ||
| 43 | { VDEV_ST_NULL, "Port Available"}, | ||
| 44 | { VDEV_ST_NOTASSIGNED, "Port Initializing"}, | ||
| 45 | { VDEV_ST_USED, "Port in Use"}, | ||
| 46 | { VDEV_ST_ERROR, "Port Error"}, | ||
| 47 | { 0, NULL} | ||
| 48 | }; | ||
| 49 | |||
| 50 | const char *usbip_status_string(int32_t status) | ||
| 51 | { | ||
| 52 | for (int i = 0; portst_strings[i].desc != NULL; i++) | ||
| 53 | if (portst_strings[i].num == status) | ||
| 54 | return portst_strings[i].desc; | ||
| 55 | |||
| 56 | return "Unknown Status"; | ||
| 57 | } | ||
| 58 | |||
| 59 | const char *usbip_speed_string(int num) | ||
| 60 | { | ||
| 61 | for (int i = 0; speed_strings[i].speed != NULL; i++) | ||
| 62 | if (speed_strings[i].num == num) | ||
| 63 | return speed_strings[i].desc; | ||
| 64 | |||
| 65 | return "Unknown Speed"; | ||
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | #define DBG_UDEV_INTEGER(name)\ | ||
| 70 | dbg("%-20s = %x", to_string(name), (int) udev->name) | ||
| 71 | |||
| 72 | #define DBG_UINF_INTEGER(name)\ | ||
| 73 | dbg("%-20s = %x", to_string(name), (int) uinf->name) | ||
| 74 | |||
| 75 | void dump_usb_interface(struct usbip_usb_interface *uinf) | ||
| 76 | { | ||
| 77 | char buff[100]; | ||
| 78 | |||
| 79 | usbip_names_get_class(buff, sizeof(buff), | ||
| 80 | uinf->bInterfaceClass, | ||
| 81 | uinf->bInterfaceSubClass, | ||
| 82 | uinf->bInterfaceProtocol); | ||
| 83 | dbg("%-20s = %s", "Interface(C/SC/P)", buff); | ||
| 84 | } | ||
| 85 | |||
| 86 | void dump_usb_device(struct usbip_usb_device *udev) | ||
| 87 | { | ||
| 88 | char buff[100]; | ||
| 89 | |||
| 90 | dbg("%-20s = %s", "path", udev->path); | ||
| 91 | dbg("%-20s = %s", "busid", udev->busid); | ||
| 92 | |||
| 93 | usbip_names_get_class(buff, sizeof(buff), | ||
| 94 | udev->bDeviceClass, | ||
| 95 | udev->bDeviceSubClass, | ||
| 96 | udev->bDeviceProtocol); | ||
| 97 | dbg("%-20s = %s", "Device(C/SC/P)", buff); | ||
| 98 | |||
| 99 | DBG_UDEV_INTEGER(bcdDevice); | ||
| 100 | |||
| 101 | usbip_names_get_product(buff, sizeof(buff), | ||
| 102 | udev->idVendor, | ||
| 103 | udev->idProduct); | ||
| 104 | dbg("%-20s = %s", "Vendor/Product", buff); | ||
| 105 | |||
| 106 | DBG_UDEV_INTEGER(bNumConfigurations); | ||
| 107 | DBG_UDEV_INTEGER(bNumInterfaces); | ||
| 108 | |||
| 109 | dbg("%-20s = %s", "speed", | ||
| 110 | usbip_speed_string(udev->speed)); | ||
| 111 | |||
| 112 | DBG_UDEV_INTEGER(busnum); | ||
| 113 | DBG_UDEV_INTEGER(devnum); | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | int read_attr_value(struct udev_device *dev, const char *name, | ||
| 118 | const char *format) | ||
| 119 | { | ||
| 120 | const char *attr; | ||
| 121 | int num = 0; | ||
| 122 | int ret; | ||
| 123 | |||
| 124 | attr = udev_device_get_sysattr_value(dev, name); | ||
| 125 | if (!attr) { | ||
| 126 | err("udev_device_get_sysattr_value failed"); | ||
| 127 | goto err; | ||
| 128 | } | ||
| 129 | |||
| 130 | /* The client chooses the device configuration | ||
| 131 | * when attaching it so right after being bound | ||
| 132 | * to usbip-host on the server the device will | ||
| 133 | * have no configuration. | ||
| 134 | * Therefore, attributes such as bConfigurationValue | ||
| 135 | * and bNumInterfaces will not exist and sscanf will | ||
| 136 | * fail. Check for these cases and don't treat them | ||
| 137 | * as errors. | ||
| 138 | */ | ||
| 139 | |||
| 140 | ret = sscanf(attr, format, &num); | ||
| 141 | if (ret < 1) { | ||
| 142 | if (strcmp(name, "bConfigurationValue") && | ||
| 143 | strcmp(name, "bNumInterfaces")) { | ||
| 144 | err("sscanf failed for attribute %s", name); | ||
| 145 | goto err; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | err: | ||
| 150 | |||
| 151 | return num; | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | int read_attr_speed(struct udev_device *dev) | ||
| 156 | { | ||
| 157 | const char *speed; | ||
| 158 | |||
| 159 | speed = udev_device_get_sysattr_value(dev, "speed"); | ||
| 160 | if (!speed) { | ||
| 161 | err("udev_device_get_sysattr_value failed"); | ||
| 162 | goto err; | ||
| 163 | } | ||
| 164 | |||
| 165 | for (int i = 0; speed_strings[i].speed != NULL; i++) { | ||
| 166 | if (!strcmp(speed, speed_strings[i].speed)) | ||
| 167 | return speed_strings[i].num; | ||
| 168 | } | ||
| 169 | |||
| 170 | err: | ||
| 171 | |||
| 172 | return USB_SPEED_UNKNOWN; | ||
| 173 | } | ||
| 174 | |||
| 175 | #define READ_ATTR(object, type, dev, name, format) \ | ||
| 176 | do { \ | ||
| 177 | (object)->name = (type) read_attr_value(dev, to_string(name), \ | ||
| 178 | format); \ | ||
| 179 | } while (0) | ||
| 180 | |||
| 181 | |||
| 182 | int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev) | ||
| 183 | { | ||
| 184 | uint32_t busnum, devnum; | ||
| 185 | const char *path, *name; | ||
| 186 | |||
| 187 | READ_ATTR(udev, uint8_t, sdev, bDeviceClass, "%02x\n"); | ||
| 188 | READ_ATTR(udev, uint8_t, sdev, bDeviceSubClass, "%02x\n"); | ||
| 189 | READ_ATTR(udev, uint8_t, sdev, bDeviceProtocol, "%02x\n"); | ||
| 190 | |||
| 191 | READ_ATTR(udev, uint16_t, sdev, idVendor, "%04x\n"); | ||
| 192 | READ_ATTR(udev, uint16_t, sdev, idProduct, "%04x\n"); | ||
| 193 | READ_ATTR(udev, uint16_t, sdev, bcdDevice, "%04x\n"); | ||
| 194 | |||
| 195 | READ_ATTR(udev, uint8_t, sdev, bConfigurationValue, "%02x\n"); | ||
| 196 | READ_ATTR(udev, uint8_t, sdev, bNumConfigurations, "%02x\n"); | ||
| 197 | READ_ATTR(udev, uint8_t, sdev, bNumInterfaces, "%02x\n"); | ||
| 198 | |||
| 199 | READ_ATTR(udev, uint8_t, sdev, devnum, "%d\n"); | ||
| 200 | udev->speed = read_attr_speed(sdev); | ||
| 201 | |||
| 202 | path = udev_device_get_syspath(sdev); | ||
| 203 | name = udev_device_get_sysname(sdev); | ||
| 204 | |||
| 205 | strncpy(udev->path, path, SYSFS_PATH_MAX); | ||
| 206 | strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE); | ||
| 207 | |||
| 208 | sscanf(name, "%u-%u", &busnum, &devnum); | ||
| 209 | udev->busnum = busnum; | ||
| 210 | |||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | int read_usb_interface(struct usbip_usb_device *udev, int i, | ||
| 215 | struct usbip_usb_interface *uinf) | ||
| 216 | { | ||
| 217 | char busid[SYSFS_BUS_ID_SIZE]; | ||
| 218 | struct udev_device *sif; | ||
| 219 | |||
| 220 | sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i); | ||
| 221 | |||
| 222 | sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", busid); | ||
| 223 | if (!sif) { | ||
| 224 | err("udev_device_new_from_subsystem_sysname %s failed", busid); | ||
| 225 | return -1; | ||
| 226 | } | ||
| 227 | |||
| 228 | READ_ATTR(uinf, uint8_t, sif, bInterfaceClass, "%02x\n"); | ||
| 229 | READ_ATTR(uinf, uint8_t, sif, bInterfaceSubClass, "%02x\n"); | ||
| 230 | READ_ATTR(uinf, uint8_t, sif, bInterfaceProtocol, "%02x\n"); | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | int usbip_names_init(char *f) | ||
| 236 | { | ||
| 237 | return names_init(f); | ||
| 238 | } | ||
| 239 | |||
| 240 | void usbip_names_free(void) | ||
| 241 | { | ||
| 242 | names_free(); | ||
| 243 | } | ||
| 244 | |||
| 245 | void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, | ||
| 246 | uint16_t product) | ||
| 247 | { | ||
| 248 | const char *prod, *vend; | ||
| 249 | |||
| 250 | prod = names_product(vendor, product); | ||
| 251 | if (!prod) | ||
| 252 | prod = "unknown product"; | ||
| 253 | |||
| 254 | |||
| 255 | vend = names_vendor(vendor); | ||
| 256 | if (!vend) | ||
| 257 | vend = "unknown vendor"; | ||
| 258 | |||
| 259 | snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product); | ||
| 260 | } | ||
| 261 | |||
| 262 | void usbip_names_get_class(char *buff, size_t size, uint8_t class, | ||
| 263 | uint8_t subclass, uint8_t protocol) | ||
| 264 | { | ||
| 265 | const char *c, *s, *p; | ||
| 266 | |||
| 267 | if (class == 0 && subclass == 0 && protocol == 0) { | ||
| 268 | snprintf(buff, size, "(Defined at Interface level) (%02x/%02x/%02x)", class, subclass, protocol); | ||
| 269 | return; | ||
| 270 | } | ||
| 271 | |||
| 272 | p = names_protocol(class, subclass, protocol); | ||
| 273 | if (!p) | ||
| 274 | p = "unknown protocol"; | ||
| 275 | |||
| 276 | s = names_subclass(class, subclass); | ||
| 277 | if (!s) | ||
| 278 | s = "unknown subclass"; | ||
| 279 | |||
| 280 | c = names_class(class); | ||
| 281 | if (!c) | ||
| 282 | c = "unknown class"; | ||
| 283 | |||
| 284 | snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, class, subclass, protocol); | ||
| 285 | } | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h deleted file mode 100644 index 5a0e95edf4df..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h +++ /dev/null | |||
| @@ -1,137 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef __USBIP_COMMON_H | ||
| 6 | #define __USBIP_COMMON_H | ||
| 7 | |||
| 8 | #include <libudev.h> | ||
| 9 | |||
| 10 | #include <stdint.h> | ||
| 11 | #include <stdio.h> | ||
| 12 | #include <stdlib.h> | ||
| 13 | #include <string.h> | ||
| 14 | |||
| 15 | #include <syslog.h> | ||
| 16 | #include <unistd.h> | ||
| 17 | #include <linux/usb/ch9.h> | ||
| 18 | #include "../../uapi/usbip.h" | ||
| 19 | |||
| 20 | #ifndef USBIDS_FILE | ||
| 21 | #define USBIDS_FILE "/usr/share/hwdata/usb.ids" | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #ifndef VHCI_STATE_PATH | ||
| 25 | #define VHCI_STATE_PATH "/var/run/vhci_hcd" | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* kernel module names */ | ||
| 29 | #define USBIP_CORE_MOD_NAME "usbip-core" | ||
| 30 | #define USBIP_HOST_DRV_NAME "usbip-host" | ||
| 31 | #define USBIP_VHCI_DRV_NAME "vhci_hcd" | ||
| 32 | |||
| 33 | /* sysfs constants */ | ||
| 34 | #define SYSFS_MNT_PATH "/sys" | ||
| 35 | #define SYSFS_BUS_NAME "bus" | ||
| 36 | #define SYSFS_BUS_TYPE "usb" | ||
| 37 | #define SYSFS_DRIVERS_NAME "drivers" | ||
| 38 | |||
| 39 | #define SYSFS_PATH_MAX 256 | ||
| 40 | #define SYSFS_BUS_ID_SIZE 32 | ||
| 41 | |||
| 42 | extern int usbip_use_syslog; | ||
| 43 | extern int usbip_use_stderr; | ||
| 44 | extern int usbip_use_debug ; | ||
| 45 | |||
| 46 | #define PROGNAME "usbip" | ||
| 47 | |||
| 48 | #define pr_fmt(fmt) "%s: %s: " fmt "\n", PROGNAME | ||
| 49 | #define dbg_fmt(fmt) pr_fmt("%s:%d:[%s] " fmt), "debug", \ | ||
| 50 | __FILE__, __LINE__, __func__ | ||
| 51 | |||
| 52 | #define err(fmt, args...) \ | ||
| 53 | do { \ | ||
| 54 | if (usbip_use_syslog) { \ | ||
| 55 | syslog(LOG_ERR, pr_fmt(fmt), "error", ##args); \ | ||
| 56 | } \ | ||
| 57 | if (usbip_use_stderr) { \ | ||
| 58 | fprintf(stderr, pr_fmt(fmt), "error", ##args); \ | ||
| 59 | } \ | ||
| 60 | } while (0) | ||
| 61 | |||
| 62 | #define info(fmt, args...) \ | ||
| 63 | do { \ | ||
| 64 | if (usbip_use_syslog) { \ | ||
| 65 | syslog(LOG_INFO, pr_fmt(fmt), "info", ##args); \ | ||
| 66 | } \ | ||
| 67 | if (usbip_use_stderr) { \ | ||
| 68 | fprintf(stderr, pr_fmt(fmt), "info", ##args); \ | ||
| 69 | } \ | ||
| 70 | } while (0) | ||
| 71 | |||
| 72 | #define dbg(fmt, args...) \ | ||
| 73 | do { \ | ||
| 74 | if (usbip_use_debug) { \ | ||
| 75 | if (usbip_use_syslog) { \ | ||
| 76 | syslog(LOG_DEBUG, dbg_fmt(fmt), ##args); \ | ||
| 77 | } \ | ||
| 78 | if (usbip_use_stderr) { \ | ||
| 79 | fprintf(stderr, dbg_fmt(fmt), ##args); \ | ||
| 80 | } \ | ||
| 81 | } \ | ||
| 82 | } while (0) | ||
| 83 | |||
| 84 | #define BUG() \ | ||
| 85 | do { \ | ||
| 86 | err("sorry, it's a bug!"); \ | ||
| 87 | abort(); \ | ||
| 88 | } while (0) | ||
| 89 | |||
| 90 | struct usbip_usb_interface { | ||
| 91 | uint8_t bInterfaceClass; | ||
| 92 | uint8_t bInterfaceSubClass; | ||
| 93 | uint8_t bInterfaceProtocol; | ||
| 94 | uint8_t padding; /* alignment */ | ||
| 95 | } __attribute__((packed)); | ||
| 96 | |||
| 97 | struct usbip_usb_device { | ||
| 98 | char path[SYSFS_PATH_MAX]; | ||
| 99 | char busid[SYSFS_BUS_ID_SIZE]; | ||
| 100 | |||
| 101 | uint32_t busnum; | ||
| 102 | uint32_t devnum; | ||
| 103 | uint32_t speed; | ||
| 104 | |||
| 105 | uint16_t idVendor; | ||
| 106 | uint16_t idProduct; | ||
| 107 | uint16_t bcdDevice; | ||
| 108 | |||
| 109 | uint8_t bDeviceClass; | ||
| 110 | uint8_t bDeviceSubClass; | ||
| 111 | uint8_t bDeviceProtocol; | ||
| 112 | uint8_t bConfigurationValue; | ||
| 113 | uint8_t bNumConfigurations; | ||
| 114 | uint8_t bNumInterfaces; | ||
| 115 | } __attribute__((packed)); | ||
| 116 | |||
| 117 | #define to_string(s) #s | ||
| 118 | |||
| 119 | void dump_usb_interface(struct usbip_usb_interface *); | ||
| 120 | void dump_usb_device(struct usbip_usb_device *); | ||
| 121 | int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev); | ||
| 122 | int read_attr_value(struct udev_device *dev, const char *name, | ||
| 123 | const char *format); | ||
| 124 | int read_usb_interface(struct usbip_usb_device *udev, int i, | ||
| 125 | struct usbip_usb_interface *uinf); | ||
| 126 | |||
| 127 | const char *usbip_speed_string(int num); | ||
| 128 | const char *usbip_status_string(int32_t status); | ||
| 129 | |||
| 130 | int usbip_names_init(char *); | ||
| 131 | void usbip_names_free(void); | ||
| 132 | void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, | ||
| 133 | uint16_t product); | ||
| 134 | void usbip_names_get_class(char *buff, size_t size, uint8_t class, | ||
| 135 | uint8_t subclass, uint8_t protocol); | ||
| 136 | |||
| 137 | #endif /* __USBIP_COMMON_H */ | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c deleted file mode 100644 index bef08d5c44e8..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c +++ /dev/null | |||
| @@ -1,280 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <sys/stat.h> | ||
| 21 | #include <fcntl.h> | ||
| 22 | |||
| 23 | #include <errno.h> | ||
| 24 | #include <unistd.h> | ||
| 25 | |||
| 26 | #include <libudev.h> | ||
| 27 | |||
| 28 | #include "usbip_common.h" | ||
| 29 | #include "usbip_host_driver.h" | ||
| 30 | #include "list.h" | ||
| 31 | #include "sysfs_utils.h" | ||
| 32 | |||
| 33 | #undef PROGNAME | ||
| 34 | #define PROGNAME "libusbip" | ||
| 35 | |||
| 36 | struct usbip_host_driver *host_driver; | ||
| 37 | struct udev *udev_context; | ||
| 38 | |||
| 39 | static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) | ||
| 40 | { | ||
| 41 | char status_attr_path[SYSFS_PATH_MAX]; | ||
| 42 | int fd; | ||
| 43 | int length; | ||
| 44 | char status; | ||
| 45 | int value = 0; | ||
| 46 | |||
| 47 | snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status", | ||
| 48 | udev->path); | ||
| 49 | |||
| 50 | fd = open(status_attr_path, O_RDONLY); | ||
| 51 | if (fd < 0) { | ||
| 52 | err("error opening attribute %s", status_attr_path); | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | |||
| 56 | length = read(fd, &status, 1); | ||
| 57 | if (length < 0) { | ||
| 58 | err("error reading attribute %s", status_attr_path); | ||
| 59 | close(fd); | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | |||
| 63 | value = atoi(&status); | ||
| 64 | |||
| 65 | return value; | ||
| 66 | } | ||
| 67 | |||
| 68 | static | ||
| 69 | struct usbip_exported_device *usbip_exported_device_new(const char *sdevpath) | ||
| 70 | { | ||
| 71 | struct usbip_exported_device *edev = NULL; | ||
| 72 | struct usbip_exported_device *edev_old; | ||
| 73 | size_t size; | ||
| 74 | int i; | ||
| 75 | |||
| 76 | edev = calloc(1, sizeof(struct usbip_exported_device)); | ||
| 77 | |||
| 78 | edev->sudev = udev_device_new_from_syspath(udev_context, sdevpath); | ||
| 79 | if (!edev->sudev) { | ||
| 80 | err("udev_device_new_from_syspath: %s", sdevpath); | ||
| 81 | goto err; | ||
| 82 | } | ||
| 83 | |||
| 84 | read_usb_device(edev->sudev, &edev->udev); | ||
| 85 | |||
| 86 | edev->status = read_attr_usbip_status(&edev->udev); | ||
| 87 | if (edev->status < 0) | ||
| 88 | goto err; | ||
| 89 | |||
| 90 | /* reallocate buffer to include usb interface data */ | ||
| 91 | size = sizeof(struct usbip_exported_device) + | ||
| 92 | edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface); | ||
| 93 | |||
| 94 | edev_old = edev; | ||
| 95 | edev = realloc(edev, size); | ||
| 96 | if (!edev) { | ||
| 97 | edev = edev_old; | ||
| 98 | dbg("realloc failed"); | ||
| 99 | goto err; | ||
| 100 | } | ||
| 101 | |||
| 102 | for (i = 0; i < edev->udev.bNumInterfaces; i++) | ||
| 103 | read_usb_interface(&edev->udev, i, &edev->uinf[i]); | ||
| 104 | |||
| 105 | return edev; | ||
| 106 | err: | ||
| 107 | if (edev->sudev) | ||
| 108 | udev_device_unref(edev->sudev); | ||
| 109 | if (edev) | ||
| 110 | free(edev); | ||
| 111 | |||
| 112 | return NULL; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int refresh_exported_devices(void) | ||
| 116 | { | ||
| 117 | struct usbip_exported_device *edev; | ||
| 118 | struct udev_enumerate *enumerate; | ||
| 119 | struct udev_list_entry *devices, *dev_list_entry; | ||
| 120 | struct udev_device *dev; | ||
| 121 | const char *path; | ||
| 122 | const char *driver; | ||
| 123 | |||
| 124 | enumerate = udev_enumerate_new(udev_context); | ||
| 125 | udev_enumerate_add_match_subsystem(enumerate, "usb"); | ||
| 126 | udev_enumerate_scan_devices(enumerate); | ||
| 127 | |||
| 128 | devices = udev_enumerate_get_list_entry(enumerate); | ||
| 129 | |||
| 130 | udev_list_entry_foreach(dev_list_entry, devices) { | ||
| 131 | path = udev_list_entry_get_name(dev_list_entry); | ||
| 132 | dev = udev_device_new_from_syspath(udev_context, path); | ||
| 133 | if (dev == NULL) | ||
| 134 | continue; | ||
| 135 | |||
| 136 | /* Check whether device uses usbip-host driver. */ | ||
| 137 | driver = udev_device_get_driver(dev); | ||
| 138 | if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) { | ||
| 139 | edev = usbip_exported_device_new(path); | ||
| 140 | if (!edev) { | ||
| 141 | dbg("usbip_exported_device_new failed"); | ||
| 142 | continue; | ||
| 143 | } | ||
| 144 | |||
| 145 | list_add(&edev->node, &host_driver->edev_list); | ||
| 146 | host_driver->ndevs++; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static void usbip_exported_device_destroy(void) | ||
| 154 | { | ||
| 155 | struct list_head *i, *tmp; | ||
| 156 | struct usbip_exported_device *edev; | ||
| 157 | |||
| 158 | list_for_each_safe(i, tmp, &host_driver->edev_list) { | ||
| 159 | edev = list_entry(i, struct usbip_exported_device, node); | ||
| 160 | list_del(i); | ||
| 161 | free(edev); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | int usbip_host_driver_open(void) | ||
| 166 | { | ||
| 167 | int rc; | ||
| 168 | |||
| 169 | udev_context = udev_new(); | ||
| 170 | if (!udev_context) { | ||
| 171 | err("udev_new failed"); | ||
| 172 | return -1; | ||
| 173 | } | ||
| 174 | |||
| 175 | host_driver = calloc(1, sizeof(*host_driver)); | ||
| 176 | |||
| 177 | host_driver->ndevs = 0; | ||
| 178 | INIT_LIST_HEAD(&host_driver->edev_list); | ||
| 179 | |||
| 180 | rc = refresh_exported_devices(); | ||
| 181 | if (rc < 0) | ||
| 182 | goto err_free_host_driver; | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | |||
| 186 | err_free_host_driver: | ||
| 187 | free(host_driver); | ||
| 188 | host_driver = NULL; | ||
| 189 | |||
| 190 | udev_unref(udev_context); | ||
| 191 | |||
| 192 | return -1; | ||
| 193 | } | ||
| 194 | |||
| 195 | void usbip_host_driver_close(void) | ||
| 196 | { | ||
| 197 | if (!host_driver) | ||
| 198 | return; | ||
| 199 | |||
| 200 | usbip_exported_device_destroy(); | ||
| 201 | |||
| 202 | free(host_driver); | ||
| 203 | host_driver = NULL; | ||
| 204 | |||
| 205 | udev_unref(udev_context); | ||
| 206 | } | ||
| 207 | |||
| 208 | int usbip_host_refresh_device_list(void) | ||
| 209 | { | ||
| 210 | int rc; | ||
| 211 | |||
| 212 | usbip_exported_device_destroy(); | ||
| 213 | |||
| 214 | host_driver->ndevs = 0; | ||
| 215 | INIT_LIST_HEAD(&host_driver->edev_list); | ||
| 216 | |||
| 217 | rc = refresh_exported_devices(); | ||
| 218 | if (rc < 0) | ||
| 219 | return -1; | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd) | ||
| 225 | { | ||
| 226 | char attr_name[] = "usbip_sockfd"; | ||
| 227 | char sockfd_attr_path[SYSFS_PATH_MAX]; | ||
| 228 | char sockfd_buff[30]; | ||
| 229 | int ret; | ||
| 230 | |||
| 231 | if (edev->status != SDEV_ST_AVAILABLE) { | ||
| 232 | dbg("device not available: %s", edev->udev.busid); | ||
| 233 | switch (edev->status) { | ||
| 234 | case SDEV_ST_ERROR: | ||
| 235 | dbg("status SDEV_ST_ERROR"); | ||
| 236 | break; | ||
| 237 | case SDEV_ST_USED: | ||
| 238 | dbg("status SDEV_ST_USED"); | ||
| 239 | break; | ||
| 240 | default: | ||
| 241 | dbg("status unknown: 0x%x", edev->status); | ||
| 242 | } | ||
| 243 | return -1; | ||
| 244 | } | ||
| 245 | |||
| 246 | /* only the first interface is true */ | ||
| 247 | snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s", | ||
| 248 | edev->udev.path, attr_name); | ||
| 249 | |||
| 250 | snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); | ||
| 251 | |||
| 252 | ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff, | ||
| 253 | strlen(sockfd_buff)); | ||
| 254 | if (ret < 0) { | ||
| 255 | err("write_sysfs_attribute failed: sockfd %s to %s", | ||
| 256 | sockfd_buff, sockfd_attr_path); | ||
| 257 | return ret; | ||
| 258 | } | ||
| 259 | |||
| 260 | info("connect: %s", edev->udev.busid); | ||
| 261 | |||
| 262 | return ret; | ||
| 263 | } | ||
| 264 | |||
| 265 | struct usbip_exported_device *usbip_host_get_device(int num) | ||
| 266 | { | ||
| 267 | struct list_head *i; | ||
| 268 | struct usbip_exported_device *edev; | ||
| 269 | int cnt = 0; | ||
| 270 | |||
| 271 | list_for_each(i, &host_driver->edev_list) { | ||
| 272 | edev = list_entry(i, struct usbip_exported_device, node); | ||
| 273 | if (num == cnt) | ||
| 274 | return edev; | ||
| 275 | else | ||
| 276 | cnt++; | ||
| 277 | } | ||
| 278 | |||
| 279 | return NULL; | ||
| 280 | } | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h deleted file mode 100644 index 2a31f855c616..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __USBIP_HOST_DRIVER_H | ||
| 20 | #define __USBIP_HOST_DRIVER_H | ||
| 21 | |||
| 22 | #include <stdint.h> | ||
| 23 | #include "usbip_common.h" | ||
| 24 | #include "list.h" | ||
| 25 | |||
| 26 | struct usbip_host_driver { | ||
| 27 | int ndevs; | ||
| 28 | /* list of exported device */ | ||
| 29 | struct list_head edev_list; | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct usbip_exported_device { | ||
| 33 | struct udev_device *sudev; | ||
| 34 | int32_t status; | ||
| 35 | struct usbip_usb_device udev; | ||
| 36 | struct list_head node; | ||
| 37 | struct usbip_usb_interface uinf[]; | ||
| 38 | }; | ||
| 39 | |||
| 40 | extern struct usbip_host_driver *host_driver; | ||
| 41 | |||
| 42 | int usbip_host_driver_open(void); | ||
| 43 | void usbip_host_driver_close(void); | ||
| 44 | |||
| 45 | int usbip_host_refresh_device_list(void); | ||
| 46 | int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd); | ||
| 47 | struct usbip_exported_device *usbip_host_get_device(int num); | ||
| 48 | |||
| 49 | #endif /* __USBIP_HOST_DRIVER_H */ | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c deleted file mode 100644 index ad9204773533..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ /dev/null | |||
| @@ -1,411 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include "usbip_common.h" | ||
| 6 | #include "vhci_driver.h" | ||
| 7 | #include <limits.h> | ||
| 8 | #include <netdb.h> | ||
| 9 | #include <libudev.h> | ||
| 10 | #include "sysfs_utils.h" | ||
| 11 | |||
| 12 | #undef PROGNAME | ||
| 13 | #define PROGNAME "libusbip" | ||
| 14 | |||
| 15 | struct usbip_vhci_driver *vhci_driver; | ||
| 16 | struct udev *udev_context; | ||
| 17 | |||
| 18 | static struct usbip_imported_device * | ||
| 19 | imported_device_init(struct usbip_imported_device *idev, char *busid) | ||
| 20 | { | ||
| 21 | struct udev_device *sudev; | ||
| 22 | |||
| 23 | sudev = udev_device_new_from_subsystem_sysname(udev_context, | ||
| 24 | "usb", busid); | ||
| 25 | if (!sudev) { | ||
| 26 | dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); | ||
| 27 | goto err; | ||
| 28 | } | ||
| 29 | read_usb_device(sudev, &idev->udev); | ||
| 30 | udev_device_unref(sudev); | ||
| 31 | |||
| 32 | return idev; | ||
| 33 | |||
| 34 | err: | ||
| 35 | return NULL; | ||
| 36 | } | ||
| 37 | |||
| 38 | |||
| 39 | |||
| 40 | static int parse_status(const char *value) | ||
| 41 | { | ||
| 42 | int ret = 0; | ||
| 43 | char *c; | ||
| 44 | |||
| 45 | |||
| 46 | for (int i = 0; i < vhci_driver->nports; i++) | ||
| 47 | memset(&vhci_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); | ||
| 48 | |||
| 49 | |||
| 50 | /* skip a header line */ | ||
| 51 | c = strchr(value, '\n'); | ||
| 52 | if (!c) | ||
| 53 | return -1; | ||
| 54 | c++; | ||
| 55 | |||
| 56 | while (*c != '\0') { | ||
| 57 | int port, status, speed, devid; | ||
| 58 | unsigned long socket; | ||
| 59 | char lbusid[SYSFS_BUS_ID_SIZE]; | ||
| 60 | |||
| 61 | ret = sscanf(c, "%d %d %d %x %lx %31s\n", | ||
| 62 | &port, &status, &speed, | ||
| 63 | &devid, &socket, lbusid); | ||
| 64 | |||
| 65 | if (ret < 5) { | ||
| 66 | dbg("sscanf failed: %d", ret); | ||
| 67 | BUG(); | ||
| 68 | } | ||
| 69 | |||
| 70 | dbg("port %d status %d speed %d devid %x", | ||
| 71 | port, status, speed, devid); | ||
| 72 | dbg("socket %lx lbusid %s", socket, lbusid); | ||
| 73 | |||
| 74 | |||
| 75 | /* if a device is connected, look at it */ | ||
| 76 | { | ||
| 77 | struct usbip_imported_device *idev = &vhci_driver->idev[port]; | ||
| 78 | |||
| 79 | idev->port = port; | ||
| 80 | idev->status = status; | ||
| 81 | |||
| 82 | idev->devid = devid; | ||
| 83 | |||
| 84 | idev->busnum = (devid >> 16); | ||
| 85 | idev->devnum = (devid & 0x0000ffff); | ||
| 86 | |||
| 87 | if (idev->status != VDEV_ST_NULL | ||
| 88 | && idev->status != VDEV_ST_NOTASSIGNED) { | ||
| 89 | idev = imported_device_init(idev, lbusid); | ||
| 90 | if (!idev) { | ||
| 91 | dbg("imported_device_init failed"); | ||
| 92 | return -1; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | |||
| 98 | /* go to the next line */ | ||
| 99 | c = strchr(c, '\n'); | ||
| 100 | if (!c) | ||
| 101 | break; | ||
| 102 | c++; | ||
| 103 | } | ||
| 104 | |||
| 105 | dbg("exit"); | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int refresh_imported_device_list(void) | ||
| 111 | { | ||
| 112 | const char *attr_status; | ||
| 113 | |||
| 114 | attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, | ||
| 115 | "status"); | ||
| 116 | if (!attr_status) { | ||
| 117 | err("udev_device_get_sysattr_value failed"); | ||
| 118 | return -1; | ||
| 119 | } | ||
| 120 | |||
| 121 | return parse_status(attr_status); | ||
| 122 | } | ||
| 123 | |||
| 124 | static int get_nports(void) | ||
| 125 | { | ||
| 126 | char *c; | ||
| 127 | int nports = 0; | ||
| 128 | const char *attr_status; | ||
| 129 | |||
| 130 | attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, | ||
| 131 | "status"); | ||
| 132 | if (!attr_status) { | ||
| 133 | err("udev_device_get_sysattr_value failed"); | ||
| 134 | return -1; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* skip a header line */ | ||
| 138 | c = strchr(attr_status, '\n'); | ||
| 139 | if (!c) | ||
| 140 | return 0; | ||
| 141 | c++; | ||
| 142 | |||
| 143 | while (*c != '\0') { | ||
| 144 | /* go to the next line */ | ||
| 145 | c = strchr(c, '\n'); | ||
| 146 | if (!c) | ||
| 147 | return nports; | ||
| 148 | c++; | ||
| 149 | nports += 1; | ||
| 150 | } | ||
| 151 | |||
| 152 | return nports; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* | ||
| 156 | * Read the given port's record. | ||
| 157 | * | ||
| 158 | * To avoid buffer overflow we will read the entire line and | ||
| 159 | * validate each part's size. The initial buffer is padded by 4 to | ||
| 160 | * accommodate the 2 spaces, 1 newline and an additional character | ||
| 161 | * which is needed to properly validate the 3rd part without it being | ||
| 162 | * truncated to an acceptable length. | ||
| 163 | */ | ||
| 164 | static int read_record(int rhport, char *host, unsigned long host_len, | ||
| 165 | char *port, unsigned long port_len, char *busid) | ||
| 166 | { | ||
| 167 | int part; | ||
| 168 | FILE *file; | ||
| 169 | char path[PATH_MAX+1]; | ||
| 170 | char *buffer, *start, *end; | ||
| 171 | char delim[] = {' ', ' ', '\n'}; | ||
| 172 | int max_len[] = {(int)host_len, (int)port_len, SYSFS_BUS_ID_SIZE}; | ||
| 173 | size_t buffer_len = host_len + port_len + SYSFS_BUS_ID_SIZE + 4; | ||
| 174 | |||
| 175 | buffer = malloc(buffer_len); | ||
| 176 | if (!buffer) | ||
| 177 | return -1; | ||
| 178 | |||
| 179 | snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); | ||
| 180 | |||
| 181 | file = fopen(path, "r"); | ||
| 182 | if (!file) { | ||
| 183 | err("fopen"); | ||
| 184 | free(buffer); | ||
| 185 | return -1; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (fgets(buffer, buffer_len, file) == NULL) { | ||
| 189 | err("fgets"); | ||
| 190 | free(buffer); | ||
| 191 | fclose(file); | ||
| 192 | return -1; | ||
| 193 | } | ||
| 194 | fclose(file); | ||
| 195 | |||
| 196 | /* validate the length of each of the 3 parts */ | ||
| 197 | start = buffer; | ||
| 198 | for (part = 0; part < 3; part++) { | ||
| 199 | end = strchr(start, delim[part]); | ||
| 200 | if (end == NULL || (end - start) > max_len[part]) { | ||
| 201 | free(buffer); | ||
| 202 | return -1; | ||
| 203 | } | ||
| 204 | start = end + 1; | ||
| 205 | } | ||
| 206 | |||
| 207 | if (sscanf(buffer, "%s %s %s\n", host, port, busid) != 3) { | ||
| 208 | err("sscanf"); | ||
| 209 | free(buffer); | ||
| 210 | return -1; | ||
| 211 | } | ||
| 212 | |||
| 213 | free(buffer); | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* ---------------------------------------------------------------------- */ | ||
| 219 | |||
| 220 | int usbip_vhci_driver_open(void) | ||
| 221 | { | ||
| 222 | udev_context = udev_new(); | ||
| 223 | if (!udev_context) { | ||
| 224 | err("udev_new failed"); | ||
| 225 | return -1; | ||
| 226 | } | ||
| 227 | |||
| 228 | vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); | ||
| 229 | |||
| 230 | /* will be freed in usbip_driver_close() */ | ||
| 231 | vhci_driver->hc_device = | ||
| 232 | udev_device_new_from_subsystem_sysname(udev_context, | ||
| 233 | USBIP_VHCI_BUS_TYPE, | ||
| 234 | USBIP_VHCI_DRV_NAME); | ||
| 235 | if (!vhci_driver->hc_device) { | ||
| 236 | err("udev_device_new_from_subsystem_sysname failed"); | ||
| 237 | goto err; | ||
| 238 | } | ||
| 239 | |||
| 240 | vhci_driver->nports = get_nports(); | ||
| 241 | |||
| 242 | dbg("available ports: %d", vhci_driver->nports); | ||
| 243 | |||
| 244 | if (refresh_imported_device_list()) | ||
| 245 | goto err; | ||
| 246 | |||
| 247 | return 0; | ||
| 248 | |||
| 249 | err: | ||
| 250 | udev_device_unref(vhci_driver->hc_device); | ||
| 251 | |||
| 252 | if (vhci_driver) | ||
| 253 | free(vhci_driver); | ||
| 254 | |||
| 255 | vhci_driver = NULL; | ||
| 256 | |||
| 257 | udev_unref(udev_context); | ||
| 258 | |||
| 259 | return -1; | ||
| 260 | } | ||
| 261 | |||
| 262 | |||
| 263 | void usbip_vhci_driver_close(void) | ||
| 264 | { | ||
| 265 | if (!vhci_driver) | ||
| 266 | return; | ||
| 267 | |||
| 268 | udev_device_unref(vhci_driver->hc_device); | ||
| 269 | |||
| 270 | free(vhci_driver); | ||
| 271 | |||
| 272 | vhci_driver = NULL; | ||
| 273 | |||
| 274 | udev_unref(udev_context); | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 278 | int usbip_vhci_refresh_device_list(void) | ||
| 279 | { | ||
| 280 | |||
| 281 | if (refresh_imported_device_list()) | ||
| 282 | goto err; | ||
| 283 | |||
| 284 | return 0; | ||
| 285 | err: | ||
| 286 | dbg("failed to refresh device list"); | ||
| 287 | return -1; | ||
| 288 | } | ||
| 289 | |||
| 290 | |||
| 291 | int usbip_vhci_get_free_port(void) | ||
| 292 | { | ||
| 293 | for (int i = 0; i < vhci_driver->nports; i++) { | ||
| 294 | if (vhci_driver->idev[i].status == VDEV_ST_NULL) | ||
| 295 | return i; | ||
| 296 | } | ||
| 297 | |||
| 298 | return -1; | ||
| 299 | } | ||
| 300 | |||
| 301 | int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, | ||
| 302 | uint32_t speed) { | ||
| 303 | char buff[200]; /* what size should be ? */ | ||
| 304 | char attach_attr_path[SYSFS_PATH_MAX]; | ||
| 305 | char attr_attach[] = "attach"; | ||
| 306 | const char *path; | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | snprintf(buff, sizeof(buff), "%u %d %u %u", | ||
| 310 | port, sockfd, devid, speed); | ||
| 311 | dbg("writing: %s", buff); | ||
| 312 | |||
| 313 | path = udev_device_get_syspath(vhci_driver->hc_device); | ||
| 314 | snprintf(attach_attr_path, sizeof(attach_attr_path), "%s/%s", | ||
| 315 | path, attr_attach); | ||
| 316 | dbg("attach attribute path: %s", attach_attr_path); | ||
| 317 | |||
| 318 | ret = write_sysfs_attribute(attach_attr_path, buff, strlen(buff)); | ||
| 319 | if (ret < 0) { | ||
| 320 | dbg("write_sysfs_attribute failed"); | ||
| 321 | return -1; | ||
| 322 | } | ||
| 323 | |||
| 324 | dbg("attached port: %d", port); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | static unsigned long get_devid(uint8_t busnum, uint8_t devnum) | ||
| 330 | { | ||
| 331 | return (busnum << 16) | devnum; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* will be removed */ | ||
| 335 | int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum, | ||
| 336 | uint8_t devnum, uint32_t speed) | ||
| 337 | { | ||
| 338 | int devid = get_devid(busnum, devnum); | ||
| 339 | |||
| 340 | return usbip_vhci_attach_device2(port, sockfd, devid, speed); | ||
| 341 | } | ||
| 342 | |||
| 343 | int usbip_vhci_detach_device(uint8_t port) | ||
| 344 | { | ||
| 345 | char detach_attr_path[SYSFS_PATH_MAX]; | ||
| 346 | char attr_detach[] = "detach"; | ||
| 347 | char buff[200]; /* what size should be ? */ | ||
| 348 | const char *path; | ||
| 349 | int ret; | ||
| 350 | |||
| 351 | snprintf(buff, sizeof(buff), "%u", port); | ||
| 352 | dbg("writing: %s", buff); | ||
| 353 | |||
| 354 | path = udev_device_get_syspath(vhci_driver->hc_device); | ||
| 355 | snprintf(detach_attr_path, sizeof(detach_attr_path), "%s/%s", | ||
| 356 | path, attr_detach); | ||
| 357 | dbg("detach attribute path: %s", detach_attr_path); | ||
| 358 | |||
| 359 | ret = write_sysfs_attribute(detach_attr_path, buff, strlen(buff)); | ||
| 360 | if (ret < 0) { | ||
| 361 | dbg("write_sysfs_attribute failed"); | ||
| 362 | return -1; | ||
| 363 | } | ||
| 364 | |||
| 365 | dbg("detached port: %d", port); | ||
| 366 | |||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) | ||
| 371 | { | ||
| 372 | char product_name[100]; | ||
| 373 | char host[NI_MAXHOST] = "unknown host"; | ||
| 374 | char serv[NI_MAXSERV] = "unknown port"; | ||
| 375 | char remote_busid[SYSFS_BUS_ID_SIZE]; | ||
| 376 | int ret; | ||
| 377 | int read_record_error = 0; | ||
| 378 | |||
| 379 | if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) | ||
| 380 | return 0; | ||
| 381 | |||
| 382 | ret = read_record(idev->port, host, sizeof(host), serv, sizeof(serv), | ||
| 383 | remote_busid); | ||
| 384 | if (ret) { | ||
| 385 | err("read_record"); | ||
| 386 | read_record_error = 1; | ||
| 387 | } | ||
| 388 | |||
| 389 | printf("Port %02d: <%s> at %s\n", idev->port, | ||
| 390 | usbip_status_string(idev->status), | ||
| 391 | usbip_speed_string(idev->udev.speed)); | ||
| 392 | |||
| 393 | usbip_names_get_product(product_name, sizeof(product_name), | ||
| 394 | idev->udev.idVendor, idev->udev.idProduct); | ||
| 395 | |||
| 396 | printf(" %s\n", product_name); | ||
| 397 | |||
| 398 | if (!read_record_error) { | ||
| 399 | printf("%10s -> usbip://%s:%s/%s\n", idev->udev.busid, | ||
| 400 | host, serv, remote_busid); | ||
| 401 | printf("%10s -> remote bus/dev %03d/%03d\n", " ", | ||
| 402 | idev->busnum, idev->devnum); | ||
| 403 | } else { | ||
| 404 | printf("%10s -> unknown host, remote port and remote busid\n", | ||
| 405 | idev->udev.busid); | ||
| 406 | printf("%10s -> remote bus/dev %03d/%03d\n", " ", | ||
| 407 | idev->busnum, idev->devnum); | ||
| 408 | } | ||
| 409 | |||
| 410 | return 0; | ||
| 411 | } | ||
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h deleted file mode 100644 index fa2316cf2cac..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef __VHCI_DRIVER_H | ||
| 6 | #define __VHCI_DRIVER_H | ||
| 7 | |||
| 8 | #include <libudev.h> | ||
| 9 | #include <stdint.h> | ||
| 10 | |||
| 11 | #include "usbip_common.h" | ||
| 12 | |||
| 13 | #define USBIP_VHCI_BUS_TYPE "platform" | ||
| 14 | #define MAXNPORT 128 | ||
| 15 | |||
| 16 | struct usbip_imported_device { | ||
| 17 | uint8_t port; | ||
| 18 | uint32_t status; | ||
| 19 | |||
| 20 | uint32_t devid; | ||
| 21 | |||
| 22 | uint8_t busnum; | ||
| 23 | uint8_t devnum; | ||
| 24 | |||
| 25 | /* usbip_class_device list */ | ||
| 26 | struct usbip_usb_device udev; | ||
| 27 | }; | ||
| 28 | |||
| 29 | struct usbip_vhci_driver { | ||
| 30 | |||
| 31 | /* /sys/devices/platform/vhci_hcd */ | ||
| 32 | struct udev_device *hc_device; | ||
| 33 | |||
| 34 | int nports; | ||
| 35 | struct usbip_imported_device idev[MAXNPORT]; | ||
| 36 | }; | ||
| 37 | |||
| 38 | |||
| 39 | extern struct usbip_vhci_driver *vhci_driver; | ||
| 40 | |||
| 41 | int usbip_vhci_driver_open(void); | ||
| 42 | void usbip_vhci_driver_close(void); | ||
| 43 | |||
| 44 | int usbip_vhci_refresh_device_list(void); | ||
| 45 | |||
| 46 | |||
| 47 | int usbip_vhci_get_free_port(void); | ||
| 48 | int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, | ||
| 49 | uint32_t speed); | ||
| 50 | |||
| 51 | /* will be removed */ | ||
| 52 | int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum, | ||
| 53 | uint8_t devnum, uint32_t speed); | ||
| 54 | |||
| 55 | int usbip_vhci_detach_device(uint8_t port); | ||
| 56 | |||
| 57 | int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev); | ||
| 58 | |||
| 59 | #endif /* __VHCI_DRIVER_H */ | ||
diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am deleted file mode 100644 index e81a4ebadeff..000000000000 --- a/drivers/staging/usbip/userspace/src/Makefile.am +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' | ||
| 2 | AM_CFLAGS = @EXTRA_CFLAGS@ | ||
| 3 | LDADD = $(top_builddir)/libsrc/libusbip.la | ||
| 4 | |||
| 5 | sbin_PROGRAMS := usbip usbipd | ||
| 6 | |||
| 7 | usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ | ||
| 8 | usbip_attach.c usbip_detach.c usbip_list.c \ | ||
| 9 | usbip_bind.c usbip_unbind.c usbip_port.c | ||
| 10 | |||
| 11 | usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip.c b/drivers/staging/usbip/userspace/src/usbip.c deleted file mode 100644 index d7599d943529..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip.c +++ /dev/null | |||
| @@ -1,201 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * command structure borrowed from udev | ||
| 3 | * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) | ||
| 4 | * | ||
| 5 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 6 | * 2005-2007 Takahiro Hirofuchi | ||
| 7 | * | ||
| 8 | * This program is free software: you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation, either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | |||
| 25 | #include <getopt.h> | ||
| 26 | #include <syslog.h> | ||
| 27 | |||
| 28 | #include "usbip_common.h" | ||
| 29 | #include "usbip_network.h" | ||
| 30 | #include "usbip.h" | ||
| 31 | |||
| 32 | static int usbip_help(int argc, char *argv[]); | ||
| 33 | static int usbip_version(int argc, char *argv[]); | ||
| 34 | |||
| 35 | static const char usbip_version_string[] = PACKAGE_STRING; | ||
| 36 | |||
| 37 | static const char usbip_usage_string[] = | ||
| 38 | "usbip [--debug] [--log] [--tcp-port PORT] [version]\n" | ||
| 39 | " [help] <command> <args>\n"; | ||
| 40 | |||
| 41 | static void usbip_usage(void) | ||
| 42 | { | ||
| 43 | printf("usage: %s", usbip_usage_string); | ||
| 44 | } | ||
| 45 | |||
| 46 | struct command { | ||
| 47 | const char *name; | ||
| 48 | int (*fn)(int argc, char *argv[]); | ||
| 49 | const char *help; | ||
| 50 | void (*usage)(void); | ||
| 51 | }; | ||
| 52 | |||
| 53 | static const struct command cmds[] = { | ||
| 54 | { | ||
| 55 | .name = "help", | ||
| 56 | .fn = usbip_help, | ||
| 57 | .help = NULL, | ||
| 58 | .usage = NULL | ||
| 59 | }, | ||
| 60 | { | ||
| 61 | .name = "version", | ||
| 62 | .fn = usbip_version, | ||
| 63 | .help = NULL, | ||
| 64 | .usage = NULL | ||
| 65 | }, | ||
| 66 | { | ||
| 67 | .name = "attach", | ||
| 68 | .fn = usbip_attach, | ||
| 69 | .help = "Attach a remote USB device", | ||
| 70 | .usage = usbip_attach_usage | ||
| 71 | }, | ||
| 72 | { | ||
| 73 | .name = "detach", | ||
| 74 | .fn = usbip_detach, | ||
| 75 | .help = "Detach a remote USB device", | ||
| 76 | .usage = usbip_detach_usage | ||
| 77 | }, | ||
| 78 | { | ||
| 79 | .name = "list", | ||
| 80 | .fn = usbip_list, | ||
| 81 | .help = "List exportable or local USB devices", | ||
| 82 | .usage = usbip_list_usage | ||
| 83 | }, | ||
| 84 | { | ||
| 85 | .name = "bind", | ||
| 86 | .fn = usbip_bind, | ||
| 87 | .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko", | ||
| 88 | .usage = usbip_bind_usage | ||
| 89 | }, | ||
| 90 | { | ||
| 91 | .name = "unbind", | ||
| 92 | .fn = usbip_unbind, | ||
| 93 | .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko", | ||
| 94 | .usage = usbip_unbind_usage | ||
| 95 | }, | ||
| 96 | { | ||
| 97 | .name = "port", | ||
| 98 | .fn = usbip_port_show, | ||
| 99 | .help = "Show imported USB devices", | ||
| 100 | .usage = NULL | ||
| 101 | }, | ||
| 102 | { NULL, NULL, NULL, NULL } | ||
| 103 | }; | ||
| 104 | |||
| 105 | static int usbip_help(int argc, char *argv[]) | ||
| 106 | { | ||
| 107 | const struct command *cmd; | ||
| 108 | int i; | ||
| 109 | int ret = 0; | ||
| 110 | |||
| 111 | if (argc > 1 && argv++) { | ||
| 112 | for (i = 0; cmds[i].name != NULL; i++) | ||
| 113 | if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) { | ||
| 114 | cmds[i].usage(); | ||
| 115 | goto done; | ||
| 116 | } | ||
| 117 | ret = -1; | ||
| 118 | } | ||
| 119 | |||
| 120 | usbip_usage(); | ||
| 121 | printf("\n"); | ||
| 122 | for (cmd = cmds; cmd->name != NULL; cmd++) | ||
| 123 | if (cmd->help != NULL) | ||
| 124 | printf(" %-10s %s\n", cmd->name, cmd->help); | ||
| 125 | printf("\n"); | ||
| 126 | done: | ||
| 127 | return ret; | ||
| 128 | } | ||
| 129 | |||
| 130 | static int usbip_version(int argc, char *argv[]) | ||
| 131 | { | ||
| 132 | (void) argc; | ||
| 133 | (void) argv; | ||
| 134 | |||
| 135 | printf(PROGNAME " (%s)\n", usbip_version_string); | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int run_command(const struct command *cmd, int argc, char *argv[]) | ||
| 140 | { | ||
| 141 | dbg("running command: `%s'", cmd->name); | ||
| 142 | return cmd->fn(argc, argv); | ||
| 143 | } | ||
| 144 | |||
| 145 | int main(int argc, char *argv[]) | ||
| 146 | { | ||
| 147 | static const struct option opts[] = { | ||
| 148 | { "debug", no_argument, NULL, 'd' }, | ||
| 149 | { "log", no_argument, NULL, 'l' }, | ||
| 150 | { "tcp-port", required_argument, NULL, 't' }, | ||
| 151 | { NULL, 0, NULL, 0 } | ||
| 152 | }; | ||
| 153 | |||
| 154 | char *cmd; | ||
| 155 | int opt; | ||
| 156 | int i, rc = -1; | ||
| 157 | |||
| 158 | usbip_use_stderr = 1; | ||
| 159 | opterr = 0; | ||
| 160 | for (;;) { | ||
| 161 | opt = getopt_long(argc, argv, "+dlt:", opts, NULL); | ||
| 162 | |||
| 163 | if (opt == -1) | ||
| 164 | break; | ||
| 165 | |||
| 166 | switch (opt) { | ||
| 167 | case 'd': | ||
| 168 | usbip_use_debug = 1; | ||
| 169 | break; | ||
| 170 | case 'l': | ||
| 171 | usbip_use_syslog = 1; | ||
| 172 | openlog("", LOG_PID, LOG_USER); | ||
| 173 | break; | ||
| 174 | case 't': | ||
| 175 | usbip_setup_port_number(optarg); | ||
| 176 | break; | ||
| 177 | case '?': | ||
| 178 | printf("usbip: invalid option\n"); | ||
| 179 | default: | ||
| 180 | usbip_usage(); | ||
| 181 | goto out; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | cmd = argv[optind]; | ||
| 186 | if (cmd) { | ||
| 187 | for (i = 0; cmds[i].name != NULL; i++) | ||
| 188 | if (!strcmp(cmds[i].name, cmd)) { | ||
| 189 | argc -= optind; | ||
| 190 | argv += optind; | ||
| 191 | optind = 0; | ||
| 192 | rc = run_command(&cmds[i], argc, argv); | ||
| 193 | goto out; | ||
| 194 | } | ||
| 195 | } | ||
| 196 | |||
| 197 | /* invalid command */ | ||
| 198 | usbip_help(0, NULL); | ||
| 199 | out: | ||
| 200 | return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); | ||
| 201 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip.h b/drivers/staging/usbip/userspace/src/usbip.h deleted file mode 100644 index 84fe66a9d8ad..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip.h +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __USBIP_H | ||
| 20 | #define __USBIP_H | ||
| 21 | |||
| 22 | #ifdef HAVE_CONFIG_H | ||
| 23 | #include "../config.h" | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* usbip commands */ | ||
| 27 | int usbip_attach(int argc, char *argv[]); | ||
| 28 | int usbip_detach(int argc, char *argv[]); | ||
| 29 | int usbip_list(int argc, char *argv[]); | ||
| 30 | int usbip_bind(int argc, char *argv[]); | ||
| 31 | int usbip_unbind(int argc, char *argv[]); | ||
| 32 | int usbip_port_show(int argc, char *argv[]); | ||
| 33 | |||
| 34 | void usbip_attach_usage(void); | ||
| 35 | void usbip_detach_usage(void); | ||
| 36 | void usbip_list_usage(void); | ||
| 37 | void usbip_bind_usage(void); | ||
| 38 | void usbip_unbind_usage(void); | ||
| 39 | |||
| 40 | #endif /* __USBIP_H */ | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/drivers/staging/usbip/userspace/src/usbip_attach.c deleted file mode 100644 index d58a14dfc094..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_attach.c +++ /dev/null | |||
| @@ -1,241 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/stat.h> | ||
| 20 | |||
| 21 | #include <limits.h> | ||
| 22 | #include <stdint.h> | ||
| 23 | #include <stdio.h> | ||
| 24 | #include <string.h> | ||
| 25 | |||
| 26 | #include <fcntl.h> | ||
| 27 | #include <getopt.h> | ||
| 28 | #include <unistd.h> | ||
| 29 | #include <errno.h> | ||
| 30 | |||
| 31 | #include "vhci_driver.h" | ||
| 32 | #include "usbip_common.h" | ||
| 33 | #include "usbip_network.h" | ||
| 34 | #include "usbip.h" | ||
| 35 | |||
| 36 | static const char usbip_attach_usage_string[] = | ||
| 37 | "usbip attach <args>\n" | ||
| 38 | " -r, --remote=<host> The machine with exported USB devices\n" | ||
| 39 | " -b, --busid=<busid> Busid of the device on <host>\n"; | ||
| 40 | |||
| 41 | void usbip_attach_usage(void) | ||
| 42 | { | ||
| 43 | printf("usage: %s", usbip_attach_usage_string); | ||
| 44 | } | ||
| 45 | |||
| 46 | #define MAX_BUFF 100 | ||
| 47 | static int record_connection(char *host, char *port, char *busid, int rhport) | ||
| 48 | { | ||
| 49 | int fd; | ||
| 50 | char path[PATH_MAX+1]; | ||
| 51 | char buff[MAX_BUFF+1]; | ||
| 52 | int ret; | ||
| 53 | |||
| 54 | ret = mkdir(VHCI_STATE_PATH, 0700); | ||
| 55 | if (ret < 0) { | ||
| 56 | /* if VHCI_STATE_PATH exists, then it better be a directory */ | ||
| 57 | if (errno == EEXIST) { | ||
| 58 | struct stat s; | ||
| 59 | |||
| 60 | ret = stat(VHCI_STATE_PATH, &s); | ||
| 61 | if (ret < 0) | ||
| 62 | return -1; | ||
| 63 | if (!(s.st_mode & S_IFDIR)) | ||
| 64 | return -1; | ||
| 65 | } else | ||
| 66 | return -1; | ||
| 67 | } | ||
| 68 | |||
| 69 | snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); | ||
| 70 | |||
| 71 | fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); | ||
| 72 | if (fd < 0) | ||
| 73 | return -1; | ||
| 74 | |||
| 75 | snprintf(buff, MAX_BUFF, "%s %s %s\n", | ||
| 76 | host, port, busid); | ||
| 77 | |||
| 78 | ret = write(fd, buff, strlen(buff)); | ||
| 79 | if (ret != (ssize_t) strlen(buff)) { | ||
| 80 | close(fd); | ||
| 81 | return -1; | ||
| 82 | } | ||
| 83 | |||
| 84 | close(fd); | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int import_device(int sockfd, struct usbip_usb_device *udev) | ||
| 90 | { | ||
| 91 | int rc; | ||
| 92 | int port; | ||
| 93 | |||
| 94 | rc = usbip_vhci_driver_open(); | ||
| 95 | if (rc < 0) { | ||
| 96 | err("open vhci_driver"); | ||
| 97 | return -1; | ||
| 98 | } | ||
| 99 | |||
| 100 | port = usbip_vhci_get_free_port(); | ||
| 101 | if (port < 0) { | ||
| 102 | err("no free port"); | ||
| 103 | usbip_vhci_driver_close(); | ||
| 104 | return -1; | ||
| 105 | } | ||
| 106 | |||
| 107 | rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, | ||
| 108 | udev->devnum, udev->speed); | ||
| 109 | if (rc < 0) { | ||
| 110 | err("import device"); | ||
| 111 | usbip_vhci_driver_close(); | ||
| 112 | return -1; | ||
| 113 | } | ||
| 114 | |||
| 115 | usbip_vhci_driver_close(); | ||
| 116 | |||
| 117 | return port; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int query_import_device(int sockfd, char *busid) | ||
| 121 | { | ||
| 122 | int rc; | ||
| 123 | struct op_import_request request; | ||
| 124 | struct op_import_reply reply; | ||
| 125 | uint16_t code = OP_REP_IMPORT; | ||
| 126 | |||
| 127 | memset(&request, 0, sizeof(request)); | ||
| 128 | memset(&reply, 0, sizeof(reply)); | ||
| 129 | |||
| 130 | /* send a request */ | ||
| 131 | rc = usbip_net_send_op_common(sockfd, OP_REQ_IMPORT, 0); | ||
| 132 | if (rc < 0) { | ||
| 133 | err("send op_common"); | ||
| 134 | return -1; | ||
| 135 | } | ||
| 136 | |||
| 137 | strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1); | ||
| 138 | |||
| 139 | PACK_OP_IMPORT_REQUEST(0, &request); | ||
| 140 | |||
| 141 | rc = usbip_net_send(sockfd, (void *) &request, sizeof(request)); | ||
| 142 | if (rc < 0) { | ||
| 143 | err("send op_import_request"); | ||
| 144 | return -1; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* receive a reply */ | ||
| 148 | rc = usbip_net_recv_op_common(sockfd, &code); | ||
| 149 | if (rc < 0) { | ||
| 150 | err("recv op_common"); | ||
| 151 | return -1; | ||
| 152 | } | ||
| 153 | |||
| 154 | rc = usbip_net_recv(sockfd, (void *) &reply, sizeof(reply)); | ||
| 155 | if (rc < 0) { | ||
| 156 | err("recv op_import_reply"); | ||
| 157 | return -1; | ||
| 158 | } | ||
| 159 | |||
| 160 | PACK_OP_IMPORT_REPLY(0, &reply); | ||
| 161 | |||
| 162 | /* check the reply */ | ||
| 163 | if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) { | ||
| 164 | err("recv different busid %s", reply.udev.busid); | ||
| 165 | return -1; | ||
| 166 | } | ||
| 167 | |||
| 168 | /* import a device */ | ||
| 169 | return import_device(sockfd, &reply.udev); | ||
| 170 | } | ||
| 171 | |||
| 172 | static int attach_device(char *host, char *busid) | ||
| 173 | { | ||
| 174 | int sockfd; | ||
| 175 | int rc; | ||
| 176 | int rhport; | ||
| 177 | |||
| 178 | sockfd = usbip_net_tcp_connect(host, usbip_port_string); | ||
| 179 | if (sockfd < 0) { | ||
| 180 | err("tcp connect"); | ||
| 181 | return -1; | ||
| 182 | } | ||
| 183 | |||
| 184 | rhport = query_import_device(sockfd, busid); | ||
| 185 | if (rhport < 0) { | ||
| 186 | err("query"); | ||
| 187 | return -1; | ||
| 188 | } | ||
| 189 | |||
| 190 | close(sockfd); | ||
| 191 | |||
| 192 | rc = record_connection(host, usbip_port_string, busid, rhport); | ||
| 193 | if (rc < 0) { | ||
| 194 | err("record connection"); | ||
| 195 | return -1; | ||
| 196 | } | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | int usbip_attach(int argc, char *argv[]) | ||
| 202 | { | ||
| 203 | static const struct option opts[] = { | ||
| 204 | { "remote", required_argument, NULL, 'r' }, | ||
| 205 | { "busid", required_argument, NULL, 'b' }, | ||
| 206 | { NULL, 0, NULL, 0 } | ||
| 207 | }; | ||
| 208 | char *host = NULL; | ||
| 209 | char *busid = NULL; | ||
| 210 | int opt; | ||
| 211 | int ret = -1; | ||
| 212 | |||
| 213 | for (;;) { | ||
| 214 | opt = getopt_long(argc, argv, "r:b:", opts, NULL); | ||
| 215 | |||
| 216 | if (opt == -1) | ||
| 217 | break; | ||
| 218 | |||
| 219 | switch (opt) { | ||
| 220 | case 'r': | ||
| 221 | host = optarg; | ||
| 222 | break; | ||
| 223 | case 'b': | ||
| 224 | busid = optarg; | ||
| 225 | break; | ||
| 226 | default: | ||
| 227 | goto err_out; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | if (!host || !busid) | ||
| 232 | goto err_out; | ||
| 233 | |||
| 234 | ret = attach_device(host, busid); | ||
| 235 | goto out; | ||
| 236 | |||
| 237 | err_out: | ||
| 238 | usbip_attach_usage(); | ||
| 239 | out: | ||
| 240 | return ret; | ||
| 241 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_bind.c b/drivers/staging/usbip/userspace/src/usbip_bind.c deleted file mode 100644 index fa46141ae68b..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_bind.c +++ /dev/null | |||
| @@ -1,214 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <libudev.h> | ||
| 20 | |||
| 21 | #include <errno.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | |||
| 26 | #include <getopt.h> | ||
| 27 | |||
| 28 | #include "usbip_common.h" | ||
| 29 | #include "utils.h" | ||
| 30 | #include "usbip.h" | ||
| 31 | #include "sysfs_utils.h" | ||
| 32 | |||
| 33 | enum unbind_status { | ||
| 34 | UNBIND_ST_OK, | ||
| 35 | UNBIND_ST_USBIP_HOST, | ||
| 36 | UNBIND_ST_FAILED | ||
| 37 | }; | ||
| 38 | |||
| 39 | static const char usbip_bind_usage_string[] = | ||
| 40 | "usbip bind <args>\n" | ||
| 41 | " -b, --busid=<busid> Bind " USBIP_HOST_DRV_NAME ".ko to device " | ||
| 42 | "on <busid>\n"; | ||
| 43 | |||
| 44 | void usbip_bind_usage(void) | ||
| 45 | { | ||
| 46 | printf("usage: %s", usbip_bind_usage_string); | ||
| 47 | } | ||
| 48 | |||
| 49 | /* call at unbound state */ | ||
| 50 | static int bind_usbip(char *busid) | ||
| 51 | { | ||
| 52 | char attr_name[] = "bind"; | ||
| 53 | char bind_attr_path[SYSFS_PATH_MAX]; | ||
| 54 | int rc = -1; | ||
| 55 | |||
| 56 | snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s", | ||
| 57 | SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE, | ||
| 58 | SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name); | ||
| 59 | |||
| 60 | rc = write_sysfs_attribute(bind_attr_path, busid, strlen(busid)); | ||
| 61 | if (rc < 0) { | ||
| 62 | err("error binding device %s to driver: %s", busid, | ||
| 63 | strerror(errno)); | ||
| 64 | return -1; | ||
| 65 | } | ||
| 66 | |||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* buggy driver may cause dead lock */ | ||
| 71 | static int unbind_other(char *busid) | ||
| 72 | { | ||
| 73 | enum unbind_status status = UNBIND_ST_OK; | ||
| 74 | |||
| 75 | char attr_name[] = "unbind"; | ||
| 76 | char unbind_attr_path[SYSFS_PATH_MAX]; | ||
| 77 | int rc = -1; | ||
| 78 | |||
| 79 | struct udev *udev; | ||
| 80 | struct udev_device *dev; | ||
| 81 | const char *driver; | ||
| 82 | const char *bDevClass; | ||
| 83 | |||
| 84 | /* Create libudev context. */ | ||
| 85 | udev = udev_new(); | ||
| 86 | |||
| 87 | /* Get the device. */ | ||
| 88 | dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid); | ||
| 89 | if (!dev) { | ||
| 90 | dbg("unable to find device with bus ID %s", busid); | ||
| 91 | goto err_close_busid_dev; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Check what kind of device it is. */ | ||
| 95 | bDevClass = udev_device_get_sysattr_value(dev, "bDeviceClass"); | ||
| 96 | if (!bDevClass) { | ||
| 97 | dbg("unable to get bDevClass device attribute"); | ||
| 98 | goto err_close_busid_dev; | ||
| 99 | } | ||
| 100 | |||
| 101 | if (!strncmp(bDevClass, "09", strlen(bDevClass))) { | ||
| 102 | dbg("skip unbinding of hub"); | ||
| 103 | goto err_close_busid_dev; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Get the device driver. */ | ||
| 107 | driver = udev_device_get_driver(dev); | ||
| 108 | if (!driver) { | ||
| 109 | /* No driver bound to this device. */ | ||
| 110 | goto out; | ||
| 111 | } | ||
| 112 | |||
| 113 | if (!strncmp(USBIP_HOST_DRV_NAME, driver, | ||
| 114 | strlen(USBIP_HOST_DRV_NAME))) { | ||
| 115 | /* Already bound to usbip-host. */ | ||
| 116 | status = UNBIND_ST_USBIP_HOST; | ||
| 117 | goto out; | ||
| 118 | } | ||
| 119 | |||
| 120 | /* Unbind device from driver. */ | ||
| 121 | snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s", | ||
| 122 | SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE, | ||
| 123 | SYSFS_DRIVERS_NAME, driver, attr_name); | ||
| 124 | |||
| 125 | rc = write_sysfs_attribute(unbind_attr_path, busid, strlen(busid)); | ||
| 126 | if (rc < 0) { | ||
| 127 | err("error unbinding device %s from driver", busid); | ||
| 128 | goto err_close_busid_dev; | ||
| 129 | } | ||
| 130 | |||
| 131 | goto out; | ||
| 132 | |||
| 133 | err_close_busid_dev: | ||
| 134 | status = UNBIND_ST_FAILED; | ||
| 135 | out: | ||
| 136 | udev_device_unref(dev); | ||
| 137 | udev_unref(udev); | ||
| 138 | |||
| 139 | return status; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int bind_device(char *busid) | ||
| 143 | { | ||
| 144 | int rc; | ||
| 145 | struct udev *udev; | ||
| 146 | struct udev_device *dev; | ||
| 147 | |||
| 148 | /* Check whether the device with this bus ID exists. */ | ||
| 149 | udev = udev_new(); | ||
| 150 | dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid); | ||
| 151 | if (!dev) { | ||
| 152 | err("device with the specified bus ID does not exist"); | ||
| 153 | return -1; | ||
| 154 | } | ||
| 155 | udev_unref(udev); | ||
| 156 | |||
| 157 | rc = unbind_other(busid); | ||
| 158 | if (rc == UNBIND_ST_FAILED) { | ||
| 159 | err("could not unbind driver from device on busid %s", busid); | ||
| 160 | return -1; | ||
| 161 | } else if (rc == UNBIND_ST_USBIP_HOST) { | ||
| 162 | err("device on busid %s is already bound to %s", busid, | ||
| 163 | USBIP_HOST_DRV_NAME); | ||
| 164 | return -1; | ||
| 165 | } | ||
| 166 | |||
| 167 | rc = modify_match_busid(busid, 1); | ||
| 168 | if (rc < 0) { | ||
| 169 | err("unable to bind device on %s", busid); | ||
| 170 | return -1; | ||
| 171 | } | ||
| 172 | |||
| 173 | rc = bind_usbip(busid); | ||
| 174 | if (rc < 0) { | ||
| 175 | err("could not bind device to %s", USBIP_HOST_DRV_NAME); | ||
| 176 | modify_match_busid(busid, 0); | ||
| 177 | return -1; | ||
| 178 | } | ||
| 179 | |||
| 180 | info("bind device on busid %s: complete", busid); | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | int usbip_bind(int argc, char *argv[]) | ||
| 186 | { | ||
| 187 | static const struct option opts[] = { | ||
| 188 | { "busid", required_argument, NULL, 'b' }, | ||
| 189 | { NULL, 0, NULL, 0 } | ||
| 190 | }; | ||
| 191 | |||
| 192 | int opt; | ||
| 193 | int ret = -1; | ||
| 194 | |||
| 195 | for (;;) { | ||
| 196 | opt = getopt_long(argc, argv, "b:", opts, NULL); | ||
| 197 | |||
| 198 | if (opt == -1) | ||
| 199 | break; | ||
| 200 | |||
| 201 | switch (opt) { | ||
| 202 | case 'b': | ||
| 203 | ret = bind_device(optarg); | ||
| 204 | goto out; | ||
| 205 | default: | ||
| 206 | goto err_out; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | err_out: | ||
| 211 | usbip_bind_usage(); | ||
| 212 | out: | ||
| 213 | return ret; | ||
| 214 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c deleted file mode 100644 index 05c6d15856eb..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_detach.c +++ /dev/null | |||
| @@ -1,110 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <ctype.h> | ||
| 20 | #include <limits.h> | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | |||
| 26 | #include <getopt.h> | ||
| 27 | #include <unistd.h> | ||
| 28 | |||
| 29 | #include "vhci_driver.h" | ||
| 30 | #include "usbip_common.h" | ||
| 31 | #include "usbip_network.h" | ||
| 32 | #include "usbip.h" | ||
| 33 | |||
| 34 | static const char usbip_detach_usage_string[] = | ||
| 35 | "usbip detach <args>\n" | ||
| 36 | " -p, --port=<port> " USBIP_VHCI_DRV_NAME | ||
| 37 | " port the device is on\n"; | ||
| 38 | |||
| 39 | void usbip_detach_usage(void) | ||
| 40 | { | ||
| 41 | printf("usage: %s", usbip_detach_usage_string); | ||
| 42 | } | ||
| 43 | |||
| 44 | static int detach_port(char *port) | ||
| 45 | { | ||
| 46 | int ret; | ||
| 47 | uint8_t portnum; | ||
| 48 | char path[PATH_MAX+1]; | ||
| 49 | |||
| 50 | for (unsigned int i = 0; i < strlen(port); i++) | ||
| 51 | if (!isdigit(port[i])) { | ||
| 52 | err("invalid port %s", port); | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* check max port */ | ||
| 57 | |||
| 58 | portnum = atoi(port); | ||
| 59 | |||
| 60 | /* remove the port state file */ | ||
| 61 | |||
| 62 | snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", portnum); | ||
| 63 | |||
| 64 | remove(path); | ||
| 65 | rmdir(VHCI_STATE_PATH); | ||
| 66 | |||
| 67 | ret = usbip_vhci_driver_open(); | ||
| 68 | if (ret < 0) { | ||
| 69 | err("open vhci_driver"); | ||
| 70 | return -1; | ||
| 71 | } | ||
| 72 | |||
| 73 | ret = usbip_vhci_detach_device(portnum); | ||
| 74 | if (ret < 0) | ||
| 75 | return -1; | ||
| 76 | |||
| 77 | usbip_vhci_driver_close(); | ||
| 78 | |||
| 79 | return ret; | ||
| 80 | } | ||
| 81 | |||
| 82 | int usbip_detach(int argc, char *argv[]) | ||
| 83 | { | ||
| 84 | static const struct option opts[] = { | ||
| 85 | { "port", required_argument, NULL, 'p' }, | ||
| 86 | { NULL, 0, NULL, 0 } | ||
| 87 | }; | ||
| 88 | int opt; | ||
| 89 | int ret = -1; | ||
| 90 | |||
| 91 | for (;;) { | ||
| 92 | opt = getopt_long(argc, argv, "p:", opts, NULL); | ||
| 93 | |||
| 94 | if (opt == -1) | ||
| 95 | break; | ||
| 96 | |||
| 97 | switch (opt) { | ||
| 98 | case 'p': | ||
| 99 | ret = detach_port(optarg); | ||
| 100 | goto out; | ||
| 101 | default: | ||
| 102 | goto err_out; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | err_out: | ||
| 107 | usbip_detach_usage(); | ||
| 108 | out: | ||
| 109 | return ret; | ||
| 110 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_list.c b/drivers/staging/usbip/userspace/src/usbip_list.c deleted file mode 100644 index d5ce34a410e7..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_list.c +++ /dev/null | |||
| @@ -1,283 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/types.h> | ||
| 20 | #include <libudev.h> | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | #include <stdbool.h> | ||
| 24 | #include <stdint.h> | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <stdlib.h> | ||
| 27 | #include <string.h> | ||
| 28 | |||
| 29 | #include <getopt.h> | ||
| 30 | #include <netdb.h> | ||
| 31 | #include <unistd.h> | ||
| 32 | |||
| 33 | #include "usbip_common.h" | ||
| 34 | #include "usbip_network.h" | ||
| 35 | #include "usbip.h" | ||
| 36 | |||
| 37 | static const char usbip_list_usage_string[] = | ||
| 38 | "usbip list [-p|--parsable] <args>\n" | ||
| 39 | " -p, --parsable Parsable list format\n" | ||
| 40 | " -r, --remote=<host> List the exportable USB devices on <host>\n" | ||
| 41 | " -l, --local List the local USB devices\n"; | ||
| 42 | |||
| 43 | void usbip_list_usage(void) | ||
| 44 | { | ||
| 45 | printf("usage: %s", usbip_list_usage_string); | ||
| 46 | } | ||
| 47 | |||
| 48 | static int get_exported_devices(char *host, int sockfd) | ||
| 49 | { | ||
| 50 | char product_name[100]; | ||
| 51 | char class_name[100]; | ||
| 52 | struct op_devlist_reply reply; | ||
| 53 | uint16_t code = OP_REP_DEVLIST; | ||
| 54 | struct usbip_usb_device udev; | ||
| 55 | struct usbip_usb_interface uintf; | ||
| 56 | unsigned int i; | ||
| 57 | int rc, j; | ||
| 58 | |||
| 59 | rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0); | ||
| 60 | if (rc < 0) { | ||
| 61 | dbg("usbip_net_send_op_common failed"); | ||
| 62 | return -1; | ||
| 63 | } | ||
| 64 | |||
| 65 | rc = usbip_net_recv_op_common(sockfd, &code); | ||
| 66 | if (rc < 0) { | ||
| 67 | dbg("usbip_net_recv_op_common failed"); | ||
| 68 | return -1; | ||
| 69 | } | ||
| 70 | |||
| 71 | memset(&reply, 0, sizeof(reply)); | ||
| 72 | rc = usbip_net_recv(sockfd, &reply, sizeof(reply)); | ||
| 73 | if (rc < 0) { | ||
| 74 | dbg("usbip_net_recv_op_devlist failed"); | ||
| 75 | return -1; | ||
| 76 | } | ||
| 77 | PACK_OP_DEVLIST_REPLY(0, &reply); | ||
| 78 | dbg("exportable devices: %d\n", reply.ndev); | ||
| 79 | |||
| 80 | if (reply.ndev == 0) { | ||
| 81 | info("no exportable devices found on %s", host); | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | printf("Exportable USB devices\n"); | ||
| 86 | printf("======================\n"); | ||
| 87 | printf(" - %s\n", host); | ||
| 88 | |||
| 89 | for (i = 0; i < reply.ndev; i++) { | ||
| 90 | memset(&udev, 0, sizeof(udev)); | ||
| 91 | rc = usbip_net_recv(sockfd, &udev, sizeof(udev)); | ||
| 92 | if (rc < 0) { | ||
| 93 | dbg("usbip_net_recv failed: usbip_usb_device[%d]", i); | ||
| 94 | return -1; | ||
| 95 | } | ||
| 96 | usbip_net_pack_usb_device(0, &udev); | ||
| 97 | |||
| 98 | usbip_names_get_product(product_name, sizeof(product_name), | ||
| 99 | udev.idVendor, udev.idProduct); | ||
| 100 | usbip_names_get_class(class_name, sizeof(class_name), | ||
| 101 | udev.bDeviceClass, udev.bDeviceSubClass, | ||
| 102 | udev.bDeviceProtocol); | ||
| 103 | printf("%11s: %s\n", udev.busid, product_name); | ||
| 104 | printf("%11s: %s\n", "", udev.path); | ||
| 105 | printf("%11s: %s\n", "", class_name); | ||
| 106 | |||
| 107 | for (j = 0; j < udev.bNumInterfaces; j++) { | ||
| 108 | rc = usbip_net_recv(sockfd, &uintf, sizeof(uintf)); | ||
| 109 | if (rc < 0) { | ||
| 110 | err("usbip_net_recv failed: usbip_usb_intf[%d]", | ||
| 111 | j); | ||
| 112 | |||
| 113 | return -1; | ||
| 114 | } | ||
| 115 | usbip_net_pack_usb_interface(0, &uintf); | ||
| 116 | |||
| 117 | usbip_names_get_class(class_name, sizeof(class_name), | ||
| 118 | uintf.bInterfaceClass, | ||
| 119 | uintf.bInterfaceSubClass, | ||
| 120 | uintf.bInterfaceProtocol); | ||
| 121 | printf("%11s: %2d - %s\n", "", j, class_name); | ||
| 122 | } | ||
| 123 | |||
| 124 | printf("\n"); | ||
| 125 | } | ||
| 126 | |||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | static int list_exported_devices(char *host) | ||
| 131 | { | ||
| 132 | int rc; | ||
| 133 | int sockfd; | ||
| 134 | |||
| 135 | sockfd = usbip_net_tcp_connect(host, usbip_port_string); | ||
| 136 | if (sockfd < 0) { | ||
| 137 | err("could not connect to %s:%s: %s", host, | ||
| 138 | usbip_port_string, gai_strerror(sockfd)); | ||
| 139 | return -1; | ||
| 140 | } | ||
| 141 | dbg("connected to %s:%s", host, usbip_port_string); | ||
| 142 | |||
| 143 | rc = get_exported_devices(host, sockfd); | ||
| 144 | if (rc < 0) { | ||
| 145 | err("failed to get device list from %s", host); | ||
| 146 | return -1; | ||
| 147 | } | ||
| 148 | |||
| 149 | close(sockfd); | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | static void print_device(const char *busid, const char *vendor, | ||
| 155 | const char *product, bool parsable) | ||
| 156 | { | ||
| 157 | if (parsable) | ||
| 158 | printf("busid=%s#usbid=%.4s:%.4s#", busid, vendor, product); | ||
| 159 | else | ||
| 160 | printf(" - busid %s (%.4s:%.4s)\n", busid, vendor, product); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void print_product_name(char *product_name, bool parsable) | ||
| 164 | { | ||
| 165 | if (!parsable) | ||
| 166 | printf(" %s\n", product_name); | ||
| 167 | } | ||
| 168 | |||
| 169 | static int list_devices(bool parsable) | ||
| 170 | { | ||
| 171 | struct udev *udev; | ||
| 172 | struct udev_enumerate *enumerate; | ||
| 173 | struct udev_list_entry *devices, *dev_list_entry; | ||
| 174 | struct udev_device *dev; | ||
| 175 | const char *path; | ||
| 176 | const char *idVendor; | ||
| 177 | const char *idProduct; | ||
| 178 | const char *bConfValue; | ||
| 179 | const char *bNumIntfs; | ||
| 180 | const char *busid; | ||
| 181 | char product_name[128]; | ||
| 182 | int ret = -1; | ||
| 183 | |||
| 184 | /* Create libudev context. */ | ||
| 185 | udev = udev_new(); | ||
| 186 | |||
| 187 | /* Create libudev device enumeration. */ | ||
| 188 | enumerate = udev_enumerate_new(udev); | ||
| 189 | |||
| 190 | /* Take only USB devices that are not hubs and do not have | ||
| 191 | * the bInterfaceNumber attribute, i.e. are not interfaces. | ||
| 192 | */ | ||
| 193 | udev_enumerate_add_match_subsystem(enumerate, "usb"); | ||
| 194 | udev_enumerate_add_nomatch_sysattr(enumerate, "bDeviceClass", "09"); | ||
| 195 | udev_enumerate_add_nomatch_sysattr(enumerate, "bInterfaceNumber", NULL); | ||
| 196 | udev_enumerate_scan_devices(enumerate); | ||
| 197 | |||
| 198 | devices = udev_enumerate_get_list_entry(enumerate); | ||
| 199 | |||
| 200 | /* Show information about each device. */ | ||
| 201 | udev_list_entry_foreach(dev_list_entry, devices) { | ||
| 202 | path = udev_list_entry_get_name(dev_list_entry); | ||
| 203 | dev = udev_device_new_from_syspath(udev, path); | ||
| 204 | |||
| 205 | /* Get device information. */ | ||
| 206 | idVendor = udev_device_get_sysattr_value(dev, "idVendor"); | ||
| 207 | idProduct = udev_device_get_sysattr_value(dev, "idProduct"); | ||
| 208 | bConfValue = udev_device_get_sysattr_value(dev, "bConfigurationValue"); | ||
| 209 | bNumIntfs = udev_device_get_sysattr_value(dev, "bNumInterfaces"); | ||
| 210 | busid = udev_device_get_sysname(dev); | ||
| 211 | if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) { | ||
| 212 | err("problem getting device attributes: %s", | ||
| 213 | strerror(errno)); | ||
| 214 | goto err_out; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* Get product name. */ | ||
| 218 | usbip_names_get_product(product_name, sizeof(product_name), | ||
| 219 | strtol(idVendor, NULL, 16), | ||
| 220 | strtol(idProduct, NULL, 16)); | ||
| 221 | |||
| 222 | /* Print information. */ | ||
| 223 | print_device(busid, idVendor, idProduct, parsable); | ||
| 224 | print_product_name(product_name, parsable); | ||
| 225 | |||
| 226 | printf("\n"); | ||
| 227 | |||
| 228 | udev_device_unref(dev); | ||
| 229 | } | ||
| 230 | |||
| 231 | ret = 0; | ||
| 232 | |||
| 233 | err_out: | ||
| 234 | udev_enumerate_unref(enumerate); | ||
| 235 | udev_unref(udev); | ||
| 236 | |||
| 237 | return ret; | ||
| 238 | } | ||
| 239 | |||
| 240 | int usbip_list(int argc, char *argv[]) | ||
| 241 | { | ||
| 242 | static const struct option opts[] = { | ||
| 243 | { "parsable", no_argument, NULL, 'p' }, | ||
| 244 | { "remote", required_argument, NULL, 'r' }, | ||
| 245 | { "local", no_argument, NULL, 'l' }, | ||
| 246 | { NULL, 0, NULL, 0 } | ||
| 247 | }; | ||
| 248 | |||
| 249 | bool parsable = false; | ||
| 250 | int opt; | ||
| 251 | int ret = -1; | ||
| 252 | |||
| 253 | if (usbip_names_init(USBIDS_FILE)) | ||
| 254 | err("failed to open %s", USBIDS_FILE); | ||
| 255 | |||
| 256 | for (;;) { | ||
| 257 | opt = getopt_long(argc, argv, "pr:l", opts, NULL); | ||
| 258 | |||
| 259 | if (opt == -1) | ||
| 260 | break; | ||
| 261 | |||
| 262 | switch (opt) { | ||
| 263 | case 'p': | ||
| 264 | parsable = true; | ||
| 265 | break; | ||
| 266 | case 'r': | ||
| 267 | ret = list_exported_devices(optarg); | ||
| 268 | goto out; | ||
| 269 | case 'l': | ||
| 270 | ret = list_devices(parsable); | ||
| 271 | goto out; | ||
| 272 | default: | ||
| 273 | goto err_out; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | err_out: | ||
| 278 | usbip_list_usage(); | ||
| 279 | out: | ||
| 280 | usbip_names_free(); | ||
| 281 | |||
| 282 | return ret; | ||
| 283 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_network.c b/drivers/staging/usbip/userspace/src/usbip_network.c deleted file mode 100644 index b4c37e76a6e0..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_network.c +++ /dev/null | |||
| @@ -1,303 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <sys/socket.h> | ||
| 20 | |||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include <arpa/inet.h> | ||
| 24 | #include <netdb.h> | ||
| 25 | #include <netinet/tcp.h> | ||
| 26 | #include <unistd.h> | ||
| 27 | |||
| 28 | #ifdef HAVE_LIBWRAP | ||
| 29 | #include <tcpd.h> | ||
| 30 | #endif | ||
| 31 | |||
| 32 | #include "usbip_common.h" | ||
| 33 | #include "usbip_network.h" | ||
| 34 | |||
| 35 | int usbip_port = 3240; | ||
| 36 | char *usbip_port_string = "3240"; | ||
| 37 | |||
| 38 | void usbip_setup_port_number(char *arg) | ||
| 39 | { | ||
| 40 | dbg("parsing port arg '%s'", arg); | ||
| 41 | char *end; | ||
| 42 | unsigned long int port = strtoul(arg, &end, 10); | ||
| 43 | |||
| 44 | if (end == arg) { | ||
| 45 | err("port: could not parse '%s' as a decimal integer", arg); | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | |||
| 49 | if (*end != '\0') { | ||
| 50 | err("port: garbage at end of '%s'", arg); | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | |||
| 54 | if (port > UINT16_MAX) { | ||
| 55 | err("port: %s too high (max=%d)", | ||
| 56 | arg, UINT16_MAX); | ||
| 57 | return; | ||
| 58 | } | ||
| 59 | |||
| 60 | usbip_port = port; | ||
| 61 | usbip_port_string = arg; | ||
| 62 | info("using port %d (\"%s\")", usbip_port, usbip_port_string); | ||
| 63 | } | ||
| 64 | |||
| 65 | void usbip_net_pack_uint32_t(int pack, uint32_t *num) | ||
| 66 | { | ||
| 67 | uint32_t i; | ||
| 68 | |||
| 69 | if (pack) | ||
| 70 | i = htonl(*num); | ||
| 71 | else | ||
| 72 | i = ntohl(*num); | ||
| 73 | |||
| 74 | *num = i; | ||
| 75 | } | ||
| 76 | |||
| 77 | void usbip_net_pack_uint16_t(int pack, uint16_t *num) | ||
| 78 | { | ||
| 79 | uint16_t i; | ||
| 80 | |||
| 81 | if (pack) | ||
| 82 | i = htons(*num); | ||
| 83 | else | ||
| 84 | i = ntohs(*num); | ||
| 85 | |||
| 86 | *num = i; | ||
| 87 | } | ||
| 88 | |||
| 89 | void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev) | ||
| 90 | { | ||
| 91 | usbip_net_pack_uint32_t(pack, &udev->busnum); | ||
| 92 | usbip_net_pack_uint32_t(pack, &udev->devnum); | ||
| 93 | usbip_net_pack_uint32_t(pack, &udev->speed); | ||
| 94 | |||
| 95 | usbip_net_pack_uint16_t(pack, &udev->idVendor); | ||
| 96 | usbip_net_pack_uint16_t(pack, &udev->idProduct); | ||
| 97 | usbip_net_pack_uint16_t(pack, &udev->bcdDevice); | ||
| 98 | } | ||
| 99 | |||
| 100 | void usbip_net_pack_usb_interface(int pack __attribute__((unused)), | ||
| 101 | struct usbip_usb_interface *udev | ||
| 102 | __attribute__((unused))) | ||
| 103 | { | ||
| 104 | /* uint8_t members need nothing */ | ||
| 105 | } | ||
| 106 | |||
| 107 | static ssize_t usbip_net_xmit(int sockfd, void *buff, size_t bufflen, | ||
| 108 | int sending) | ||
| 109 | { | ||
| 110 | ssize_t nbytes; | ||
| 111 | ssize_t total = 0; | ||
| 112 | |||
| 113 | if (!bufflen) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | do { | ||
| 117 | if (sending) | ||
| 118 | nbytes = send(sockfd, buff, bufflen, 0); | ||
| 119 | else | ||
| 120 | nbytes = recv(sockfd, buff, bufflen, MSG_WAITALL); | ||
| 121 | |||
| 122 | if (nbytes <= 0) | ||
| 123 | return -1; | ||
| 124 | |||
| 125 | buff = (void *)((intptr_t) buff + nbytes); | ||
| 126 | bufflen -= nbytes; | ||
| 127 | total += nbytes; | ||
| 128 | |||
| 129 | } while (bufflen > 0); | ||
| 130 | |||
| 131 | return total; | ||
| 132 | } | ||
| 133 | |||
| 134 | ssize_t usbip_net_recv(int sockfd, void *buff, size_t bufflen) | ||
| 135 | { | ||
| 136 | return usbip_net_xmit(sockfd, buff, bufflen, 0); | ||
| 137 | } | ||
| 138 | |||
| 139 | ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen) | ||
| 140 | { | ||
| 141 | return usbip_net_xmit(sockfd, buff, bufflen, 1); | ||
| 142 | } | ||
| 143 | |||
| 144 | int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status) | ||
| 145 | { | ||
| 146 | struct op_common op_common; | ||
| 147 | int rc; | ||
| 148 | |||
| 149 | memset(&op_common, 0, sizeof(op_common)); | ||
| 150 | |||
| 151 | op_common.version = USBIP_VERSION; | ||
| 152 | op_common.code = code; | ||
| 153 | op_common.status = status; | ||
| 154 | |||
| 155 | PACK_OP_COMMON(1, &op_common); | ||
| 156 | |||
| 157 | rc = usbip_net_send(sockfd, &op_common, sizeof(op_common)); | ||
| 158 | if (rc < 0) { | ||
| 159 | dbg("usbip_net_send failed: %d", rc); | ||
| 160 | return -1; | ||
| 161 | } | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | int usbip_net_recv_op_common(int sockfd, uint16_t *code) | ||
| 167 | { | ||
| 168 | struct op_common op_common; | ||
| 169 | int rc; | ||
| 170 | |||
| 171 | memset(&op_common, 0, sizeof(op_common)); | ||
| 172 | |||
| 173 | rc = usbip_net_recv(sockfd, &op_common, sizeof(op_common)); | ||
| 174 | if (rc < 0) { | ||
| 175 | dbg("usbip_net_recv failed: %d", rc); | ||
| 176 | goto err; | ||
| 177 | } | ||
| 178 | |||
| 179 | PACK_OP_COMMON(0, &op_common); | ||
| 180 | |||
| 181 | if (op_common.version != USBIP_VERSION) { | ||
| 182 | dbg("version mismatch: %d %d", op_common.version, | ||
| 183 | USBIP_VERSION); | ||
| 184 | goto err; | ||
| 185 | } | ||
| 186 | |||
| 187 | switch (*code) { | ||
| 188 | case OP_UNSPEC: | ||
| 189 | break; | ||
| 190 | default: | ||
| 191 | if (op_common.code != *code) { | ||
| 192 | dbg("unexpected pdu %#0x for %#0x", op_common.code, | ||
| 193 | *code); | ||
| 194 | goto err; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | if (op_common.status != ST_OK) { | ||
| 199 | dbg("request failed at peer: %d", op_common.status); | ||
| 200 | goto err; | ||
| 201 | } | ||
| 202 | |||
| 203 | *code = op_common.code; | ||
| 204 | |||
| 205 | return 0; | ||
| 206 | err: | ||
| 207 | return -1; | ||
| 208 | } | ||
| 209 | |||
| 210 | int usbip_net_set_reuseaddr(int sockfd) | ||
| 211 | { | ||
| 212 | const int val = 1; | ||
| 213 | int ret; | ||
| 214 | |||
| 215 | ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); | ||
| 216 | if (ret < 0) | ||
| 217 | dbg("setsockopt: SO_REUSEADDR"); | ||
| 218 | |||
| 219 | return ret; | ||
| 220 | } | ||
| 221 | |||
| 222 | int usbip_net_set_nodelay(int sockfd) | ||
| 223 | { | ||
| 224 | const int val = 1; | ||
| 225 | int ret; | ||
| 226 | |||
| 227 | ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); | ||
| 228 | if (ret < 0) | ||
| 229 | dbg("setsockopt: TCP_NODELAY"); | ||
| 230 | |||
| 231 | return ret; | ||
| 232 | } | ||
| 233 | |||
| 234 | int usbip_net_set_keepalive(int sockfd) | ||
| 235 | { | ||
| 236 | const int val = 1; | ||
| 237 | int ret; | ||
| 238 | |||
| 239 | ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); | ||
| 240 | if (ret < 0) | ||
| 241 | dbg("setsockopt: SO_KEEPALIVE"); | ||
| 242 | |||
| 243 | return ret; | ||
| 244 | } | ||
| 245 | |||
| 246 | int usbip_net_set_v6only(int sockfd) | ||
| 247 | { | ||
| 248 | const int val = 1; | ||
| 249 | int ret; | ||
| 250 | |||
| 251 | ret = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)); | ||
| 252 | if (ret < 0) | ||
| 253 | dbg("setsockopt: IPV6_V6ONLY"); | ||
| 254 | |||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | |||
| 258 | /* | ||
| 259 | * IPv6 Ready | ||
| 260 | */ | ||
| 261 | int usbip_net_tcp_connect(char *hostname, char *service) | ||
| 262 | { | ||
| 263 | struct addrinfo hints, *res, *rp; | ||
| 264 | int sockfd; | ||
| 265 | int ret; | ||
| 266 | |||
| 267 | memset(&hints, 0, sizeof(hints)); | ||
| 268 | hints.ai_family = AF_UNSPEC; | ||
| 269 | hints.ai_socktype = SOCK_STREAM; | ||
| 270 | |||
| 271 | /* get all possible addresses */ | ||
| 272 | ret = getaddrinfo(hostname, service, &hints, &res); | ||
| 273 | if (ret < 0) { | ||
| 274 | dbg("getaddrinfo: %s service %s: %s", hostname, service, | ||
| 275 | gai_strerror(ret)); | ||
| 276 | return ret; | ||
| 277 | } | ||
| 278 | |||
| 279 | /* try the addresses */ | ||
| 280 | for (rp = res; rp; rp = rp->ai_next) { | ||
| 281 | sockfd = socket(rp->ai_family, rp->ai_socktype, | ||
| 282 | rp->ai_protocol); | ||
| 283 | if (sockfd < 0) | ||
| 284 | continue; | ||
| 285 | |||
| 286 | /* should set TCP_NODELAY for usbip */ | ||
| 287 | usbip_net_set_nodelay(sockfd); | ||
| 288 | /* TODO: write code for heartbeat */ | ||
| 289 | usbip_net_set_keepalive(sockfd); | ||
| 290 | |||
| 291 | if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0) | ||
| 292 | break; | ||
| 293 | |||
| 294 | close(sockfd); | ||
| 295 | } | ||
| 296 | |||
| 297 | freeaddrinfo(res); | ||
| 298 | |||
| 299 | if (!rp) | ||
| 300 | return EAI_SYSTEM; | ||
| 301 | |||
| 302 | return sockfd; | ||
| 303 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/drivers/staging/usbip/userspace/src/usbip_network.h deleted file mode 100644 index c1e875cf1078..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_network.h +++ /dev/null | |||
| @@ -1,185 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2007 Takahiro Hirofuchi | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef __USBIP_NETWORK_H | ||
| 6 | #define __USBIP_NETWORK_H | ||
| 7 | |||
| 8 | #ifdef HAVE_CONFIG_H | ||
| 9 | #include "../config.h" | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include <sys/types.h> | ||
| 13 | |||
| 14 | #include <stdint.h> | ||
| 15 | |||
| 16 | extern int usbip_port; | ||
| 17 | extern char *usbip_port_string; | ||
| 18 | void usbip_setup_port_number(char *arg); | ||
| 19 | |||
| 20 | /* ---------------------------------------------------------------------- */ | ||
| 21 | /* Common header for all the kinds of PDUs. */ | ||
| 22 | struct op_common { | ||
| 23 | uint16_t version; | ||
| 24 | |||
| 25 | #define OP_REQUEST (0x80 << 8) | ||
| 26 | #define OP_REPLY (0x00 << 8) | ||
| 27 | uint16_t code; | ||
| 28 | |||
| 29 | /* add more error code */ | ||
| 30 | #define ST_OK 0x00 | ||
| 31 | #define ST_NA 0x01 | ||
| 32 | uint32_t status; /* op_code status (for reply) */ | ||
| 33 | |||
| 34 | } __attribute__((packed)); | ||
| 35 | |||
| 36 | #define PACK_OP_COMMON(pack, op_common) do {\ | ||
| 37 | usbip_net_pack_uint16_t(pack, &(op_common)->version);\ | ||
| 38 | usbip_net_pack_uint16_t(pack, &(op_common)->code);\ | ||
| 39 | usbip_net_pack_uint32_t(pack, &(op_common)->status);\ | ||
| 40 | } while (0) | ||
| 41 | |||
| 42 | /* ---------------------------------------------------------------------- */ | ||
| 43 | /* Dummy Code */ | ||
| 44 | #define OP_UNSPEC 0x00 | ||
| 45 | #define OP_REQ_UNSPEC OP_UNSPEC | ||
| 46 | #define OP_REP_UNSPEC OP_UNSPEC | ||
| 47 | |||
| 48 | /* ---------------------------------------------------------------------- */ | ||
| 49 | /* Retrieve USB device information. (still not used) */ | ||
| 50 | #define OP_DEVINFO 0x02 | ||
| 51 | #define OP_REQ_DEVINFO (OP_REQUEST | OP_DEVINFO) | ||
| 52 | #define OP_REP_DEVINFO (OP_REPLY | OP_DEVINFO) | ||
| 53 | |||
| 54 | struct op_devinfo_request { | ||
| 55 | char busid[SYSFS_BUS_ID_SIZE]; | ||
| 56 | } __attribute__((packed)); | ||
| 57 | |||
| 58 | struct op_devinfo_reply { | ||
| 59 | struct usbip_usb_device udev; | ||
| 60 | struct usbip_usb_interface uinf[]; | ||
| 61 | } __attribute__((packed)); | ||
| 62 | |||
| 63 | /* ---------------------------------------------------------------------- */ | ||
| 64 | /* Import a remote USB device. */ | ||
| 65 | #define OP_IMPORT 0x03 | ||
| 66 | #define OP_REQ_IMPORT (OP_REQUEST | OP_IMPORT) | ||
| 67 | #define OP_REP_IMPORT (OP_REPLY | OP_IMPORT) | ||
| 68 | |||
| 69 | struct op_import_request { | ||
| 70 | char busid[SYSFS_BUS_ID_SIZE]; | ||
| 71 | } __attribute__((packed)); | ||
| 72 | |||
| 73 | struct op_import_reply { | ||
| 74 | struct usbip_usb_device udev; | ||
| 75 | // struct usbip_usb_interface uinf[]; | ||
| 76 | } __attribute__((packed)); | ||
| 77 | |||
| 78 | #define PACK_OP_IMPORT_REQUEST(pack, request) do {\ | ||
| 79 | } while (0) | ||
| 80 | |||
| 81 | #define PACK_OP_IMPORT_REPLY(pack, reply) do {\ | ||
| 82 | usbip_net_pack_usb_device(pack, &(reply)->udev);\ | ||
| 83 | } while (0) | ||
| 84 | |||
| 85 | /* ---------------------------------------------------------------------- */ | ||
| 86 | /* Export a USB device to a remote host. */ | ||
| 87 | #define OP_EXPORT 0x06 | ||
| 88 | #define OP_REQ_EXPORT (OP_REQUEST | OP_EXPORT) | ||
| 89 | #define OP_REP_EXPORT (OP_REPLY | OP_EXPORT) | ||
| 90 | |||
| 91 | struct op_export_request { | ||
| 92 | struct usbip_usb_device udev; | ||
| 93 | } __attribute__((packed)); | ||
| 94 | |||
| 95 | struct op_export_reply { | ||
| 96 | int returncode; | ||
| 97 | } __attribute__((packed)); | ||
| 98 | |||
| 99 | |||
| 100 | #define PACK_OP_EXPORT_REQUEST(pack, request) do {\ | ||
| 101 | usbip_net_pack_usb_device(pack, &(request)->udev);\ | ||
| 102 | } while (0) | ||
| 103 | |||
| 104 | #define PACK_OP_EXPORT_REPLY(pack, reply) do {\ | ||
| 105 | } while (0) | ||
| 106 | |||
| 107 | /* ---------------------------------------------------------------------- */ | ||
| 108 | /* un-Export a USB device from a remote host. */ | ||
| 109 | #define OP_UNEXPORT 0x07 | ||
| 110 | #define OP_REQ_UNEXPORT (OP_REQUEST | OP_UNEXPORT) | ||
| 111 | #define OP_REP_UNEXPORT (OP_REPLY | OP_UNEXPORT) | ||
| 112 | |||
| 113 | struct op_unexport_request { | ||
| 114 | struct usbip_usb_device udev; | ||
| 115 | } __attribute__((packed)); | ||
| 116 | |||
| 117 | struct op_unexport_reply { | ||
| 118 | int returncode; | ||
| 119 | } __attribute__((packed)); | ||
| 120 | |||
| 121 | #define PACK_OP_UNEXPORT_REQUEST(pack, request) do {\ | ||
| 122 | usbip_net_pack_usb_device(pack, &(request)->udev);\ | ||
| 123 | } while (0) | ||
| 124 | |||
| 125 | #define PACK_OP_UNEXPORT_REPLY(pack, reply) do {\ | ||
| 126 | } while (0) | ||
| 127 | |||
| 128 | /* ---------------------------------------------------------------------- */ | ||
| 129 | /* Negotiate IPSec encryption key. (still not used) */ | ||
| 130 | #define OP_CRYPKEY 0x04 | ||
| 131 | #define OP_REQ_CRYPKEY (OP_REQUEST | OP_CRYPKEY) | ||
| 132 | #define OP_REP_CRYPKEY (OP_REPLY | OP_CRYPKEY) | ||
| 133 | |||
| 134 | struct op_crypkey_request { | ||
| 135 | /* 128bit key */ | ||
| 136 | uint32_t key[4]; | ||
| 137 | } __attribute__((packed)); | ||
| 138 | |||
| 139 | struct op_crypkey_reply { | ||
| 140 | uint32_t __reserved; | ||
| 141 | } __attribute__((packed)); | ||
| 142 | |||
| 143 | |||
| 144 | /* ---------------------------------------------------------------------- */ | ||
| 145 | /* Retrieve the list of exported USB devices. */ | ||
| 146 | #define OP_DEVLIST 0x05 | ||
| 147 | #define OP_REQ_DEVLIST (OP_REQUEST | OP_DEVLIST) | ||
| 148 | #define OP_REP_DEVLIST (OP_REPLY | OP_DEVLIST) | ||
| 149 | |||
| 150 | struct op_devlist_request { | ||
| 151 | } __attribute__((packed)); | ||
| 152 | |||
| 153 | struct op_devlist_reply { | ||
| 154 | uint32_t ndev; | ||
| 155 | /* followed by reply_extra[] */ | ||
| 156 | } __attribute__((packed)); | ||
| 157 | |||
| 158 | struct op_devlist_reply_extra { | ||
| 159 | struct usbip_usb_device udev; | ||
| 160 | struct usbip_usb_interface uinf[]; | ||
| 161 | } __attribute__((packed)); | ||
| 162 | |||
| 163 | #define PACK_OP_DEVLIST_REQUEST(pack, request) do {\ | ||
| 164 | } while (0) | ||
| 165 | |||
| 166 | #define PACK_OP_DEVLIST_REPLY(pack, reply) do {\ | ||
| 167 | usbip_net_pack_uint32_t(pack, &(reply)->ndev);\ | ||
| 168 | } while (0) | ||
| 169 | |||
| 170 | void usbip_net_pack_uint32_t(int pack, uint32_t *num); | ||
| 171 | void usbip_net_pack_uint16_t(int pack, uint16_t *num); | ||
| 172 | void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev); | ||
| 173 | void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf); | ||
| 174 | |||
| 175 | ssize_t usbip_net_recv(int sockfd, void *buff, size_t bufflen); | ||
| 176 | ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen); | ||
| 177 | int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status); | ||
| 178 | int usbip_net_recv_op_common(int sockfd, uint16_t *code); | ||
| 179 | int usbip_net_set_reuseaddr(int sockfd); | ||
| 180 | int usbip_net_set_nodelay(int sockfd); | ||
| 181 | int usbip_net_set_keepalive(int sockfd); | ||
| 182 | int usbip_net_set_v6only(int sockfd); | ||
| 183 | int usbip_net_tcp_connect(char *hostname, char *port); | ||
| 184 | |||
| 185 | #endif /* __USBIP_NETWORK_H */ | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_port.c b/drivers/staging/usbip/userspace/src/usbip_port.c deleted file mode 100644 index a2e884fd9226..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_port.c +++ /dev/null | |||
| @@ -1,57 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include "vhci_driver.h" | ||
| 17 | #include "usbip_common.h" | ||
| 18 | |||
| 19 | static int list_imported_devices(void) | ||
| 20 | { | ||
| 21 | int i; | ||
| 22 | struct usbip_imported_device *idev; | ||
| 23 | int ret; | ||
| 24 | |||
| 25 | ret = usbip_vhci_driver_open(); | ||
| 26 | if (ret < 0) { | ||
| 27 | err("open vhci_driver"); | ||
| 28 | return -1; | ||
| 29 | } | ||
| 30 | |||
| 31 | printf("Imported USB devices\n"); | ||
| 32 | printf("====================\n"); | ||
| 33 | |||
| 34 | for (i = 0; i < vhci_driver->nports; i++) { | ||
| 35 | idev = &vhci_driver->idev[i]; | ||
| 36 | |||
| 37 | if (usbip_vhci_imported_device_dump(idev) < 0) | ||
| 38 | ret = -1; | ||
| 39 | } | ||
| 40 | |||
| 41 | usbip_vhci_driver_close(); | ||
| 42 | |||
| 43 | return ret; | ||
| 44 | |||
| 45 | } | ||
| 46 | |||
| 47 | int usbip_port_show(__attribute__((unused)) int argc, | ||
| 48 | __attribute__((unused)) char *argv[]) | ||
| 49 | { | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | ret = list_imported_devices(); | ||
| 53 | if (ret < 0) | ||
| 54 | err("list imported devices"); | ||
| 55 | |||
| 56 | return ret; | ||
| 57 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbip_unbind.c b/drivers/staging/usbip/userspace/src/usbip_unbind.c deleted file mode 100644 index a4a496c9cbaf..000000000000 --- a/drivers/staging/usbip/userspace/src/usbip_unbind.c +++ /dev/null | |||
| @@ -1,141 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <libudev.h> | ||
| 20 | |||
| 21 | #include <errno.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | #include <getopt.h> | ||
| 26 | |||
| 27 | #include "usbip_common.h" | ||
| 28 | #include "utils.h" | ||
| 29 | #include "usbip.h" | ||
| 30 | #include "sysfs_utils.h" | ||
| 31 | |||
| 32 | static const char usbip_unbind_usage_string[] = | ||
| 33 | "usbip unbind <args>\n" | ||
| 34 | " -b, --busid=<busid> Unbind " USBIP_HOST_DRV_NAME ".ko from " | ||
| 35 | "device on <busid>\n"; | ||
| 36 | |||
| 37 | void usbip_unbind_usage(void) | ||
| 38 | { | ||
| 39 | printf("usage: %s", usbip_unbind_usage_string); | ||
| 40 | } | ||
| 41 | |||
| 42 | static int unbind_device(char *busid) | ||
| 43 | { | ||
| 44 | char bus_type[] = "usb"; | ||
| 45 | int rc, ret = -1; | ||
| 46 | |||
| 47 | char unbind_attr_name[] = "unbind"; | ||
| 48 | char unbind_attr_path[SYSFS_PATH_MAX]; | ||
| 49 | char rebind_attr_name[] = "rebind"; | ||
| 50 | char rebind_attr_path[SYSFS_PATH_MAX]; | ||
| 51 | |||
| 52 | struct udev *udev; | ||
| 53 | struct udev_device *dev; | ||
| 54 | const char *driver; | ||
| 55 | |||
| 56 | /* Create libudev context. */ | ||
| 57 | udev = udev_new(); | ||
| 58 | |||
| 59 | /* Check whether the device with this bus ID exists. */ | ||
| 60 | dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid); | ||
| 61 | if (!dev) { | ||
| 62 | err("device with the specified bus ID does not exist"); | ||
| 63 | goto err_close_udev; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Check whether the device is using usbip-host driver. */ | ||
| 67 | driver = udev_device_get_driver(dev); | ||
| 68 | if (!driver || strcmp(driver, "usbip-host")) { | ||
| 69 | err("device is not bound to usbip-host driver"); | ||
| 70 | goto err_close_udev; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* Unbind device from driver. */ | ||
| 74 | snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s", | ||
| 75 | SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME, | ||
| 76 | USBIP_HOST_DRV_NAME, unbind_attr_name); | ||
| 77 | |||
| 78 | rc = write_sysfs_attribute(unbind_attr_path, busid, strlen(busid)); | ||
| 79 | if (rc < 0) { | ||
| 80 | err("error unbinding device %s from driver", busid); | ||
| 81 | goto err_close_udev; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* Notify driver of unbind. */ | ||
| 85 | rc = modify_match_busid(busid, 0); | ||
| 86 | if (rc < 0) { | ||
| 87 | err("unable to unbind device on %s", busid); | ||
| 88 | goto err_close_udev; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* Trigger new probing. */ | ||
| 92 | snprintf(rebind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s", | ||
| 93 | SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME, | ||
| 94 | USBIP_HOST_DRV_NAME, rebind_attr_name); | ||
| 95 | |||
| 96 | rc = write_sysfs_attribute(rebind_attr_path, busid, strlen(busid)); | ||
| 97 | if (rc < 0) { | ||
| 98 | err("error rebinding"); | ||
| 99 | goto err_close_udev; | ||
| 100 | } | ||
| 101 | |||
| 102 | ret = 0; | ||
| 103 | info("unbind device on busid %s: complete", busid); | ||
| 104 | |||
| 105 | err_close_udev: | ||
| 106 | udev_device_unref(dev); | ||
| 107 | udev_unref(udev); | ||
| 108 | |||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | int usbip_unbind(int argc, char *argv[]) | ||
| 113 | { | ||
| 114 | static const struct option opts[] = { | ||
| 115 | { "busid", required_argument, NULL, 'b' }, | ||
| 116 | { NULL, 0, NULL, 0 } | ||
| 117 | }; | ||
| 118 | |||
| 119 | int opt; | ||
| 120 | int ret = -1; | ||
| 121 | |||
| 122 | for (;;) { | ||
| 123 | opt = getopt_long(argc, argv, "b:", opts, NULL); | ||
| 124 | |||
| 125 | if (opt == -1) | ||
| 126 | break; | ||
| 127 | |||
| 128 | switch (opt) { | ||
| 129 | case 'b': | ||
| 130 | ret = unbind_device(optarg); | ||
| 131 | goto out; | ||
| 132 | default: | ||
| 133 | goto err_out; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | err_out: | ||
| 138 | usbip_unbind_usage(); | ||
| 139 | out: | ||
| 140 | return ret; | ||
| 141 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c deleted file mode 100644 index 2f87f2d348ba..000000000000 --- a/drivers/staging/usbip/userspace/src/usbipd.c +++ /dev/null | |||
| @@ -1,679 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifdef HAVE_CONFIG_H | ||
| 20 | #include "../config.h" | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #define _GNU_SOURCE | ||
| 24 | #include <errno.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | #include <netdb.h> | ||
| 27 | #include <string.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | #include <sys/types.h> | ||
| 30 | #include <sys/stat.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | #include <sys/socket.h> | ||
| 33 | #include <netinet/in.h> | ||
| 34 | |||
| 35 | #ifdef HAVE_LIBWRAP | ||
| 36 | #include <tcpd.h> | ||
| 37 | #endif | ||
| 38 | |||
| 39 | #include <getopt.h> | ||
| 40 | #include <signal.h> | ||
| 41 | #include <poll.h> | ||
| 42 | |||
| 43 | #include "usbip_host_driver.h" | ||
| 44 | #include "usbip_common.h" | ||
| 45 | #include "usbip_network.h" | ||
| 46 | #include "list.h" | ||
| 47 | |||
| 48 | #undef PROGNAME | ||
| 49 | #define PROGNAME "usbipd" | ||
| 50 | #define MAXSOCKFD 20 | ||
| 51 | |||
| 52 | #define MAIN_LOOP_TIMEOUT 10 | ||
| 53 | |||
| 54 | #define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" | ||
| 55 | |||
| 56 | static const char usbip_version_string[] = PACKAGE_STRING; | ||
| 57 | |||
| 58 | static const char usbipd_help_string[] = | ||
| 59 | "usage: usbipd [options]\n" | ||
| 60 | "\n" | ||
| 61 | " -4, --ipv4\n" | ||
| 62 | " Bind to IPv4. Default is both.\n" | ||
| 63 | "\n" | ||
| 64 | " -6, --ipv6\n" | ||
| 65 | " Bind to IPv6. Default is both.\n" | ||
| 66 | "\n" | ||
| 67 | " -D, --daemon\n" | ||
| 68 | " Run as a daemon process.\n" | ||
| 69 | "\n" | ||
| 70 | " -d, --debug\n" | ||
| 71 | " Print debugging information.\n" | ||
| 72 | "\n" | ||
| 73 | " -PFILE, --pid FILE\n" | ||
| 74 | " Write process id to FILE.\n" | ||
| 75 | " If no FILE specified, use " DEFAULT_PID_FILE "\n" | ||
| 76 | "\n" | ||
| 77 | " -tPORT, --tcp-port PORT\n" | ||
| 78 | " Listen on TCP/IP port PORT.\n" | ||
| 79 | "\n" | ||
| 80 | " -h, --help\n" | ||
| 81 | " Print this help.\n" | ||
| 82 | "\n" | ||
| 83 | " -v, --version\n" | ||
| 84 | " Show version.\n"; | ||
| 85 | |||
| 86 | static void usbipd_help(void) | ||
| 87 | { | ||
| 88 | printf("%s\n", usbipd_help_string); | ||
| 89 | } | ||
| 90 | |||
| 91 | static int recv_request_import(int sockfd) | ||
| 92 | { | ||
| 93 | struct op_import_request req; | ||
| 94 | struct op_common reply; | ||
| 95 | struct usbip_exported_device *edev; | ||
| 96 | struct usbip_usb_device pdu_udev; | ||
| 97 | struct list_head *i; | ||
| 98 | int found = 0; | ||
| 99 | int error = 0; | ||
| 100 | int rc; | ||
| 101 | |||
| 102 | memset(&req, 0, sizeof(req)); | ||
| 103 | memset(&reply, 0, sizeof(reply)); | ||
| 104 | |||
| 105 | rc = usbip_net_recv(sockfd, &req, sizeof(req)); | ||
| 106 | if (rc < 0) { | ||
| 107 | dbg("usbip_net_recv failed: import request"); | ||
| 108 | return -1; | ||
| 109 | } | ||
| 110 | PACK_OP_IMPORT_REQUEST(0, &req); | ||
| 111 | |||
| 112 | list_for_each(i, &host_driver->edev_list) { | ||
| 113 | edev = list_entry(i, struct usbip_exported_device, node); | ||
| 114 | if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { | ||
| 115 | info("found requested device: %s", req.busid); | ||
| 116 | found = 1; | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | if (found) { | ||
| 122 | /* should set TCP_NODELAY for usbip */ | ||
| 123 | usbip_net_set_nodelay(sockfd); | ||
| 124 | |||
| 125 | /* export device needs a TCP/IP socket descriptor */ | ||
| 126 | rc = usbip_host_export_device(edev, sockfd); | ||
| 127 | if (rc < 0) | ||
| 128 | error = 1; | ||
| 129 | } else { | ||
| 130 | info("requested device not found: %s", req.busid); | ||
| 131 | error = 1; | ||
| 132 | } | ||
| 133 | |||
| 134 | rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, | ||
| 135 | (!error ? ST_OK : ST_NA)); | ||
| 136 | if (rc < 0) { | ||
| 137 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT); | ||
| 138 | return -1; | ||
| 139 | } | ||
| 140 | |||
| 141 | if (error) { | ||
| 142 | dbg("import request busid %s: failed", req.busid); | ||
| 143 | return -1; | ||
| 144 | } | ||
| 145 | |||
| 146 | memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); | ||
| 147 | usbip_net_pack_usb_device(1, &pdu_udev); | ||
| 148 | |||
| 149 | rc = usbip_net_send(sockfd, &pdu_udev, sizeof(pdu_udev)); | ||
| 150 | if (rc < 0) { | ||
| 151 | dbg("usbip_net_send failed: devinfo"); | ||
| 152 | return -1; | ||
| 153 | } | ||
| 154 | |||
| 155 | dbg("import request busid %s: complete", req.busid); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | static int send_reply_devlist(int connfd) | ||
| 161 | { | ||
| 162 | struct usbip_exported_device *edev; | ||
| 163 | struct usbip_usb_device pdu_udev; | ||
| 164 | struct usbip_usb_interface pdu_uinf; | ||
| 165 | struct op_devlist_reply reply; | ||
| 166 | struct list_head *j; | ||
| 167 | int rc, i; | ||
| 168 | |||
| 169 | reply.ndev = 0; | ||
| 170 | /* number of exported devices */ | ||
| 171 | list_for_each(j, &host_driver->edev_list) { | ||
| 172 | reply.ndev += 1; | ||
| 173 | } | ||
| 174 | info("exportable devices: %d", reply.ndev); | ||
| 175 | |||
| 176 | rc = usbip_net_send_op_common(connfd, OP_REP_DEVLIST, ST_OK); | ||
| 177 | if (rc < 0) { | ||
| 178 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST); | ||
| 179 | return -1; | ||
| 180 | } | ||
| 181 | PACK_OP_DEVLIST_REPLY(1, &reply); | ||
| 182 | |||
| 183 | rc = usbip_net_send(connfd, &reply, sizeof(reply)); | ||
| 184 | if (rc < 0) { | ||
| 185 | dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST); | ||
| 186 | return -1; | ||
| 187 | } | ||
| 188 | |||
| 189 | list_for_each(j, &host_driver->edev_list) { | ||
| 190 | edev = list_entry(j, struct usbip_exported_device, node); | ||
| 191 | dump_usb_device(&edev->udev); | ||
| 192 | memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); | ||
| 193 | usbip_net_pack_usb_device(1, &pdu_udev); | ||
| 194 | |||
| 195 | rc = usbip_net_send(connfd, &pdu_udev, sizeof(pdu_udev)); | ||
| 196 | if (rc < 0) { | ||
| 197 | dbg("usbip_net_send failed: pdu_udev"); | ||
| 198 | return -1; | ||
| 199 | } | ||
| 200 | |||
| 201 | for (i = 0; i < edev->udev.bNumInterfaces; i++) { | ||
| 202 | dump_usb_interface(&edev->uinf[i]); | ||
| 203 | memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf)); | ||
| 204 | usbip_net_pack_usb_interface(1, &pdu_uinf); | ||
| 205 | |||
| 206 | rc = usbip_net_send(connfd, &pdu_uinf, | ||
| 207 | sizeof(pdu_uinf)); | ||
| 208 | if (rc < 0) { | ||
| 209 | err("usbip_net_send failed: pdu_uinf"); | ||
| 210 | return -1; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static int recv_request_devlist(int connfd) | ||
| 219 | { | ||
| 220 | struct op_devlist_request req; | ||
| 221 | int rc; | ||
| 222 | |||
| 223 | memset(&req, 0, sizeof(req)); | ||
| 224 | |||
| 225 | rc = usbip_net_recv(connfd, &req, sizeof(req)); | ||
| 226 | if (rc < 0) { | ||
| 227 | dbg("usbip_net_recv failed: devlist request"); | ||
| 228 | return -1; | ||
| 229 | } | ||
| 230 | |||
| 231 | rc = send_reply_devlist(connfd); | ||
| 232 | if (rc < 0) { | ||
| 233 | dbg("send_reply_devlist failed"); | ||
| 234 | return -1; | ||
| 235 | } | ||
| 236 | |||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | static int recv_pdu(int connfd) | ||
| 241 | { | ||
| 242 | uint16_t code = OP_UNSPEC; | ||
| 243 | int ret; | ||
| 244 | |||
| 245 | ret = usbip_net_recv_op_common(connfd, &code); | ||
| 246 | if (ret < 0) { | ||
| 247 | dbg("could not receive opcode: %#0x", code); | ||
| 248 | return -1; | ||
| 249 | } | ||
| 250 | |||
| 251 | ret = usbip_host_refresh_device_list(); | ||
| 252 | if (ret < 0) { | ||
| 253 | dbg("could not refresh device list: %d", ret); | ||
| 254 | return -1; | ||
| 255 | } | ||
| 256 | |||
| 257 | info("received request: %#0x(%d)", code, connfd); | ||
| 258 | switch (code) { | ||
| 259 | case OP_REQ_DEVLIST: | ||
| 260 | ret = recv_request_devlist(connfd); | ||
| 261 | break; | ||
| 262 | case OP_REQ_IMPORT: | ||
| 263 | ret = recv_request_import(connfd); | ||
| 264 | break; | ||
| 265 | case OP_REQ_DEVINFO: | ||
| 266 | case OP_REQ_CRYPKEY: | ||
| 267 | default: | ||
| 268 | err("received an unknown opcode: %#0x", code); | ||
| 269 | ret = -1; | ||
| 270 | } | ||
| 271 | |||
| 272 | if (ret == 0) | ||
| 273 | info("request %#0x(%d): complete", code, connfd); | ||
| 274 | else | ||
| 275 | info("request %#0x(%d): failed", code, connfd); | ||
| 276 | |||
| 277 | return ret; | ||
| 278 | } | ||
| 279 | |||
| 280 | #ifdef HAVE_LIBWRAP | ||
| 281 | static int tcpd_auth(int connfd) | ||
| 282 | { | ||
| 283 | struct request_info request; | ||
| 284 | int rc; | ||
| 285 | |||
| 286 | request_init(&request, RQ_DAEMON, PROGNAME, RQ_FILE, connfd, 0); | ||
| 287 | fromhost(&request); | ||
| 288 | rc = hosts_access(&request); | ||
| 289 | if (rc == 0) | ||
| 290 | return -1; | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | #endif | ||
| 295 | |||
| 296 | static int do_accept(int listenfd) | ||
| 297 | { | ||
| 298 | int connfd; | ||
| 299 | struct sockaddr_storage ss; | ||
| 300 | socklen_t len = sizeof(ss); | ||
| 301 | char host[NI_MAXHOST], port[NI_MAXSERV]; | ||
| 302 | int rc; | ||
| 303 | |||
| 304 | memset(&ss, 0, sizeof(ss)); | ||
| 305 | |||
| 306 | connfd = accept(listenfd, (struct sockaddr *)&ss, &len); | ||
| 307 | if (connfd < 0) { | ||
| 308 | err("failed to accept connection"); | ||
| 309 | return -1; | ||
| 310 | } | ||
| 311 | |||
| 312 | rc = getnameinfo((struct sockaddr *)&ss, len, host, sizeof(host), | ||
| 313 | port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); | ||
| 314 | if (rc) | ||
| 315 | err("getnameinfo: %s", gai_strerror(rc)); | ||
| 316 | |||
| 317 | #ifdef HAVE_LIBWRAP | ||
| 318 | rc = tcpd_auth(connfd); | ||
| 319 | if (rc < 0) { | ||
| 320 | info("denied access from %s", host); | ||
| 321 | close(connfd); | ||
| 322 | return -1; | ||
| 323 | } | ||
| 324 | #endif | ||
| 325 | info("connection from %s:%s", host, port); | ||
| 326 | |||
| 327 | return connfd; | ||
| 328 | } | ||
| 329 | |||
| 330 | int process_request(int listenfd) | ||
| 331 | { | ||
| 332 | pid_t childpid; | ||
| 333 | int connfd; | ||
| 334 | |||
| 335 | connfd = do_accept(listenfd); | ||
| 336 | if (connfd < 0) | ||
| 337 | return -1; | ||
| 338 | childpid = fork(); | ||
| 339 | if (childpid == 0) { | ||
| 340 | close(listenfd); | ||
| 341 | recv_pdu(connfd); | ||
| 342 | exit(0); | ||
| 343 | } | ||
| 344 | close(connfd); | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 348 | static void addrinfo_to_text(struct addrinfo *ai, char buf[], | ||
| 349 | const size_t buf_size) | ||
| 350 | { | ||
| 351 | char hbuf[NI_MAXHOST]; | ||
| 352 | char sbuf[NI_MAXSERV]; | ||
| 353 | int rc; | ||
| 354 | |||
| 355 | buf[0] = '\0'; | ||
| 356 | |||
| 357 | rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), | ||
| 358 | sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); | ||
| 359 | if (rc) | ||
| 360 | err("getnameinfo: %s", gai_strerror(rc)); | ||
| 361 | |||
| 362 | snprintf(buf, buf_size, "%s:%s", hbuf, sbuf); | ||
| 363 | } | ||
| 364 | |||
| 365 | static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[], | ||
| 366 | int maxsockfd) | ||
| 367 | { | ||
| 368 | struct addrinfo *ai; | ||
| 369 | int ret, nsockfd = 0; | ||
| 370 | const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2; | ||
| 371 | char ai_buf[ai_buf_size]; | ||
| 372 | |||
| 373 | for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) { | ||
| 374 | int sock; | ||
| 375 | |||
| 376 | addrinfo_to_text(ai, ai_buf, ai_buf_size); | ||
| 377 | dbg("opening %s", ai_buf); | ||
| 378 | sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||
| 379 | if (sock < 0) { | ||
| 380 | err("socket: %s: %d (%s)", | ||
| 381 | ai_buf, errno, strerror(errno)); | ||
| 382 | continue; | ||
| 383 | } | ||
| 384 | |||
| 385 | usbip_net_set_reuseaddr(sock); | ||
| 386 | usbip_net_set_nodelay(sock); | ||
| 387 | /* We use seperate sockets for IPv4 and IPv6 | ||
| 388 | * (see do_standalone_mode()) */ | ||
| 389 | usbip_net_set_v6only(sock); | ||
| 390 | |||
| 391 | if (sock >= FD_SETSIZE) { | ||
| 392 | err("FD_SETSIZE: %s: sock=%d, max=%d", | ||
| 393 | ai_buf, sock, FD_SETSIZE); | ||
| 394 | close(sock); | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | |||
| 398 | ret = bind(sock, ai->ai_addr, ai->ai_addrlen); | ||
| 399 | if (ret < 0) { | ||
| 400 | err("bind: %s: %d (%s)", | ||
| 401 | ai_buf, errno, strerror(errno)); | ||
| 402 | close(sock); | ||
| 403 | continue; | ||
| 404 | } | ||
| 405 | |||
| 406 | ret = listen(sock, SOMAXCONN); | ||
| 407 | if (ret < 0) { | ||
| 408 | err("listen: %s: %d (%s)", | ||
| 409 | ai_buf, errno, strerror(errno)); | ||
| 410 | close(sock); | ||
| 411 | continue; | ||
| 412 | } | ||
| 413 | |||
| 414 | info("listening on %s", ai_buf); | ||
| 415 | sockfdlist[nsockfd++] = sock; | ||
| 416 | } | ||
| 417 | |||
| 418 | return nsockfd; | ||
| 419 | } | ||
| 420 | |||
| 421 | static struct addrinfo *do_getaddrinfo(char *host, int ai_family) | ||
| 422 | { | ||
| 423 | struct addrinfo hints, *ai_head; | ||
| 424 | int rc; | ||
| 425 | |||
| 426 | memset(&hints, 0, sizeof(hints)); | ||
| 427 | hints.ai_family = ai_family; | ||
| 428 | hints.ai_socktype = SOCK_STREAM; | ||
| 429 | hints.ai_flags = AI_PASSIVE; | ||
| 430 | |||
| 431 | rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head); | ||
| 432 | if (rc) { | ||
| 433 | err("failed to get a network address %s: %s", usbip_port_string, | ||
| 434 | gai_strerror(rc)); | ||
| 435 | return NULL; | ||
| 436 | } | ||
| 437 | |||
| 438 | return ai_head; | ||
| 439 | } | ||
| 440 | |||
| 441 | static void signal_handler(int i) | ||
| 442 | { | ||
| 443 | dbg("received '%s' signal", strsignal(i)); | ||
| 444 | } | ||
| 445 | |||
| 446 | static void set_signal(void) | ||
| 447 | { | ||
| 448 | struct sigaction act; | ||
| 449 | |||
| 450 | memset(&act, 0, sizeof(act)); | ||
| 451 | act.sa_handler = signal_handler; | ||
| 452 | sigemptyset(&act.sa_mask); | ||
| 453 | sigaction(SIGTERM, &act, NULL); | ||
| 454 | sigaction(SIGINT, &act, NULL); | ||
| 455 | act.sa_handler = SIG_IGN; | ||
| 456 | sigaction(SIGCLD, &act, NULL); | ||
| 457 | } | ||
| 458 | |||
| 459 | static const char *pid_file; | ||
| 460 | |||
| 461 | static void write_pid_file(void) | ||
| 462 | { | ||
| 463 | if (pid_file) { | ||
| 464 | dbg("creating pid file %s", pid_file); | ||
| 465 | FILE *fp; | ||
| 466 | |||
| 467 | fp = fopen(pid_file, "w"); | ||
| 468 | if (!fp) { | ||
| 469 | err("pid_file: %s: %d (%s)", | ||
| 470 | pid_file, errno, strerror(errno)); | ||
| 471 | return; | ||
| 472 | } | ||
| 473 | fprintf(fp, "%d\n", getpid()); | ||
| 474 | fclose(fp); | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | static void remove_pid_file(void) | ||
| 479 | { | ||
| 480 | if (pid_file) { | ||
| 481 | dbg("removing pid file %s", pid_file); | ||
| 482 | unlink(pid_file); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | |||
| 486 | static int do_standalone_mode(int daemonize, int ipv4, int ipv6) | ||
| 487 | { | ||
| 488 | struct addrinfo *ai_head; | ||
| 489 | int sockfdlist[MAXSOCKFD]; | ||
| 490 | int nsockfd, family; | ||
| 491 | int i, terminate; | ||
| 492 | struct pollfd *fds; | ||
| 493 | struct timespec timeout; | ||
| 494 | sigset_t sigmask; | ||
| 495 | |||
| 496 | if (usbip_host_driver_open()) { | ||
| 497 | err("please load " USBIP_CORE_MOD_NAME ".ko and " | ||
| 498 | USBIP_HOST_DRV_NAME ".ko!"); | ||
| 499 | return -1; | ||
| 500 | } | ||
| 501 | |||
| 502 | if (daemonize) { | ||
| 503 | if (daemon(0, 0) < 0) { | ||
| 504 | err("daemonizing failed: %s", strerror(errno)); | ||
| 505 | usbip_host_driver_close(); | ||
| 506 | return -1; | ||
| 507 | } | ||
| 508 | umask(0); | ||
| 509 | usbip_use_syslog = 1; | ||
| 510 | } | ||
| 511 | set_signal(); | ||
| 512 | write_pid_file(); | ||
| 513 | |||
| 514 | info("starting " PROGNAME " (%s)", usbip_version_string); | ||
| 515 | |||
| 516 | /* | ||
| 517 | * To suppress warnings on systems with bindv6only disabled | ||
| 518 | * (default), we use seperate sockets for IPv6 and IPv4 and set | ||
| 519 | * IPV6_V6ONLY on the IPv6 sockets. | ||
| 520 | */ | ||
| 521 | if (ipv4 && ipv6) | ||
| 522 | family = AF_UNSPEC; | ||
| 523 | else if (ipv4) | ||
| 524 | family = AF_INET; | ||
| 525 | else | ||
| 526 | family = AF_INET6; | ||
| 527 | |||
| 528 | ai_head = do_getaddrinfo(NULL, family); | ||
| 529 | if (!ai_head) { | ||
| 530 | usbip_host_driver_close(); | ||
| 531 | return -1; | ||
| 532 | } | ||
| 533 | nsockfd = listen_all_addrinfo(ai_head, sockfdlist, | ||
| 534 | sizeof(sockfdlist) / sizeof(*sockfdlist)); | ||
| 535 | freeaddrinfo(ai_head); | ||
| 536 | if (nsockfd <= 0) { | ||
| 537 | err("failed to open a listening socket"); | ||
| 538 | usbip_host_driver_close(); | ||
| 539 | return -1; | ||
| 540 | } | ||
| 541 | |||
| 542 | dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es"); | ||
| 543 | |||
| 544 | fds = calloc(nsockfd, sizeof(struct pollfd)); | ||
| 545 | for (i = 0; i < nsockfd; i++) { | ||
| 546 | fds[i].fd = sockfdlist[i]; | ||
| 547 | fds[i].events = POLLIN; | ||
| 548 | } | ||
| 549 | timeout.tv_sec = MAIN_LOOP_TIMEOUT; | ||
| 550 | timeout.tv_nsec = 0; | ||
| 551 | |||
| 552 | sigfillset(&sigmask); | ||
| 553 | sigdelset(&sigmask, SIGTERM); | ||
| 554 | sigdelset(&sigmask, SIGINT); | ||
| 555 | |||
| 556 | terminate = 0; | ||
| 557 | while (!terminate) { | ||
| 558 | int r; | ||
| 559 | |||
| 560 | r = ppoll(fds, nsockfd, &timeout, &sigmask); | ||
| 561 | if (r < 0) { | ||
| 562 | dbg("%s", strerror(errno)); | ||
| 563 | terminate = 1; | ||
| 564 | } else if (r) { | ||
| 565 | for (i = 0; i < nsockfd; i++) { | ||
| 566 | if (fds[i].revents & POLLIN) { | ||
| 567 | dbg("read event on fd[%d]=%d", | ||
| 568 | i, sockfdlist[i]); | ||
| 569 | process_request(sockfdlist[i]); | ||
| 570 | } | ||
| 571 | } | ||
| 572 | } else { | ||
| 573 | dbg("heartbeat timeout on ppoll()"); | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | info("shutting down " PROGNAME); | ||
| 578 | free(fds); | ||
| 579 | usbip_host_driver_close(); | ||
| 580 | |||
| 581 | return 0; | ||
| 582 | } | ||
| 583 | |||
| 584 | int main(int argc, char *argv[]) | ||
| 585 | { | ||
| 586 | static const struct option longopts[] = { | ||
| 587 | { "ipv4", no_argument, NULL, '4' }, | ||
| 588 | { "ipv6", no_argument, NULL, '6' }, | ||
| 589 | { "daemon", no_argument, NULL, 'D' }, | ||
| 590 | { "daemon", no_argument, NULL, 'D' }, | ||
| 591 | { "debug", no_argument, NULL, 'd' }, | ||
| 592 | { "pid", optional_argument, NULL, 'P' }, | ||
| 593 | { "tcp-port", required_argument, NULL, 't' }, | ||
| 594 | { "help", no_argument, NULL, 'h' }, | ||
| 595 | { "version", no_argument, NULL, 'v' }, | ||
| 596 | { NULL, 0, NULL, 0 } | ||
| 597 | }; | ||
| 598 | |||
| 599 | enum { | ||
| 600 | cmd_standalone_mode = 1, | ||
| 601 | cmd_help, | ||
| 602 | cmd_version | ||
| 603 | } cmd; | ||
| 604 | |||
| 605 | int daemonize = 0; | ||
| 606 | int ipv4 = 0, ipv6 = 0; | ||
| 607 | int opt, rc = -1; | ||
| 608 | |||
| 609 | pid_file = NULL; | ||
| 610 | |||
| 611 | usbip_use_stderr = 1; | ||
| 612 | usbip_use_syslog = 0; | ||
| 613 | |||
| 614 | if (geteuid() != 0) | ||
| 615 | err("not running as root?"); | ||
| 616 | |||
| 617 | cmd = cmd_standalone_mode; | ||
| 618 | for (;;) { | ||
| 619 | opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL); | ||
| 620 | |||
| 621 | if (opt == -1) | ||
| 622 | break; | ||
| 623 | |||
| 624 | switch (opt) { | ||
| 625 | case '4': | ||
| 626 | ipv4 = 1; | ||
| 627 | break; | ||
| 628 | case '6': | ||
| 629 | ipv6 = 1; | ||
| 630 | break; | ||
| 631 | case 'D': | ||
| 632 | daemonize = 1; | ||
| 633 | break; | ||
| 634 | case 'd': | ||
| 635 | usbip_use_debug = 1; | ||
| 636 | break; | ||
| 637 | case 'h': | ||
| 638 | cmd = cmd_help; | ||
| 639 | break; | ||
| 640 | case 'P': | ||
| 641 | pid_file = optarg ? optarg : DEFAULT_PID_FILE; | ||
| 642 | break; | ||
| 643 | case 't': | ||
| 644 | usbip_setup_port_number(optarg); | ||
| 645 | break; | ||
| 646 | case 'v': | ||
| 647 | cmd = cmd_version; | ||
| 648 | break; | ||
| 649 | case '?': | ||
| 650 | usbipd_help(); | ||
| 651 | default: | ||
| 652 | goto err_out; | ||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 656 | if (!ipv4 && !ipv6) | ||
| 657 | ipv4 = ipv6 = 1; | ||
| 658 | |||
| 659 | switch (cmd) { | ||
| 660 | case cmd_standalone_mode: | ||
| 661 | rc = do_standalone_mode(daemonize, ipv4, ipv6); | ||
| 662 | remove_pid_file(); | ||
| 663 | break; | ||
| 664 | case cmd_version: | ||
| 665 | printf(PROGNAME " (%s)\n", usbip_version_string); | ||
| 666 | rc = 0; | ||
| 667 | break; | ||
| 668 | case cmd_help: | ||
| 669 | usbipd_help(); | ||
| 670 | rc = 0; | ||
| 671 | break; | ||
| 672 | default: | ||
| 673 | usbipd_help(); | ||
| 674 | goto err_out; | ||
| 675 | } | ||
| 676 | |||
| 677 | err_out: | ||
| 678 | return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); | ||
| 679 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/utils.c b/drivers/staging/usbip/userspace/src/utils.c deleted file mode 100644 index 2b3d6d235015..000000000000 --- a/drivers/staging/usbip/userspace/src/utils.c +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <errno.h> | ||
| 20 | #include <stdio.h> | ||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include "usbip_common.h" | ||
| 24 | #include "utils.h" | ||
| 25 | #include "sysfs_utils.h" | ||
| 26 | |||
| 27 | int modify_match_busid(char *busid, int add) | ||
| 28 | { | ||
| 29 | char attr_name[] = "match_busid"; | ||
| 30 | char command[SYSFS_BUS_ID_SIZE + 4]; | ||
| 31 | char match_busid_attr_path[SYSFS_PATH_MAX]; | ||
| 32 | int rc; | ||
| 33 | |||
| 34 | snprintf(match_busid_attr_path, sizeof(match_busid_attr_path), | ||
| 35 | "%s/%s/%s/%s/%s/%s", SYSFS_MNT_PATH, SYSFS_BUS_NAME, | ||
| 36 | SYSFS_BUS_TYPE, SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, | ||
| 37 | attr_name); | ||
| 38 | |||
| 39 | if (add) | ||
| 40 | snprintf(command, SYSFS_BUS_ID_SIZE + 4, "add %s", busid); | ||
| 41 | else | ||
| 42 | snprintf(command, SYSFS_BUS_ID_SIZE + 4, "del %s", busid); | ||
| 43 | |||
| 44 | rc = write_sysfs_attribute(match_busid_attr_path, command, | ||
| 45 | sizeof(command)); | ||
| 46 | if (rc < 0) { | ||
| 47 | dbg("failed to write match_busid: %s", strerror(errno)); | ||
| 48 | return -1; | ||
| 49 | } | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | } | ||
diff --git a/drivers/staging/usbip/userspace/src/utils.h b/drivers/staging/usbip/userspace/src/utils.h deleted file mode 100644 index 5916fd3e02a6..000000000000 --- a/drivers/staging/usbip/userspace/src/utils.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> | ||
| 3 | * 2005-2007 Takahiro Hirofuchi | ||
| 4 | * | ||
| 5 | * This program is free software: you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation, either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __UTILS_H | ||
| 20 | #define __UTILS_H | ||
| 21 | |||
| 22 | int modify_match_busid(char *busid, int add); | ||
| 23 | |||
| 24 | #endif /* __UTILS_H */ | ||
| 25 | |||
diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index 8fcf8a7b6c22..9562cd026dc0 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c | |||
| @@ -150,7 +150,26 @@ int tb_path_activate(struct tb_path *path) | |||
| 150 | 150 | ||
| 151 | /* Activate hops. */ | 151 | /* Activate hops. */ |
| 152 | for (i = path->path_length - 1; i >= 0; i--) { | 152 | for (i = path->path_length - 1; i >= 0; i--) { |
| 153 | struct tb_regs_hop hop; | 153 | struct tb_regs_hop hop = { 0 }; |
| 154 | |||
| 155 | /* | ||
| 156 | * We do (currently) not tear down paths setup by the firmeware. | ||
| 157 | * If a firmware device is unplugged and plugged in again then | ||
| 158 | * it can happen that we reuse some of the hops from the (now | ||
| 159 | * defunct) firmeware path. This causes the hotplug operation to | ||
| 160 | * fail (the pci device does not show up). Clearing the hop | ||
| 161 | * before overwriting it fixes the problem. | ||
| 162 | * | ||
| 163 | * Should be removed once we discover and tear down firmeware | ||
| 164 | * paths. | ||
| 165 | */ | ||
| 166 | res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS, | ||
| 167 | 2 * path->hops[i].in_hop_index, 2); | ||
| 168 | if (res) { | ||
| 169 | __tb_path_deactivate_hops(path, i); | ||
| 170 | __tb_path_deallocate_nfc(path, 0); | ||
| 171 | goto err; | ||
| 172 | } | ||
| 154 | 173 | ||
| 155 | /* dword 0 */ | 174 | /* dword 0 */ |
| 156 | hop.next_hop = path->hops[i].next_hop_index; | 175 | hop.next_hop = path->hops[i].next_hop_index; |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 4db7987ec225..57d9df84ce5d 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
| @@ -540,6 +540,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { | |||
| 540 | { "INT3434", 0 }, | 540 | { "INT3434", 0 }, |
| 541 | { "INT3435", 0 }, | 541 | { "INT3435", 0 }, |
| 542 | { "80860F0A", 0 }, | 542 | { "80860F0A", 0 }, |
| 543 | { "8086228A", 0 }, | ||
| 543 | { }, | 544 | { }, |
| 544 | }; | 545 | }; |
| 545 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 546 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 7b63677475c1..d7d4584549a5 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
| @@ -527,6 +527,45 @@ static void atmel_enable_ms(struct uart_port *port) | |||
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | /* | 529 | /* |
| 530 | * Disable modem status interrupts | ||
| 531 | */ | ||
| 532 | static void atmel_disable_ms(struct uart_port *port) | ||
| 533 | { | ||
| 534 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
| 535 | uint32_t idr = 0; | ||
| 536 | |||
| 537 | /* | ||
| 538 | * Interrupt should not be disabled twice | ||
| 539 | */ | ||
| 540 | if (!atmel_port->ms_irq_enabled) | ||
| 541 | return; | ||
| 542 | |||
| 543 | atmel_port->ms_irq_enabled = false; | ||
| 544 | |||
| 545 | if (atmel_port->gpio_irq[UART_GPIO_CTS] >= 0) | ||
| 546 | disable_irq(atmel_port->gpio_irq[UART_GPIO_CTS]); | ||
| 547 | else | ||
| 548 | idr |= ATMEL_US_CTSIC; | ||
| 549 | |||
| 550 | if (atmel_port->gpio_irq[UART_GPIO_DSR] >= 0) | ||
| 551 | disable_irq(atmel_port->gpio_irq[UART_GPIO_DSR]); | ||
| 552 | else | ||
| 553 | idr |= ATMEL_US_DSRIC; | ||
| 554 | |||
| 555 | if (atmel_port->gpio_irq[UART_GPIO_RI] >= 0) | ||
| 556 | disable_irq(atmel_port->gpio_irq[UART_GPIO_RI]); | ||
| 557 | else | ||
| 558 | idr |= ATMEL_US_RIIC; | ||
| 559 | |||
| 560 | if (atmel_port->gpio_irq[UART_GPIO_DCD] >= 0) | ||
| 561 | disable_irq(atmel_port->gpio_irq[UART_GPIO_DCD]); | ||
| 562 | else | ||
| 563 | idr |= ATMEL_US_DCDIC; | ||
| 564 | |||
| 565 | UART_PUT_IDR(port, idr); | ||
| 566 | } | ||
| 567 | |||
| 568 | /* | ||
| 530 | * Control the transmission of a break signal | 569 | * Control the transmission of a break signal |
| 531 | */ | 570 | */ |
| 532 | static void atmel_break_ctl(struct uart_port *port, int break_state) | 571 | static void atmel_break_ctl(struct uart_port *port, int break_state) |
| @@ -1993,7 +2032,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1993 | 2032 | ||
| 1994 | /* CTS flow-control and modem-status interrupts */ | 2033 | /* CTS flow-control and modem-status interrupts */ |
| 1995 | if (UART_ENABLE_MS(port, termios->c_cflag)) | 2034 | if (UART_ENABLE_MS(port, termios->c_cflag)) |
| 1996 | port->ops->enable_ms(port); | 2035 | atmel_enable_ms(port); |
| 2036 | else | ||
| 2037 | atmel_disable_ms(port); | ||
| 1997 | 2038 | ||
| 1998 | spin_unlock_irqrestore(&port->lock, flags); | 2039 | spin_unlock_irqrestore(&port->lock, flags); |
| 1999 | } | 2040 | } |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 01951d27cc03..806e4bcadbd7 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
| @@ -581,7 +581,7 @@ static unsigned int cdns_uart_tx_empty(struct uart_port *port) | |||
| 581 | { | 581 | { |
| 582 | unsigned int status; | 582 | unsigned int status; |
| 583 | 583 | ||
| 584 | status = cdns_uart_readl(CDNS_UART_ISR_OFFSET) & CDNS_UART_IXR_TXEMPTY; | 584 | status = cdns_uart_readl(CDNS_UART_SR_OFFSET) & CDNS_UART_SR_TXEMPTY; |
| 585 | return status ? TIOCSER_TEMT : 0; | 585 | return status ? TIOCSER_TEMT : 0; |
| 586 | } | 586 | } |
| 587 | 587 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index e0cad4418085..cf1b19bca306 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -92,6 +92,8 @@ source "drivers/usb/storage/Kconfig" | |||
| 92 | 92 | ||
| 93 | source "drivers/usb/image/Kconfig" | 93 | source "drivers/usb/image/Kconfig" |
| 94 | 94 | ||
| 95 | source "drivers/usb/usbip/Kconfig" | ||
| 96 | |||
| 95 | endif | 97 | endif |
| 96 | 98 | ||
| 97 | source "drivers/usb/musb/Kconfig" | 99 | source "drivers/usb/musb/Kconfig" |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 3cba892b83a2..d7be71778059 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
| @@ -60,3 +60,5 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ | |||
| 60 | obj-$(CONFIG_USB_GADGET) += gadget/ | 60 | obj-$(CONFIG_USB_GADGET) += gadget/ |
| 61 | 61 | ||
| 62 | obj-$(CONFIG_USB_COMMON) += common/ | 62 | obj-$(CONFIG_USB_COMMON) += common/ |
| 63 | |||
| 64 | obj-$(CONFIG_USBIP_CORE) += usbip/ | ||
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index d72b9d2de2c5..4935ac38fd00 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c | |||
| @@ -20,13 +20,13 @@ | |||
| 20 | static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) | 20 | static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) |
| 21 | { | 21 | { |
| 22 | struct device *dev = ci->gadget.dev.parent; | 22 | struct device *dev = ci->gadget.dev.parent; |
| 23 | int val; | ||
| 24 | 23 | ||
| 25 | switch (event) { | 24 | switch (event) { |
| 26 | case CI_HDRC_CONTROLLER_RESET_EVENT: | 25 | case CI_HDRC_CONTROLLER_RESET_EVENT: |
| 27 | dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); | 26 | dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); |
| 28 | writel(0, USB_AHBBURST); | 27 | writel(0, USB_AHBBURST); |
| 29 | writel(0, USB_AHBMODE); | 28 | writel(0, USB_AHBMODE); |
| 29 | usb_phy_init(ci->transceiver); | ||
| 30 | break; | 30 | break; |
| 31 | case CI_HDRC_CONTROLLER_STOPPED_EVENT: | 31 | case CI_HDRC_CONTROLLER_STOPPED_EVENT: |
| 32 | dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n"); | 32 | dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n"); |
| @@ -34,10 +34,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) | |||
| 34 | * Put the transceiver in non-driving mode. Otherwise host | 34 | * Put the transceiver in non-driving mode. Otherwise host |
| 35 | * may not detect soft-disconnection. | 35 | * may not detect soft-disconnection. |
| 36 | */ | 36 | */ |
| 37 | val = usb_phy_io_read(ci->transceiver, ULPI_FUNC_CTRL); | 37 | usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN); |
| 38 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
| 39 | val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; | ||
| 40 | usb_phy_io_write(ci->transceiver, val, ULPI_FUNC_CTRL); | ||
| 41 | break; | 38 | break; |
| 42 | default: | 39 | default: |
| 43 | dev_dbg(dev, "unknown ci_hdrc event\n"); | 40 | dev_dbg(dev, "unknown ci_hdrc event\n"); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8a4dcbc7a75f..d481c99a20d7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -1728,8 +1728,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1728 | * - Change autosuspend delay of hub can avoid unnecessary auto | 1728 | * - Change autosuspend delay of hub can avoid unnecessary auto |
| 1729 | * suspend timer for hub, also may decrease power consumption | 1729 | * suspend timer for hub, also may decrease power consumption |
| 1730 | * of USB bus. | 1730 | * of USB bus. |
| 1731 | * | ||
| 1732 | * - If user has indicated to prevent autosuspend by passing | ||
| 1733 | * usbcore.autosuspend = -1 then keep autosuspend disabled. | ||
| 1731 | */ | 1734 | */ |
| 1732 | pm_runtime_set_autosuspend_delay(&hdev->dev, 0); | 1735 | #ifdef CONFIG_PM_RUNTIME |
| 1736 | if (hdev->dev.power.autosuspend_delay >= 0) | ||
| 1737 | pm_runtime_set_autosuspend_delay(&hdev->dev, 0); | ||
| 1738 | #endif | ||
| 1733 | 1739 | ||
| 1734 | /* | 1740 | /* |
| 1735 | * Hubs have proper suspend/resume support, except for root hubs | 1741 | * Hubs have proper suspend/resume support, except for root hubs |
| @@ -2107,8 +2113,8 @@ void usb_disconnect(struct usb_device **pdev) | |||
| 2107 | { | 2113 | { |
| 2108 | struct usb_port *port_dev = NULL; | 2114 | struct usb_port *port_dev = NULL; |
| 2109 | struct usb_device *udev = *pdev; | 2115 | struct usb_device *udev = *pdev; |
| 2110 | struct usb_hub *hub; | 2116 | struct usb_hub *hub = NULL; |
| 2111 | int port1; | 2117 | int port1 = 1; |
| 2112 | 2118 | ||
| 2113 | /* mark the device as inactive, so any further urb submissions for | 2119 | /* mark the device as inactive, so any further urb submissions for |
| 2114 | * this device (and any of its children) will fail immediately. | 2120 | * this device (and any of its children) will fail immediately. |
| @@ -4631,9 +4637,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, | |||
| 4631 | if (status != -ENODEV && | 4637 | if (status != -ENODEV && |
| 4632 | port1 != unreliable_port && | 4638 | port1 != unreliable_port && |
| 4633 | printk_ratelimit()) | 4639 | printk_ratelimit()) |
| 4634 | dev_err(&udev->dev, "connect-debounce failed, port %d disabled\n", | 4640 | dev_err(&port_dev->dev, "connect-debounce failed\n"); |
| 4635 | port1); | ||
| 4636 | |||
| 4637 | portstatus &= ~USB_PORT_STAT_CONNECTION; | 4641 | portstatus &= ~USB_PORT_STAT_CONNECTION; |
| 4638 | unreliable_port = port1; | 4642 | unreliable_port = port1; |
| 4639 | } else { | 4643 | } else { |
| @@ -5020,9 +5024,10 @@ static void hub_events(void) | |||
| 5020 | 5024 | ||
| 5021 | hub = list_entry(tmp, struct usb_hub, event_list); | 5025 | hub = list_entry(tmp, struct usb_hub, event_list); |
| 5022 | kref_get(&hub->kref); | 5026 | kref_get(&hub->kref); |
| 5027 | hdev = hub->hdev; | ||
| 5028 | usb_get_dev(hdev); | ||
| 5023 | spin_unlock_irq(&hub_event_lock); | 5029 | spin_unlock_irq(&hub_event_lock); |
| 5024 | 5030 | ||
| 5025 | hdev = hub->hdev; | ||
| 5026 | hub_dev = hub->intfdev; | 5031 | hub_dev = hub->intfdev; |
| 5027 | intf = to_usb_interface(hub_dev); | 5032 | intf = to_usb_interface(hub_dev); |
| 5028 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", | 5033 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", |
| @@ -5135,6 +5140,7 @@ static void hub_events(void) | |||
| 5135 | usb_autopm_put_interface(intf); | 5140 | usb_autopm_put_interface(intf); |
| 5136 | loop_disconnected: | 5141 | loop_disconnected: |
| 5137 | usb_unlock_device(hdev); | 5142 | usb_unlock_device(hdev); |
| 5143 | usb_put_dev(hdev); | ||
| 5138 | kref_put(&hub->kref, hub_release); | 5144 | kref_put(&hub->kref, hub_release); |
| 5139 | 5145 | ||
| 5140 | } /* end while (1) */ | 5146 | } /* end while (1) */ |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0ba9c335b584..ce6071d65d51 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -1649,6 +1649,7 @@ static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) | |||
| 1649 | dev_err(hsotg->dev, | 1649 | dev_err(hsotg->dev, |
| 1650 | "%s: timeout flushing fifo (GRSTCTL=%08x)\n", | 1650 | "%s: timeout flushing fifo (GRSTCTL=%08x)\n", |
| 1651 | __func__, val); | 1651 | __func__, val); |
| 1652 | break; | ||
| 1652 | } | 1653 | } |
| 1653 | 1654 | ||
| 1654 | udelay(1); | 1655 | udelay(1); |
| @@ -1901,7 +1902,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
| 1901 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | 1902 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) |
| 1902 | { | 1903 | { |
| 1903 | u32 dsts = readl(hsotg->regs + DSTS); | 1904 | u32 dsts = readl(hsotg->regs + DSTS); |
| 1904 | int ep0_mps = 0, ep_mps; | 1905 | int ep0_mps = 0, ep_mps = 8; |
| 1905 | 1906 | ||
| 1906 | /* | 1907 | /* |
| 1907 | * This should signal the finish of the enumeration phase | 1908 | * This should signal the finish of the enumeration phase |
| @@ -2747,13 +2748,14 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) | |||
| 2747 | 2748 | ||
| 2748 | dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); | 2749 | dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); |
| 2749 | 2750 | ||
| 2750 | if (hsotg->phy) { | 2751 | if (hsotg->uphy) |
| 2751 | phy_init(hsotg->phy); | ||
| 2752 | phy_power_on(hsotg->phy); | ||
| 2753 | } else if (hsotg->uphy) | ||
| 2754 | usb_phy_init(hsotg->uphy); | 2752 | usb_phy_init(hsotg->uphy); |
| 2755 | else if (hsotg->plat->phy_init) | 2753 | else if (hsotg->plat && hsotg->plat->phy_init) |
| 2756 | hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); | 2754 | hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); |
| 2755 | else { | ||
| 2756 | phy_init(hsotg->phy); | ||
| 2757 | phy_power_on(hsotg->phy); | ||
| 2758 | } | ||
| 2757 | } | 2759 | } |
| 2758 | 2760 | ||
| 2759 | /** | 2761 | /** |
| @@ -2767,13 +2769,14 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) | |||
| 2767 | { | 2769 | { |
| 2768 | struct platform_device *pdev = to_platform_device(hsotg->dev); | 2770 | struct platform_device *pdev = to_platform_device(hsotg->dev); |
| 2769 | 2771 | ||
| 2770 | if (hsotg->phy) { | 2772 | if (hsotg->uphy) |
| 2771 | phy_power_off(hsotg->phy); | ||
| 2772 | phy_exit(hsotg->phy); | ||
| 2773 | } else if (hsotg->uphy) | ||
| 2774 | usb_phy_shutdown(hsotg->uphy); | 2773 | usb_phy_shutdown(hsotg->uphy); |
| 2775 | else if (hsotg->plat->phy_exit) | 2774 | else if (hsotg->plat && hsotg->plat->phy_exit) |
| 2776 | hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); | 2775 | hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); |
| 2776 | else { | ||
| 2777 | phy_power_off(hsotg->phy); | ||
| 2778 | phy_exit(hsotg->phy); | ||
| 2779 | } | ||
| 2777 | } | 2780 | } |
| 2778 | 2781 | ||
| 2779 | /** | 2782 | /** |
| @@ -2892,13 +2895,11 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
| 2892 | return -ENODEV; | 2895 | return -ENODEV; |
| 2893 | 2896 | ||
| 2894 | /* all endpoints should be shutdown */ | 2897 | /* all endpoints should be shutdown */ |
| 2895 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 2898 | for (ep = 1; ep < hsotg->num_of_eps; ep++) |
| 2896 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 2899 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); |
| 2897 | 2900 | ||
| 2898 | spin_lock_irqsave(&hsotg->lock, flags); | 2901 | spin_lock_irqsave(&hsotg->lock, flags); |
| 2899 | 2902 | ||
| 2900 | s3c_hsotg_phy_disable(hsotg); | ||
| 2901 | |||
| 2902 | if (!driver) | 2903 | if (!driver) |
| 2903 | hsotg->driver = NULL; | 2904 | hsotg->driver = NULL; |
| 2904 | 2905 | ||
| @@ -2941,7 +2942,6 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | |||
| 2941 | s3c_hsotg_phy_enable(hsotg); | 2942 | s3c_hsotg_phy_enable(hsotg); |
| 2942 | s3c_hsotg_core_init(hsotg); | 2943 | s3c_hsotg_core_init(hsotg); |
| 2943 | } else { | 2944 | } else { |
| 2944 | s3c_hsotg_disconnect(hsotg); | ||
| 2945 | s3c_hsotg_phy_disable(hsotg); | 2945 | s3c_hsotg_phy_disable(hsotg); |
| 2946 | } | 2946 | } |
| 2947 | 2947 | ||
| @@ -3441,13 +3441,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
| 3441 | 3441 | ||
| 3442 | hsotg->irq = ret; | 3442 | hsotg->irq = ret; |
| 3443 | 3443 | ||
| 3444 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, | ||
| 3445 | dev_name(dev), hsotg); | ||
| 3446 | if (ret < 0) { | ||
| 3447 | dev_err(dev, "cannot claim IRQ\n"); | ||
| 3448 | goto err_clk; | ||
| 3449 | } | ||
| 3450 | |||
| 3451 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); | 3444 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); |
| 3452 | 3445 | ||
| 3453 | hsotg->gadget.max_speed = USB_SPEED_HIGH; | 3446 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
| @@ -3488,9 +3481,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
| 3488 | if (hsotg->phy && (phy_get_bus_width(phy) == 8)) | 3481 | if (hsotg->phy && (phy_get_bus_width(phy) == 8)) |
| 3489 | hsotg->phyif = GUSBCFG_PHYIF8; | 3482 | hsotg->phyif = GUSBCFG_PHYIF8; |
| 3490 | 3483 | ||
| 3491 | if (hsotg->phy) | ||
| 3492 | phy_init(hsotg->phy); | ||
| 3493 | |||
| 3494 | /* usb phy enable */ | 3484 | /* usb phy enable */ |
| 3495 | s3c_hsotg_phy_enable(hsotg); | 3485 | s3c_hsotg_phy_enable(hsotg); |
| 3496 | 3486 | ||
| @@ -3498,6 +3488,17 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
| 3498 | s3c_hsotg_init(hsotg); | 3488 | s3c_hsotg_init(hsotg); |
| 3499 | s3c_hsotg_hw_cfg(hsotg); | 3489 | s3c_hsotg_hw_cfg(hsotg); |
| 3500 | 3490 | ||
| 3491 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, | ||
| 3492 | dev_name(dev), hsotg); | ||
| 3493 | if (ret < 0) { | ||
| 3494 | s3c_hsotg_phy_disable(hsotg); | ||
| 3495 | clk_disable_unprepare(hsotg->clk); | ||
| 3496 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | ||
| 3497 | hsotg->supplies); | ||
| 3498 | dev_err(dev, "cannot claim IRQ\n"); | ||
| 3499 | goto err_clk; | ||
| 3500 | } | ||
| 3501 | |||
| 3501 | /* hsotg->num_of_eps holds number of EPs other than ep0 */ | 3502 | /* hsotg->num_of_eps holds number of EPs other than ep0 */ |
| 3502 | 3503 | ||
| 3503 | if (hsotg->num_of_eps == 0) { | 3504 | if (hsotg->num_of_eps == 0) { |
| @@ -3582,9 +3583,6 @@ static int s3c_hsotg_remove(struct platform_device *pdev) | |||
| 3582 | usb_gadget_unregister_driver(hsotg->driver); | 3583 | usb_gadget_unregister_driver(hsotg->driver); |
| 3583 | } | 3584 | } |
| 3584 | 3585 | ||
| 3585 | s3c_hsotg_phy_disable(hsotg); | ||
| 3586 | if (hsotg->phy) | ||
| 3587 | phy_exit(hsotg->phy); | ||
| 3588 | clk_disable_unprepare(hsotg->clk); | 3586 | clk_disable_unprepare(hsotg->clk); |
| 3589 | 3587 | ||
| 3590 | return 0; | 3588 | return 0; |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b769c1faaf03..9069984fe5cf 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -799,20 +799,21 @@ static int dwc3_remove(struct platform_device *pdev) | |||
| 799 | { | 799 | { |
| 800 | struct dwc3 *dwc = platform_get_drvdata(pdev); | 800 | struct dwc3 *dwc = platform_get_drvdata(pdev); |
| 801 | 801 | ||
| 802 | dwc3_debugfs_exit(dwc); | ||
| 803 | dwc3_core_exit_mode(dwc); | ||
| 804 | dwc3_event_buffers_cleanup(dwc); | ||
| 805 | dwc3_free_event_buffers(dwc); | ||
| 806 | |||
| 802 | usb_phy_set_suspend(dwc->usb2_phy, 1); | 807 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
| 803 | usb_phy_set_suspend(dwc->usb3_phy, 1); | 808 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
| 804 | phy_power_off(dwc->usb2_generic_phy); | 809 | phy_power_off(dwc->usb2_generic_phy); |
| 805 | phy_power_off(dwc->usb3_generic_phy); | 810 | phy_power_off(dwc->usb3_generic_phy); |
| 806 | 811 | ||
| 812 | dwc3_core_exit(dwc); | ||
| 813 | |||
| 807 | pm_runtime_put_sync(&pdev->dev); | 814 | pm_runtime_put_sync(&pdev->dev); |
| 808 | pm_runtime_disable(&pdev->dev); | 815 | pm_runtime_disable(&pdev->dev); |
| 809 | 816 | ||
| 810 | dwc3_debugfs_exit(dwc); | ||
| 811 | dwc3_core_exit_mode(dwc); | ||
| 812 | dwc3_event_buffers_cleanup(dwc); | ||
| 813 | dwc3_free_event_buffers(dwc); | ||
| 814 | dwc3_core_exit(dwc); | ||
| 815 | |||
| 816 | return 0; | 817 | return 0; |
| 817 | } | 818 | } |
| 818 | 819 | ||
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ef4936ff626c..fc0de3753648 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
| @@ -425,7 +425,7 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) | |||
| 425 | 425 | ||
| 426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) | 426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) |
| 427 | { | 427 | { |
| 428 | u32 ret; | 428 | int ret; |
| 429 | struct device_node *node = omap->dev->of_node; | 429 | struct device_node *node = omap->dev->of_node; |
| 430 | struct extcon_dev *edev; | 430 | struct extcon_dev *edev; |
| 431 | 431 | ||
| @@ -576,9 +576,9 @@ static int dwc3_omap_remove(struct platform_device *pdev) | |||
| 576 | if (omap->extcon_id_dev.edev) | 576 | if (omap->extcon_id_dev.edev) |
| 577 | extcon_unregister_interest(&omap->extcon_id_dev); | 577 | extcon_unregister_interest(&omap->extcon_id_dev); |
| 578 | dwc3_omap_disable_irqs(omap); | 578 | dwc3_omap_disable_irqs(omap); |
| 579 | device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); | ||
| 579 | pm_runtime_put_sync(&pdev->dev); | 580 | pm_runtime_put_sync(&pdev->dev); |
| 580 | pm_runtime_disable(&pdev->dev); | 581 | pm_runtime_disable(&pdev->dev); |
| 581 | device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); | ||
| 582 | 582 | ||
| 583 | return 0; | 583 | return 0; |
| 584 | } | 584 | } |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 349cacc577d8..490a6ca00733 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -527,7 +527,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
| 527 | dep->stream_capable = true; | 527 | dep->stream_capable = true; |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | if (usb_endpoint_xfer_isoc(desc)) | 530 | if (!usb_endpoint_xfer_control(desc)) |
| 531 | params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; | 531 | params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; |
| 532 | 532 | ||
| 533 | /* | 533 | /* |
| @@ -1225,16 +1225,17 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, | |||
| 1225 | 1225 | ||
| 1226 | int ret; | 1226 | int ret; |
| 1227 | 1227 | ||
| 1228 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1228 | if (!dep->endpoint.desc) { | 1229 | if (!dep->endpoint.desc) { |
| 1229 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", | 1230 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", |
| 1230 | request, ep->name); | 1231 | request, ep->name); |
| 1232 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1231 | return -ESHUTDOWN; | 1233 | return -ESHUTDOWN; |
| 1232 | } | 1234 | } |
| 1233 | 1235 | ||
| 1234 | dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", | 1236 | dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", |
| 1235 | request, ep->name, request->length); | 1237 | request, ep->name, request->length); |
| 1236 | 1238 | ||
| 1237 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1238 | ret = __dwc3_gadget_ep_queue(dep, req); | 1239 | ret = __dwc3_gadget_ep_queue(dep, req); |
| 1239 | spin_unlock_irqrestore(&dwc->lock, flags); | 1240 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 1240 | 1241 | ||
| @@ -2041,12 +2042,6 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
| 2041 | dwc3_endpoint_transfer_complete(dwc, dep, event); | 2042 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2042 | break; | 2043 | break; |
| 2043 | case DWC3_DEPEVT_XFERINPROGRESS: | 2044 | case DWC3_DEPEVT_XFERINPROGRESS: |
| 2044 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
| 2045 | dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n", | ||
| 2046 | dep->name); | ||
| 2047 | return; | ||
| 2048 | } | ||
| 2049 | |||
| 2050 | dwc3_endpoint_transfer_complete(dwc, dep, event); | 2045 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2051 | break; | 2046 | break; |
| 2052 | case DWC3_DEPEVT_XFERNOTREADY: | 2047 | case DWC3_DEPEVT_XFERNOTREADY: |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index a186afeaa700..9add915d41f7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG | 4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG |
| 5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG | 5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG |
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc | 6 | ccflags-y += -Idrivers/usb/gadget/udc |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o | 8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o |
| 9 | libcomposite-y := usbstring.o config.o epautoconf.o | 9 | libcomposite-y := usbstring.o config.o epautoconf.o |
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 6d91f21b52a6..83ae1065149d 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | # USB peripheral controller drivers | 2 | # USB peripheral controller drivers |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | 5 | ccflags-y := -Idrivers/usb/gadget/ |
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | 6 | ccflags-y += -Idrivers/usb/gadget/udc/ |
| 7 | 7 | ||
| 8 | # USB Functions | 8 | # USB Functions |
| 9 | usb_f_acm-y := f_acm.o | 9 | usb_f_acm-y := f_acm.o |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index dc30adf15a01..0dc3552d1360 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
| @@ -155,6 +155,12 @@ struct ffs_io_data { | |||
| 155 | struct usb_request *req; | 155 | struct usb_request *req; |
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| 158 | struct ffs_desc_helper { | ||
| 159 | struct ffs_data *ffs; | ||
| 160 | unsigned interfaces_count; | ||
| 161 | unsigned eps_count; | ||
| 162 | }; | ||
| 163 | |||
| 158 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); | 164 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); |
| 159 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); | 165 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); |
| 160 | 166 | ||
| @@ -1830,7 +1836,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1830 | u8 *valuep, struct usb_descriptor_header *desc, | 1836 | u8 *valuep, struct usb_descriptor_header *desc, |
| 1831 | void *priv) | 1837 | void *priv) |
| 1832 | { | 1838 | { |
| 1833 | struct ffs_data *ffs = priv; | 1839 | struct ffs_desc_helper *helper = priv; |
| 1840 | struct usb_endpoint_descriptor *d; | ||
| 1834 | 1841 | ||
| 1835 | ENTER(); | 1842 | ENTER(); |
| 1836 | 1843 | ||
| @@ -1844,8 +1851,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1844 | * encountered interface "n" then there are at least | 1851 | * encountered interface "n" then there are at least |
| 1845 | * "n+1" interfaces. | 1852 | * "n+1" interfaces. |
| 1846 | */ | 1853 | */ |
| 1847 | if (*valuep >= ffs->interfaces_count) | 1854 | if (*valuep >= helper->interfaces_count) |
| 1848 | ffs->interfaces_count = *valuep + 1; | 1855 | helper->interfaces_count = *valuep + 1; |
| 1849 | break; | 1856 | break; |
| 1850 | 1857 | ||
| 1851 | case FFS_STRING: | 1858 | case FFS_STRING: |
| @@ -1853,14 +1860,22 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1853 | * Strings are indexed from 1 (0 is magic ;) reserved | 1860 | * Strings are indexed from 1 (0 is magic ;) reserved |
| 1854 | * for languages list or some such) | 1861 | * for languages list or some such) |
| 1855 | */ | 1862 | */ |
| 1856 | if (*valuep > ffs->strings_count) | 1863 | if (*valuep > helper->ffs->strings_count) |
| 1857 | ffs->strings_count = *valuep; | 1864 | helper->ffs->strings_count = *valuep; |
| 1858 | break; | 1865 | break; |
| 1859 | 1866 | ||
| 1860 | case FFS_ENDPOINT: | 1867 | case FFS_ENDPOINT: |
| 1861 | /* Endpoints are indexed from 1 as well. */ | 1868 | d = (void *)desc; |
| 1862 | if ((*valuep & USB_ENDPOINT_NUMBER_MASK) > ffs->eps_count) | 1869 | helper->eps_count++; |
| 1863 | ffs->eps_count = (*valuep & USB_ENDPOINT_NUMBER_MASK); | 1870 | if (helper->eps_count >= 15) |
| 1871 | return -EINVAL; | ||
| 1872 | /* Check if descriptors for any speed were already parsed */ | ||
| 1873 | if (!helper->ffs->eps_count && !helper->ffs->interfaces_count) | ||
| 1874 | helper->ffs->eps_addrmap[helper->eps_count] = | ||
| 1875 | d->bEndpointAddress; | ||
| 1876 | else if (helper->ffs->eps_addrmap[helper->eps_count] != | ||
| 1877 | d->bEndpointAddress) | ||
| 1878 | return -EINVAL; | ||
| 1864 | break; | 1879 | break; |
| 1865 | } | 1880 | } |
| 1866 | 1881 | ||
| @@ -2053,6 +2068,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 2053 | char *data = _data, *raw_descs; | 2068 | char *data = _data, *raw_descs; |
| 2054 | unsigned os_descs_count = 0, counts[3], flags; | 2069 | unsigned os_descs_count = 0, counts[3], flags; |
| 2055 | int ret = -EINVAL, i; | 2070 | int ret = -EINVAL, i; |
| 2071 | struct ffs_desc_helper helper; | ||
| 2056 | 2072 | ||
| 2057 | ENTER(); | 2073 | ENTER(); |
| 2058 | 2074 | ||
| @@ -2101,13 +2117,29 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 2101 | 2117 | ||
| 2102 | /* Read descriptors */ | 2118 | /* Read descriptors */ |
| 2103 | raw_descs = data; | 2119 | raw_descs = data; |
| 2120 | helper.ffs = ffs; | ||
| 2104 | for (i = 0; i < 3; ++i) { | 2121 | for (i = 0; i < 3; ++i) { |
| 2105 | if (!counts[i]) | 2122 | if (!counts[i]) |
| 2106 | continue; | 2123 | continue; |
| 2124 | helper.interfaces_count = 0; | ||
| 2125 | helper.eps_count = 0; | ||
| 2107 | ret = ffs_do_descs(counts[i], data, len, | 2126 | ret = ffs_do_descs(counts[i], data, len, |
| 2108 | __ffs_data_do_entity, ffs); | 2127 | __ffs_data_do_entity, &helper); |
| 2109 | if (ret < 0) | 2128 | if (ret < 0) |
| 2110 | goto error; | 2129 | goto error; |
| 2130 | if (!ffs->eps_count && !ffs->interfaces_count) { | ||
| 2131 | ffs->eps_count = helper.eps_count; | ||
| 2132 | ffs->interfaces_count = helper.interfaces_count; | ||
| 2133 | } else { | ||
| 2134 | if (ffs->eps_count != helper.eps_count) { | ||
| 2135 | ret = -EINVAL; | ||
| 2136 | goto error; | ||
| 2137 | } | ||
| 2138 | if (ffs->interfaces_count != helper.interfaces_count) { | ||
| 2139 | ret = -EINVAL; | ||
| 2140 | goto error; | ||
| 2141 | } | ||
| 2142 | } | ||
| 2111 | data += ret; | 2143 | data += ret; |
| 2112 | len -= ret; | 2144 | len -= ret; |
| 2113 | } | 2145 | } |
| @@ -2342,9 +2374,18 @@ static void ffs_event_add(struct ffs_data *ffs, | |||
| 2342 | spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); | 2374 | spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); |
| 2343 | } | 2375 | } |
| 2344 | 2376 | ||
| 2345 | |||
| 2346 | /* Bind/unbind USB function hooks *******************************************/ | 2377 | /* Bind/unbind USB function hooks *******************************************/ |
| 2347 | 2378 | ||
| 2379 | static int ffs_ep_addr2idx(struct ffs_data *ffs, u8 endpoint_address) | ||
| 2380 | { | ||
| 2381 | int i; | ||
| 2382 | |||
| 2383 | for (i = 1; i < ARRAY_SIZE(ffs->eps_addrmap); ++i) | ||
| 2384 | if (ffs->eps_addrmap[i] == endpoint_address) | ||
| 2385 | return i; | ||
| 2386 | return -ENOENT; | ||
| 2387 | } | ||
| 2388 | |||
| 2348 | static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | 2389 | static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, |
| 2349 | struct usb_descriptor_header *desc, | 2390 | struct usb_descriptor_header *desc, |
| 2350 | void *priv) | 2391 | void *priv) |
| @@ -2378,7 +2419,10 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
| 2378 | if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) | 2419 | if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) |
| 2379 | return 0; | 2420 | return 0; |
| 2380 | 2421 | ||
| 2381 | idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; | 2422 | idx = ffs_ep_addr2idx(func->ffs, ds->bEndpointAddress) - 1; |
| 2423 | if (idx < 0) | ||
| 2424 | return idx; | ||
| 2425 | |||
| 2382 | ffs_ep = func->eps + idx; | 2426 | ffs_ep = func->eps + idx; |
| 2383 | 2427 | ||
| 2384 | if (unlikely(ffs_ep->descs[ep_desc_id])) { | 2428 | if (unlikely(ffs_ep->descs[ep_desc_id])) { |
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index d50adda913cf..6e6f87656e7b 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c | |||
| @@ -1127,10 +1127,7 @@ void gether_disconnect(struct gether *link) | |||
| 1127 | 1127 | ||
| 1128 | DBG(dev, "%s\n", __func__); | 1128 | DBG(dev, "%s\n", __func__); |
| 1129 | 1129 | ||
| 1130 | netif_tx_lock(dev->net); | ||
| 1131 | netif_stop_queue(dev->net); | 1130 | netif_stop_queue(dev->net); |
| 1132 | netif_tx_unlock(dev->net); | ||
| 1133 | |||
| 1134 | netif_carrier_off(dev->net); | 1131 | netif_carrier_off(dev->net); |
| 1135 | 1132 | ||
| 1136 | /* disable endpoints, forcing (synchronous) completion | 1133 | /* disable endpoints, forcing (synchronous) completion |
diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index 63d6e71569c1..d48897e8ffeb 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h | |||
| @@ -224,6 +224,8 @@ struct ffs_data { | |||
| 224 | void *ms_os_descs_ext_prop_name_avail; | 224 | void *ms_os_descs_ext_prop_name_avail; |
| 225 | void *ms_os_descs_ext_prop_data_avail; | 225 | void *ms_os_descs_ext_prop_data_avail; |
| 226 | 226 | ||
| 227 | u8 eps_addrmap[15]; | ||
| 228 | |||
| 227 | unsigned short strings_count; | 229 | unsigned short strings_count; |
| 228 | unsigned short interfaces_count; | 230 | unsigned short interfaces_count; |
| 229 | unsigned short eps_count; | 231 | unsigned short eps_count; |
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..a5eb9a3fbb7a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c | |||
| @@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); | 195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); |
| 196 | usb_ep_set_halt(ep); | 196 | usb_ep_set_halt(ep); |
| 197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| 198 | uvc_queue_cancel(queue, 0); | ||
| 198 | goto requeue; | 199 | goto requeue; |
| 199 | } | 200 | } |
| 200 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 201 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| @@ -281,6 +282,7 @@ error: | |||
| 281 | static int | 282 | static int |
| 282 | uvc_video_pump(struct uvc_video *video) | 283 | uvc_video_pump(struct uvc_video *video) |
| 283 | { | 284 | { |
| 285 | struct uvc_video_queue *queue = &video->queue; | ||
| 284 | struct usb_request *req; | 286 | struct usb_request *req; |
| 285 | struct uvc_buffer *buf; | 287 | struct uvc_buffer *buf; |
| 286 | unsigned long flags; | 288 | unsigned long flags; |
| @@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video) | |||
| 322 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); | 324 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); |
| 323 | usb_ep_set_halt(video->ep); | 325 | usb_ep_set_halt(video->ep); |
| 324 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 326 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| 327 | uvc_queue_cancel(queue, 0); | ||
| 325 | break; | 328 | break; |
| 326 | } | 329 | } |
| 327 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 330 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile index a11aad5635df..edba2d1ee0f3 100644 --- a/drivers/usb/gadget/legacy/Makefile +++ b/drivers/usb/gadget/legacy/Makefile | |||
| @@ -2,9 +2,9 @@ | |||
| 2 | # USB gadget drivers | 2 | # USB gadget drivers |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | 5 | ccflags-y := -Idrivers/usb/gadget/ |
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | 6 | ccflags-y += -Idrivers/usb/gadget/udc/ |
| 7 | ccflags-y += -I$(PWD)/drivers/usb/gadget/function/ | 7 | ccflags-y += -Idrivers/usb/gadget/function/ |
| 8 | 8 | ||
| 9 | g_zero-y := zero.o | 9 | g_zero-y := zero.o |
| 10 | g_audio-y := audio.o | 10 | g_audio-y := audio.o |
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 986fc511a2ed..225e385a6160 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c | |||
| @@ -222,10 +222,12 @@ static void dbgp_unbind(struct usb_gadget *gadget) | |||
| 222 | { | 222 | { |
| 223 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 223 | #ifdef CONFIG_USB_G_DBGP_SERIAL |
| 224 | kfree(dbgp.serial); | 224 | kfree(dbgp.serial); |
| 225 | dbgp.serial = NULL; | ||
| 225 | #endif | 226 | #endif |
| 226 | if (dbgp.req) { | 227 | if (dbgp.req) { |
| 227 | kfree(dbgp.req->buf); | 228 | kfree(dbgp.req->buf); |
| 228 | usb_ep_free_request(gadget->ep0, dbgp.req); | 229 | usb_ep_free_request(gadget->ep0, dbgp.req); |
| 230 | dbgp.req = NULL; | ||
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | gadget->ep0->driver_data = NULL; | 233 | gadget->ep0->driver_data = NULL; |
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 2e4ce7704908..e96077b8bf79 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
| @@ -440,7 +440,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
| 440 | 440 | ||
| 441 | value = -ENOMEM; | 441 | value = -ENOMEM; |
| 442 | kbuf = memdup_user(buf, len); | 442 | kbuf = memdup_user(buf, len); |
| 443 | if (!kbuf) { | 443 | if (IS_ERR(kbuf)) { |
| 444 | value = PTR_ERR(kbuf); | 444 | value = PTR_ERR(kbuf); |
| 445 | goto free1; | 445 | goto free1; |
| 446 | } | 446 | } |
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 5151f947a4f5..34ebaa68504c 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig | |||
| @@ -332,7 +332,7 @@ config USB_GOKU | |||
| 332 | gadget drivers to also be dynamically linked. | 332 | gadget drivers to also be dynamically linked. |
| 333 | 333 | ||
| 334 | config USB_EG20T | 334 | config USB_EG20T |
| 335 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | 335 | tristate "Intel QUARK X1000/EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" |
| 336 | depends on PCI | 336 | depends on PCI |
| 337 | help | 337 | help |
| 338 | This is a USB device driver for EG20T PCH. | 338 | This is a USB device driver for EG20T PCH. |
| @@ -353,6 +353,7 @@ config USB_EG20T | |||
| 353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | 353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. |
| 354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | 354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. |
| 355 | 355 | ||
| 356 | This driver can be used with Intel's Quark X1000 SOC platform | ||
| 356 | # | 357 | # |
| 357 | # LAST -- dummy/emulated controller | 358 | # LAST -- dummy/emulated controller |
| 358 | # | 359 | # |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 906e65f0e4fa..c9fe67e29d35 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
| @@ -1661,7 +1661,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
| 1661 | if (dma_status) { | 1661 | if (dma_status) { |
| 1662 | int i; | 1662 | int i; |
| 1663 | 1663 | ||
| 1664 | for (i = 1; i < USBA_NR_DMAS; i++) | 1664 | for (i = 1; i <= USBA_NR_DMAS; i++) |
| 1665 | if (dma_status & (1 << i)) | 1665 | if (dma_status & (1 << i)) |
| 1666 | usba_dma_irq(udc, &udc->usba_ep[i]); | 1666 | usba_dma_irq(udc, &udc->usba_ep[i]); |
| 1667 | } | 1667 | } |
diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index d40255f784df..5c5d1adda7eb 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c | |||
| @@ -1398,13 +1398,17 @@ static int fusb300_probe(struct platform_device *pdev) | |||
| 1398 | 1398 | ||
| 1399 | /* initialize udc */ | 1399 | /* initialize udc */ |
| 1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); | 1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); |
| 1401 | if (fusb300 == NULL) | 1401 | if (fusb300 == NULL) { |
| 1402 | ret = -ENOMEM; | ||
| 1402 | goto clean_up; | 1403 | goto clean_up; |
| 1404 | } | ||
| 1403 | 1405 | ||
| 1404 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { | 1406 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { |
| 1405 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); | 1407 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); |
| 1406 | if (_ep[i] == NULL) | 1408 | if (_ep[i] == NULL) { |
| 1409 | ret = -ENOMEM; | ||
| 1407 | goto clean_up; | 1410 | goto clean_up; |
| 1411 | } | ||
| 1408 | fusb300->ep[i] = _ep[i]; | 1412 | fusb300->ep[i] = _ep[i]; |
| 1409 | } | 1413 | } |
| 1410 | 1414 | ||
diff --git a/drivers/usb/gadget/udc/fusb300_udc.h b/drivers/usb/gadget/udc/fusb300_udc.h index ae811d8d38b4..ad39f892d200 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.h +++ b/drivers/usb/gadget/udc/fusb300_udc.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | #ifndef __FUSB300_UDC_H__ | 14 | #ifndef __FUSB300_UDC_H__ |
| 15 | #define __FUSB300_UDC_H_ | 15 | #define __FUSB300_UDC_H__ |
| 16 | 16 | ||
| 17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 18 | 18 | ||
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index f4eac113690e..2e95715b50c0 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
| @@ -3320,7 +3320,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | |||
| 3320 | if (stat & tmp) { | 3320 | if (stat & tmp) { |
| 3321 | writel(tmp, &dev->regs->irqstat1); | 3321 | writel(tmp, &dev->regs->irqstat1); |
| 3322 | if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && | 3322 | if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && |
| 3323 | (readl(&dev->usb->usbstat) & mask)) || | 3323 | ((readl(&dev->usb->usbstat) & mask) == 0)) || |
| 3324 | ((readl(&dev->usb->usbctl) & | 3324 | ((readl(&dev->usb->usbctl) & |
| 3325 | BIT(VBUS_PIN)) == 0)) && | 3325 | BIT(VBUS_PIN)) == 0)) && |
| 3326 | (dev->gadget.speed != USB_SPEED_UNKNOWN)) { | 3326 | (dev->gadget.speed != USB_SPEED_UNKNOWN)) { |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index eb8c3bedb57a..460d953c91b6 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
| @@ -343,6 +343,7 @@ struct pch_vbus_gpio_data { | |||
| 343 | * @setup_data: Received setup data | 343 | * @setup_data: Received setup data |
| 344 | * @phys_addr: of device memory | 344 | * @phys_addr: of device memory |
| 345 | * @base_addr: for mapped device memory | 345 | * @base_addr: for mapped device memory |
| 346 | * @bar: Indicates which PCI BAR for USB regs | ||
| 346 | * @irq: IRQ line for the device | 347 | * @irq: IRQ line for the device |
| 347 | * @cfg_data: current cfg, intf, and alt in use | 348 | * @cfg_data: current cfg, intf, and alt in use |
| 348 | * @vbus_gpio: GPIO informaton for detecting VBUS | 349 | * @vbus_gpio: GPIO informaton for detecting VBUS |
| @@ -370,14 +371,17 @@ struct pch_udc_dev { | |||
| 370 | struct usb_ctrlrequest setup_data; | 371 | struct usb_ctrlrequest setup_data; |
| 371 | unsigned long phys_addr; | 372 | unsigned long phys_addr; |
| 372 | void __iomem *base_addr; | 373 | void __iomem *base_addr; |
| 374 | unsigned bar; | ||
| 373 | unsigned irq; | 375 | unsigned irq; |
| 374 | struct pch_udc_cfg_data cfg_data; | 376 | struct pch_udc_cfg_data cfg_data; |
| 375 | struct pch_vbus_gpio_data vbus_gpio; | 377 | struct pch_vbus_gpio_data vbus_gpio; |
| 376 | }; | 378 | }; |
| 377 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) | 379 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) |
| 378 | 380 | ||
| 381 | #define PCH_UDC_PCI_BAR_QUARK_X1000 0 | ||
| 379 | #define PCH_UDC_PCI_BAR 1 | 382 | #define PCH_UDC_PCI_BAR 1 |
| 380 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 383 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
| 384 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC 0x0939 | ||
| 381 | #define PCI_VENDOR_ID_ROHM 0x10DB | 385 | #define PCI_VENDOR_ID_ROHM 0x10DB |
| 382 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D | 386 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D |
| 383 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 | 387 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 |
| @@ -3076,7 +3080,7 @@ static void pch_udc_remove(struct pci_dev *pdev) | |||
| 3076 | iounmap(dev->base_addr); | 3080 | iounmap(dev->base_addr); |
| 3077 | if (dev->mem_region) | 3081 | if (dev->mem_region) |
| 3078 | release_mem_region(dev->phys_addr, | 3082 | release_mem_region(dev->phys_addr, |
| 3079 | pci_resource_len(pdev, PCH_UDC_PCI_BAR)); | 3083 | pci_resource_len(pdev, dev->bar)); |
| 3080 | if (dev->active) | 3084 | if (dev->active) |
| 3081 | pci_disable_device(pdev); | 3085 | pci_disable_device(pdev); |
| 3082 | kfree(dev); | 3086 | kfree(dev); |
| @@ -3144,9 +3148,15 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
| 3144 | dev->active = 1; | 3148 | dev->active = 1; |
| 3145 | pci_set_drvdata(pdev, dev); | 3149 | pci_set_drvdata(pdev, dev); |
| 3146 | 3150 | ||
| 3151 | /* Determine BAR based on PCI ID */ | ||
| 3152 | if (id->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC) | ||
| 3153 | dev->bar = PCH_UDC_PCI_BAR_QUARK_X1000; | ||
| 3154 | else | ||
| 3155 | dev->bar = PCH_UDC_PCI_BAR; | ||
| 3156 | |||
| 3147 | /* PCI resource allocation */ | 3157 | /* PCI resource allocation */ |
| 3148 | resource = pci_resource_start(pdev, 1); | 3158 | resource = pci_resource_start(pdev, dev->bar); |
| 3149 | len = pci_resource_len(pdev, 1); | 3159 | len = pci_resource_len(pdev, dev->bar); |
| 3150 | 3160 | ||
| 3151 | if (!request_mem_region(resource, len, KBUILD_MODNAME)) { | 3161 | if (!request_mem_region(resource, len, KBUILD_MODNAME)) { |
| 3152 | dev_err(&pdev->dev, "%s: pci device used already\n", __func__); | 3162 | dev_err(&pdev->dev, "%s: pci device used already\n", __func__); |
| @@ -3212,6 +3222,12 @@ finished: | |||
| 3212 | 3222 | ||
| 3213 | static const struct pci_device_id pch_udc_pcidev_id[] = { | 3223 | static const struct pci_device_id pch_udc_pcidev_id[] = { |
| 3214 | { | 3224 | { |
| 3225 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
| 3226 | PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC), | ||
| 3227 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
| 3228 | .class_mask = 0xffffffff, | ||
| 3229 | }, | ||
| 3230 | { | ||
| 3215 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), | 3231 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), |
| 3216 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | 3232 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, |
| 3217 | .class_mask = 0xffffffff, | 3233 | .class_mask = 0xffffffff, |
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 46008421c1ec..de2a8713b428 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c | |||
| @@ -1868,8 +1868,8 @@ static int r8a66597_probe(struct platform_device *pdev) | |||
| 1868 | 1868 | ||
| 1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1870 | reg = devm_ioremap_resource(&pdev->dev, res); | 1870 | reg = devm_ioremap_resource(&pdev->dev, res); |
| 1871 | if (!reg) | 1871 | if (IS_ERR(reg)) |
| 1872 | return -ENODEV; | 1872 | return PTR_ERR(reg); |
| 1873 | 1873 | ||
| 1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 1875 | irq = ires->start; | 1875 | irq = ires->start; |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index cc305c71ac3d..6130b7574908 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -1230,7 +1230,7 @@ int ehci_hub_control( | |||
| 1230 | if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) { | 1230 | if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) { |
| 1231 | spin_unlock_irqrestore(&ehci->lock, flags); | 1231 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 1232 | retval = ehset_single_step_set_feature(hcd, | 1232 | retval = ehset_single_step_set_feature(hcd, |
| 1233 | wIndex); | 1233 | wIndex + 1); |
| 1234 | spin_lock_irqsave(&ehci->lock, flags); | 1234 | spin_lock_irqsave(&ehci->lock, flags); |
| 1235 | break; | 1235 | break; |
| 1236 | } | 1236 | } |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index aa79e8749040..69aece31143a 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
| @@ -468,7 +468,8 @@ static void xhci_hub_report_usb2_link_state(u32 *status, u32 status_reg) | |||
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | /* Updates Link Status for super Speed port */ | 470 | /* Updates Link Status for super Speed port */ |
| 471 | static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg) | 471 | static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci, |
| 472 | u32 *status, u32 status_reg) | ||
| 472 | { | 473 | { |
| 473 | u32 pls = status_reg & PORT_PLS_MASK; | 474 | u32 pls = status_reg & PORT_PLS_MASK; |
| 474 | 475 | ||
| @@ -507,7 +508,8 @@ static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg) | |||
| 507 | * in which sometimes the port enters compliance mode | 508 | * in which sometimes the port enters compliance mode |
| 508 | * caused by a delay on the host-device negotiation. | 509 | * caused by a delay on the host-device negotiation. |
| 509 | */ | 510 | */ |
| 510 | if (pls == USB_SS_PORT_LS_COMP_MOD) | 511 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && |
| 512 | (pls == USB_SS_PORT_LS_COMP_MOD)) | ||
| 511 | pls |= USB_PORT_STAT_CONNECTION; | 513 | pls |= USB_PORT_STAT_CONNECTION; |
| 512 | } | 514 | } |
| 513 | 515 | ||
| @@ -666,7 +668,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, | |||
| 666 | } | 668 | } |
| 667 | /* Update Port Link State */ | 669 | /* Update Port Link State */ |
| 668 | if (hcd->speed == HCD_USB3) { | 670 | if (hcd->speed == HCD_USB3) { |
| 669 | xhci_hub_report_usb3_link_state(&status, raw_port_status); | 671 | xhci_hub_report_usb3_link_state(xhci, &status, raw_port_status); |
| 670 | /* | 672 | /* |
| 671 | * Verify if all USB3 Ports Have entered U0 already. | 673 | * Verify if all USB3 Ports Have entered U0 already. |
| 672 | * Delete Compliance Mode Timer if so. | 674 | * Delete Compliance Mode Timer if so. |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 8056d90690ee..8936211b161d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
| @@ -1812,6 +1812,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
| 1812 | 1812 | ||
| 1813 | if (xhci->lpm_command) | 1813 | if (xhci->lpm_command) |
| 1814 | xhci_free_command(xhci, xhci->lpm_command); | 1814 | xhci_free_command(xhci, xhci->lpm_command); |
| 1815 | xhci->lpm_command = NULL; | ||
| 1815 | if (xhci->cmd_ring) | 1816 | if (xhci->cmd_ring) |
| 1816 | xhci_ring_free(xhci, xhci->cmd_ring); | 1817 | xhci_ring_free(xhci, xhci->cmd_ring); |
| 1817 | xhci->cmd_ring = NULL; | 1818 | xhci->cmd_ring = NULL; |
| @@ -1819,7 +1820,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
| 1819 | xhci_cleanup_command_queue(xhci); | 1820 | xhci_cleanup_command_queue(xhci); |
| 1820 | 1821 | ||
| 1821 | num_ports = HCS_MAX_PORTS(xhci->hcs_params1); | 1822 | num_ports = HCS_MAX_PORTS(xhci->hcs_params1); |
| 1822 | for (i = 0; i < num_ports; i++) { | 1823 | for (i = 0; i < num_ports && xhci->rh_bw; i++) { |
| 1823 | struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; | 1824 | struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; |
| 1824 | for (j = 0; j < XHCI_MAX_INTERVAL; j++) { | 1825 | for (j = 0; j < XHCI_MAX_INTERVAL; j++) { |
| 1825 | struct list_head *ep = &bwt->interval_bw[j].endpoints; | 1826 | struct list_head *ep = &bwt->interval_bw[j].endpoints; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 687d36608155..c22a3e15a16e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -101,6 +101,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 101 | /* AMD PLL quirk */ | 101 | /* AMD PLL quirk */ |
| 102 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | 102 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
| 103 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 103 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
| 104 | |||
| 105 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | ||
| 106 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
| 107 | |||
| 104 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | 108 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
| 105 | xhci->quirks |= XHCI_LPM_SUPPORT; | 109 | xhci->quirks |= XHCI_LPM_SUPPORT; |
| 106 | xhci->quirks |= XHCI_INTEL_HOST; | 110 | xhci->quirks |= XHCI_INTEL_HOST; |
| @@ -151,6 +155,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 151 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 155 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
| 152 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 156 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 153 | 157 | ||
| 158 | /* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ | ||
| 159 | if (pdev->vendor == PCI_VENDOR_ID_VIA && | ||
| 160 | pdev->device == 0x3432) | ||
| 161 | xhci->quirks |= XHCI_BROKEN_STREAMS; | ||
| 162 | |||
| 154 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 163 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
| 155 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 164 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
| 156 | "QUIRK: Resetting on resume"); | 165 | "QUIRK: Resetting on resume"); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 60fb52ae864b..abed30b82905 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -364,32 +364,6 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
| 364 | } | 364 | } |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | /* | ||
| 368 | * Find the segment that trb is in. Start searching in start_seg. | ||
| 369 | * If we must move past a segment that has a link TRB with a toggle cycle state | ||
| 370 | * bit set, then we will toggle the value pointed at by cycle_state. | ||
| 371 | */ | ||
| 372 | static struct xhci_segment *find_trb_seg( | ||
| 373 | struct xhci_segment *start_seg, | ||
| 374 | union xhci_trb *trb, int *cycle_state) | ||
| 375 | { | ||
| 376 | struct xhci_segment *cur_seg = start_seg; | ||
| 377 | struct xhci_generic_trb *generic_trb; | ||
| 378 | |||
| 379 | while (cur_seg->trbs > trb || | ||
| 380 | &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { | ||
| 381 | generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic; | ||
| 382 | if (generic_trb->field[3] & cpu_to_le32(LINK_TOGGLE)) | ||
| 383 | *cycle_state ^= 0x1; | ||
| 384 | cur_seg = cur_seg->next; | ||
| 385 | if (cur_seg == start_seg) | ||
| 386 | /* Looped over the entire list. Oops! */ | ||
| 387 | return NULL; | ||
| 388 | } | ||
| 389 | return cur_seg; | ||
| 390 | } | ||
| 391 | |||
| 392 | |||
| 393 | static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, | 367 | static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, |
| 394 | unsigned int slot_id, unsigned int ep_index, | 368 | unsigned int slot_id, unsigned int ep_index, |
| 395 | unsigned int stream_id) | 369 | unsigned int stream_id) |
| @@ -459,9 +433,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
| 459 | struct xhci_virt_device *dev = xhci->devs[slot_id]; | 433 | struct xhci_virt_device *dev = xhci->devs[slot_id]; |
| 460 | struct xhci_virt_ep *ep = &dev->eps[ep_index]; | 434 | struct xhci_virt_ep *ep = &dev->eps[ep_index]; |
| 461 | struct xhci_ring *ep_ring; | 435 | struct xhci_ring *ep_ring; |
| 462 | struct xhci_generic_trb *trb; | 436 | struct xhci_segment *new_seg; |
| 437 | union xhci_trb *new_deq; | ||
| 463 | dma_addr_t addr; | 438 | dma_addr_t addr; |
| 464 | u64 hw_dequeue; | 439 | u64 hw_dequeue; |
| 440 | bool cycle_found = false; | ||
| 441 | bool td_last_trb_found = false; | ||
| 465 | 442 | ||
| 466 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, | 443 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, |
| 467 | ep_index, stream_id); | 444 | ep_index, stream_id); |
| @@ -486,45 +463,45 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
| 486 | hw_dequeue = le64_to_cpu(ep_ctx->deq); | 463 | hw_dequeue = le64_to_cpu(ep_ctx->deq); |
| 487 | } | 464 | } |
| 488 | 465 | ||
| 489 | /* Find virtual address and segment of hardware dequeue pointer */ | 466 | new_seg = ep_ring->deq_seg; |
| 490 | state->new_deq_seg = ep_ring->deq_seg; | 467 | new_deq = ep_ring->dequeue; |
| 491 | state->new_deq_ptr = ep_ring->dequeue; | 468 | state->new_cycle_state = hw_dequeue & 0x1; |
| 492 | while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr) | 469 | |
| 493 | != (dma_addr_t)(hw_dequeue & ~0xf)) { | ||
| 494 | next_trb(xhci, ep_ring, &state->new_deq_seg, | ||
| 495 | &state->new_deq_ptr); | ||
| 496 | if (state->new_deq_ptr == ep_ring->dequeue) { | ||
| 497 | WARN_ON(1); | ||
| 498 | return; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | /* | 470 | /* |
| 502 | * Find cycle state for last_trb, starting at old cycle state of | 471 | * We want to find the pointer, segment and cycle state of the new trb |
| 503 | * hw_dequeue. If there is only one segment ring, find_trb_seg() will | 472 | * (the one after current TD's last_trb). We know the cycle state at |
| 504 | * return immediately and cannot toggle the cycle state if this search | 473 | * hw_dequeue, so walk the ring until both hw_dequeue and last_trb are |
| 505 | * wraps around, so add one more toggle manually in that case. | 474 | * found. |
| 506 | */ | 475 | */ |
| 507 | state->new_cycle_state = hw_dequeue & 0x1; | 476 | do { |
| 508 | if (ep_ring->first_seg == ep_ring->first_seg->next && | 477 | if (!cycle_found && xhci_trb_virt_to_dma(new_seg, new_deq) |
| 509 | cur_td->last_trb < state->new_deq_ptr) | 478 | == (dma_addr_t)(hw_dequeue & ~0xf)) { |
| 510 | state->new_cycle_state ^= 0x1; | 479 | cycle_found = true; |
| 480 | if (td_last_trb_found) | ||
| 481 | break; | ||
| 482 | } | ||
| 483 | if (new_deq == cur_td->last_trb) | ||
| 484 | td_last_trb_found = true; | ||
| 511 | 485 | ||
| 512 | state->new_deq_ptr = cur_td->last_trb; | 486 | if (cycle_found && |
| 513 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 487 | TRB_TYPE_LINK_LE32(new_deq->generic.field[3]) && |
| 514 | "Finding segment containing last TRB in TD."); | 488 | new_deq->generic.field[3] & cpu_to_le32(LINK_TOGGLE)) |
| 515 | state->new_deq_seg = find_trb_seg(state->new_deq_seg, | 489 | state->new_cycle_state ^= 0x1; |
| 516 | state->new_deq_ptr, &state->new_cycle_state); | 490 | |
| 517 | if (!state->new_deq_seg) { | 491 | next_trb(xhci, ep_ring, &new_seg, &new_deq); |
| 518 | WARN_ON(1); | 492 | |
| 519 | return; | 493 | /* Search wrapped around, bail out */ |
| 520 | } | 494 | if (new_deq == ep->ring->dequeue) { |
| 495 | xhci_err(xhci, "Error: Failed finding new dequeue state\n"); | ||
| 496 | state->new_deq_seg = NULL; | ||
| 497 | state->new_deq_ptr = NULL; | ||
| 498 | return; | ||
| 499 | } | ||
| 500 | |||
| 501 | } while (!cycle_found || !td_last_trb_found); | ||
| 521 | 502 | ||
| 522 | /* Increment to find next TRB after last_trb. Cycle if appropriate. */ | 503 | state->new_deq_seg = new_seg; |
| 523 | trb = &state->new_deq_ptr->generic; | 504 | state->new_deq_ptr = new_deq; |
| 524 | if (TRB_TYPE_LINK_LE32(trb->field[3]) && | ||
| 525 | (trb->field[3] & cpu_to_le32(LINK_TOGGLE))) | ||
| 526 | state->new_cycle_state ^= 0x1; | ||
| 527 | next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); | ||
| 528 | 505 | ||
| 529 | /* Don't update the ring cycle state for the producer (us). */ | 506 | /* Don't update the ring cycle state for the producer (us). */ |
| 530 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 507 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
| @@ -2487,7 +2464,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
| 2487 | * last TRB of the previous TD. The command completion handle | 2464 | * last TRB of the previous TD. The command completion handle |
| 2488 | * will take care the rest. | 2465 | * will take care the rest. |
| 2489 | */ | 2466 | */ |
| 2490 | if (!event_seg && trb_comp_code == COMP_STOP_INVAL) { | 2467 | if (!event_seg && (trb_comp_code == COMP_STOP || |
| 2468 | trb_comp_code == COMP_STOP_INVAL)) { | ||
| 2491 | ret = 0; | 2469 | ret = 0; |
| 2492 | goto cleanup; | 2470 | goto cleanup; |
| 2493 | } | 2471 | } |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b6f21175b872..c4a8fca8ae93 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -2880,6 +2880,9 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | |||
| 2880 | ep_index, ep->stopped_stream, ep->stopped_td, | 2880 | ep_index, ep->stopped_stream, ep->stopped_td, |
| 2881 | &deq_state); | 2881 | &deq_state); |
| 2882 | 2882 | ||
| 2883 | if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) | ||
| 2884 | return; | ||
| 2885 | |||
| 2883 | /* HW with the reset endpoint quirk will use the saved dequeue state to | 2886 | /* HW with the reset endpoint quirk will use the saved dequeue state to |
| 2884 | * issue a configure endpoint command later. | 2887 | * issue a configure endpoint command later. |
| 2885 | */ | 2888 | */ |
| @@ -3968,13 +3971,21 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci, | |||
| 3968 | int ret; | 3971 | int ret; |
| 3969 | 3972 | ||
| 3970 | spin_lock_irqsave(&xhci->lock, flags); | 3973 | spin_lock_irqsave(&xhci->lock, flags); |
| 3971 | if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { | 3974 | |
| 3975 | virt_dev = xhci->devs[udev->slot_id]; | ||
| 3976 | |||
| 3977 | /* | ||
| 3978 | * virt_dev might not exists yet if xHC resumed from hibernate (S4) and | ||
| 3979 | * xHC was re-initialized. Exit latency will be set later after | ||
| 3980 | * hub_port_finish_reset() is done and xhci->devs[] are re-allocated | ||
| 3981 | */ | ||
| 3982 | |||
| 3983 | if (!virt_dev || max_exit_latency == virt_dev->current_mel) { | ||
| 3972 | spin_unlock_irqrestore(&xhci->lock, flags); | 3984 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 3973 | return 0; | 3985 | return 0; |
| 3974 | } | 3986 | } |
| 3975 | 3987 | ||
| 3976 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | 3988 | /* Attempt to issue an Evaluate Context command to change the MEL. */ |
| 3977 | virt_dev = xhci->devs[udev->slot_id]; | ||
| 3978 | command = xhci->lpm_command; | 3989 | command = xhci->lpm_command; |
| 3979 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 3990 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); |
| 3980 | if (!ctrl_ctx) { | 3991 | if (!ctrl_ctx) { |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 06b5d77cd9ad..633caf643122 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
| @@ -3250,6 +3250,7 @@ static const struct usb_device_id sisusb_table[] = { | |||
| 3250 | { USB_DEVICE(0x0711, 0x0918) }, | 3250 | { USB_DEVICE(0x0711, 0x0918) }, |
| 3251 | { USB_DEVICE(0x0711, 0x0920) }, | 3251 | { USB_DEVICE(0x0711, 0x0920) }, |
| 3252 | { USB_DEVICE(0x0711, 0x0950) }, | 3252 | { USB_DEVICE(0x0711, 0x0950) }, |
| 3253 | { USB_DEVICE(0x0711, 0x5200) }, | ||
| 3253 | { USB_DEVICE(0x182d, 0x021c) }, | 3254 | { USB_DEVICE(0x182d, 0x021c) }, |
| 3254 | { USB_DEVICE(0x182d, 0x0269) }, | 3255 | { USB_DEVICE(0x182d, 0x0269) }, |
| 3255 | { } | 3256 | { } |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 47ae6455d073..3ee133f675ab 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
| @@ -39,6 +39,7 @@ struct cppi41_dma_channel { | |||
| 39 | u32 transferred; | 39 | u32 transferred; |
| 40 | u32 packet_sz; | 40 | u32 packet_sz; |
| 41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
| 42 | int tx_zlp; | ||
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| 44 | #define MUSB_DMA_NUM_CHANNELS 15 | 45 | #define MUSB_DMA_NUM_CHANNELS 15 |
| @@ -122,6 +123,8 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
| 122 | { | 123 | { |
| 123 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 124 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
| 124 | struct musb *musb = hw_ep->musb; | 125 | struct musb *musb = hw_ep->musb; |
| 126 | void __iomem *epio = hw_ep->regs; | ||
| 127 | u16 csr; | ||
| 125 | 128 | ||
| 126 | if (!cppi41_channel->prog_len || | 129 | if (!cppi41_channel->prog_len || |
| 127 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { | 130 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { |
| @@ -131,15 +134,24 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
| 131 | cppi41_channel->transferred; | 134 | cppi41_channel->transferred; |
| 132 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; | 135 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; |
| 133 | cppi41_channel->channel.rx_packet_done = true; | 136 | cppi41_channel->channel.rx_packet_done = true; |
| 137 | |||
| 138 | /* | ||
| 139 | * transmit ZLP using PIO mode for transfers which size is | ||
| 140 | * multiple of EP packet size. | ||
| 141 | */ | ||
| 142 | if (cppi41_channel->tx_zlp && (cppi41_channel->transferred % | ||
| 143 | cppi41_channel->packet_sz) == 0) { | ||
| 144 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
| 145 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY; | ||
| 146 | musb_writew(epio, MUSB_TXCSR, csr); | ||
| 147 | } | ||
| 134 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); | 148 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); |
| 135 | } else { | 149 | } else { |
| 136 | /* next iteration, reload */ | 150 | /* next iteration, reload */ |
| 137 | struct dma_chan *dc = cppi41_channel->dc; | 151 | struct dma_chan *dc = cppi41_channel->dc; |
| 138 | struct dma_async_tx_descriptor *dma_desc; | 152 | struct dma_async_tx_descriptor *dma_desc; |
| 139 | enum dma_transfer_direction direction; | 153 | enum dma_transfer_direction direction; |
| 140 | u16 csr; | ||
| 141 | u32 remain_bytes; | 154 | u32 remain_bytes; |
| 142 | void __iomem *epio = cppi41_channel->hw_ep->regs; | ||
| 143 | 155 | ||
| 144 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; | 156 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; |
| 145 | 157 | ||
| @@ -363,6 +375,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, | |||
| 363 | cppi41_channel->total_len = len; | 375 | cppi41_channel->total_len = len; |
| 364 | cppi41_channel->transferred = 0; | 376 | cppi41_channel->transferred = 0; |
| 365 | cppi41_channel->packet_sz = packet_sz; | 377 | cppi41_channel->packet_sz = packet_sz; |
| 378 | cppi41_channel->tx_zlp = (cppi41_channel->is_tx && mode) ? 1 : 0; | ||
| 366 | 379 | ||
| 367 | /* | 380 | /* |
| 368 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more | 381 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more |
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 9aad00f11bd5..221faed9f074 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c | |||
| @@ -96,7 +96,7 @@ static bool ux500_configure_channel(struct dma_channel *channel, | |||
| 96 | struct musb *musb = ux500_channel->controller->private_data; | 96 | struct musb *musb = ux500_channel->controller->private_data; |
| 97 | 97 | ||
| 98 | dev_dbg(musb->controller, | 98 | dev_dbg(musb->controller, |
| 99 | "packet_sz=%d, mode=%d, dma_addr=0x%llu, len=%d is_tx=%d\n", | 99 | "packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n", |
| 100 | packet_sz, mode, (unsigned long long) dma_addr, | 100 | packet_sz, mode, (unsigned long long) dma_addr, |
| 101 | len, ux500_channel->is_tx); | 101 | len, ux500_channel->is_tx); |
| 102 | 102 | ||
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index ea9e705555df..f4b14bd97e14 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c | |||
| @@ -260,10 +260,8 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 260 | 260 | ||
| 261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), | 261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), |
| 262 | GFP_KERNEL); | 262 | GFP_KERNEL); |
| 263 | if (!gpio_vbus->phy.otg) { | 263 | if (!gpio_vbus->phy.otg) |
| 264 | kfree(gpio_vbus); | ||
| 265 | return -ENOMEM; | 264 | return -ENOMEM; |
| 266 | } | ||
| 267 | 265 | ||
| 268 | platform_set_drvdata(pdev, gpio_vbus); | 266 | platform_set_drvdata(pdev, gpio_vbus); |
| 269 | gpio_vbus->dev = &pdev->dev; | 267 | gpio_vbus->dev = &pdev->dev; |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index e4108eec5ef4..afc09087ec36 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
| @@ -1601,8 +1601,8 @@ static int msm_otg_probe(struct platform_device *pdev) | |||
| 1601 | */ | 1601 | */ |
| 1602 | if (motg->phy_number) { | 1602 | if (motg->phy_number) { |
| 1603 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); | 1603 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); |
| 1604 | if (IS_ERR(phy_select)) | 1604 | if (!phy_select) |
| 1605 | return PTR_ERR(phy_select); | 1605 | return -ENOMEM; |
| 1606 | /* Enable second PHY with the OTG port */ | 1606 | /* Enable second PHY with the OTG port */ |
| 1607 | writel(0x1, phy_select); | 1607 | writel(0x1, phy_select); |
| 1608 | } | 1608 | } |
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index c42bdf0c4a1f..00972eca04e7 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2012-2013 Freescale Semiconductor, Inc. | 2 | * Copyright 2012-2014 Freescale Semiconductor, Inc. |
| 3 | * Copyright (C) 2012 Marek Vasut <marex@denx.de> | 3 | * Copyright (C) 2012 Marek Vasut <marex@denx.de> |
| 4 | * on behalf of DENX Software Engineering GmbH | 4 | * on behalf of DENX Software Engineering GmbH |
| 5 | * | 5 | * |
| @@ -125,7 +125,13 @@ static const struct mxs_phy_data imx6sl_phy_data = { | |||
| 125 | MXS_PHY_NEED_IP_FIX, | 125 | MXS_PHY_NEED_IP_FIX, |
| 126 | }; | 126 | }; |
| 127 | 127 | ||
| 128 | static const struct mxs_phy_data imx6sx_phy_data = { | ||
| 129 | .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | | ||
| 130 | MXS_PHY_NEED_IP_FIX, | ||
| 131 | }; | ||
| 132 | |||
| 128 | static const struct of_device_id mxs_phy_dt_ids[] = { | 133 | static const struct of_device_id mxs_phy_dt_ids[] = { |
| 134 | { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, }, | ||
| 129 | { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, | 135 | { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, |
| 130 | { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, | 136 | { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, |
| 131 | { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, | 137 | { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, |
diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h index 68771bfd1825..80eedd45a20a 100644 --- a/drivers/usb/phy/phy-samsung-usb.h +++ b/drivers/usb/phy/phy-samsung-usb.h | |||
| @@ -216,7 +216,7 @@ | |||
| 216 | 216 | ||
| 217 | #define EXYNOS5_DRD_PHYPARAM1 (0x20) | 217 | #define EXYNOS5_DRD_PHYPARAM1 (0x20) |
| 218 | 218 | ||
| 219 | #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) | 219 | #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x3f << 0) |
| 220 | #define PHYPARAM1_PCS_TXDEEMPH (0x1c) | 220 | #define PHYPARAM1_PCS_TXDEEMPH (0x1c) |
| 221 | 221 | ||
| 222 | #define EXYNOS5_DRD_PHYTERM (0x24) | 222 | #define EXYNOS5_DRD_PHYTERM (0x24) |
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 13b4fa287da8..886f1807a67b 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c | |||
| @@ -878,8 +878,8 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, | |||
| 878 | return -ENOMEM; | 878 | return -ENOMEM; |
| 879 | } | 879 | } |
| 880 | 880 | ||
| 881 | tegra_phy->config = devm_kzalloc(&pdev->dev, | 881 | tegra_phy->config = devm_kzalloc(&pdev->dev, sizeof(*config), |
| 882 | sizeof(*tegra_phy->config), GFP_KERNEL); | 882 | GFP_KERNEL); |
| 883 | if (!tegra_phy->config) { | 883 | if (!tegra_phy->config) { |
| 884 | dev_err(&pdev->dev, | 884 | dev_err(&pdev->dev, |
| 885 | "unable to allocate memory for USB UTMIP config\n"); | 885 | "unable to allocate memory for USB UTMIP config\n"); |
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 6d0f6080eceb..045cd309367a 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
| @@ -232,6 +232,9 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) | |||
| 232 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); | 232 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); |
| 233 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | 233 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { |
| 234 | dev_dbg(dev, "unable to find transceiver\n"); | 234 | dev_dbg(dev, "unable to find transceiver\n"); |
| 235 | if (!IS_ERR(phy)) | ||
| 236 | phy = ERR_PTR(-ENODEV); | ||
| 237 | |||
| 235 | goto err0; | 238 | goto err0; |
| 236 | } | 239 | } |
| 237 | 240 | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 4fd36530bfa3..b0c97a3f1bfe 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
| @@ -108,19 +108,45 @@ static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) | |||
| 108 | return list_first_entry(&pipe->list, struct usbhs_pkt, node); | 108 | return list_first_entry(&pipe->list, struct usbhs_pkt, node); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, | ||
| 112 | struct usbhs_fifo *fifo); | ||
| 113 | static void usbhsf_fifo_unselect(struct usbhs_pipe *pipe, | ||
| 114 | struct usbhs_fifo *fifo); | ||
| 115 | static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo, | ||
| 116 | struct usbhs_pkt *pkt); | ||
| 117 | #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) | ||
| 118 | #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) | ||
| 119 | static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map); | ||
| 111 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) | 120 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) |
| 112 | { | 121 | { |
| 113 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 122 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
| 123 | struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe); | ||
| 114 | unsigned long flags; | 124 | unsigned long flags; |
| 115 | 125 | ||
| 116 | /******************** spin lock ********************/ | 126 | /******************** spin lock ********************/ |
| 117 | usbhs_lock(priv, flags); | 127 | usbhs_lock(priv, flags); |
| 118 | 128 | ||
| 129 | usbhs_pipe_disable(pipe); | ||
| 130 | |||
| 119 | if (!pkt) | 131 | if (!pkt) |
| 120 | pkt = __usbhsf_pkt_get(pipe); | 132 | pkt = __usbhsf_pkt_get(pipe); |
| 121 | 133 | ||
| 122 | if (pkt) | 134 | if (pkt) { |
| 135 | struct dma_chan *chan = NULL; | ||
| 136 | |||
| 137 | if (fifo) | ||
| 138 | chan = usbhsf_dma_chan_get(fifo, pkt); | ||
| 139 | if (chan) { | ||
| 140 | dmaengine_terminate_all(chan); | ||
| 141 | usbhsf_fifo_clear(pipe, fifo); | ||
| 142 | usbhsf_dma_unmap(pkt); | ||
| 143 | } | ||
| 144 | |||
| 123 | __usbhsf_pkt_del(pkt); | 145 | __usbhsf_pkt_del(pkt); |
| 146 | } | ||
| 147 | |||
| 148 | if (fifo) | ||
| 149 | usbhsf_fifo_unselect(pipe, fifo); | ||
| 124 | 150 | ||
| 125 | usbhs_unlock(priv, flags); | 151 | usbhs_unlock(priv, flags); |
| 126 | /******************** spin unlock ******************/ | 152 | /******************** spin unlock ******************/ |
| @@ -544,6 +570,7 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
| 544 | usbhsf_send_terminator(pipe, fifo); | 570 | usbhsf_send_terminator(pipe, fifo); |
| 545 | 571 | ||
| 546 | usbhsf_tx_irq_ctrl(pipe, !*is_done); | 572 | usbhsf_tx_irq_ctrl(pipe, !*is_done); |
| 573 | usbhs_pipe_running(pipe, !*is_done); | ||
| 547 | usbhs_pipe_enable(pipe); | 574 | usbhs_pipe_enable(pipe); |
| 548 | 575 | ||
| 549 | dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", | 576 | dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", |
| @@ -570,12 +597,21 @@ usbhs_fifo_write_busy: | |||
| 570 | * retry in interrupt | 597 | * retry in interrupt |
| 571 | */ | 598 | */ |
| 572 | usbhsf_tx_irq_ctrl(pipe, 1); | 599 | usbhsf_tx_irq_ctrl(pipe, 1); |
| 600 | usbhs_pipe_running(pipe, 1); | ||
| 573 | 601 | ||
| 574 | return ret; | 602 | return ret; |
| 575 | } | 603 | } |
| 576 | 604 | ||
| 605 | static int usbhsf_pio_prepare_push(struct usbhs_pkt *pkt, int *is_done) | ||
| 606 | { | ||
| 607 | if (usbhs_pipe_is_running(pkt->pipe)) | ||
| 608 | return 0; | ||
| 609 | |||
| 610 | return usbhsf_pio_try_push(pkt, is_done); | ||
| 611 | } | ||
| 612 | |||
| 577 | struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { | 613 | struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { |
| 578 | .prepare = usbhsf_pio_try_push, | 614 | .prepare = usbhsf_pio_prepare_push, |
| 579 | .try_run = usbhsf_pio_try_push, | 615 | .try_run = usbhsf_pio_try_push, |
| 580 | }; | 616 | }; |
| 581 | 617 | ||
| @@ -589,6 +625,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
| 589 | if (usbhs_pipe_is_busy(pipe)) | 625 | if (usbhs_pipe_is_busy(pipe)) |
| 590 | return 0; | 626 | return 0; |
| 591 | 627 | ||
| 628 | if (usbhs_pipe_is_running(pipe)) | ||
| 629 | return 0; | ||
| 630 | |||
| 592 | /* | 631 | /* |
| 593 | * pipe enable to prepare packet receive | 632 | * pipe enable to prepare packet receive |
| 594 | */ | 633 | */ |
| @@ -597,6 +636,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
| 597 | 636 | ||
| 598 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); | 637 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); |
| 599 | usbhs_pipe_enable(pipe); | 638 | usbhs_pipe_enable(pipe); |
| 639 | usbhs_pipe_running(pipe, 1); | ||
| 600 | usbhsf_rx_irq_ctrl(pipe, 1); | 640 | usbhsf_rx_irq_ctrl(pipe, 1); |
| 601 | 641 | ||
| 602 | return 0; | 642 | return 0; |
| @@ -642,6 +682,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
| 642 | (total_len < maxp)) { /* short packet */ | 682 | (total_len < maxp)) { /* short packet */ |
| 643 | *is_done = 1; | 683 | *is_done = 1; |
| 644 | usbhsf_rx_irq_ctrl(pipe, 0); | 684 | usbhsf_rx_irq_ctrl(pipe, 0); |
| 685 | usbhs_pipe_running(pipe, 0); | ||
| 645 | usbhs_pipe_disable(pipe); /* disable pipe first */ | 686 | usbhs_pipe_disable(pipe); /* disable pipe first */ |
| 646 | } | 687 | } |
| 647 | 688 | ||
| @@ -763,8 +804,6 @@ static void __usbhsf_dma_ctrl(struct usbhs_pipe *pipe, | |||
| 763 | usbhs_bset(priv, fifo->sel, DREQE, dreqe); | 804 | usbhs_bset(priv, fifo->sel, DREQE, dreqe); |
| 764 | } | 805 | } |
| 765 | 806 | ||
| 766 | #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) | ||
| 767 | #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) | ||
| 768 | static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | 807 | static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) |
| 769 | { | 808 | { |
| 770 | struct usbhs_pipe *pipe = pkt->pipe; | 809 | struct usbhs_pipe *pipe = pkt->pipe; |
| @@ -805,6 +844,7 @@ static void xfer_work(struct work_struct *work) | |||
| 805 | dev_dbg(dev, " %s %d (%d/ %d)\n", | 844 | dev_dbg(dev, " %s %d (%d/ %d)\n", |
| 806 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | 845 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
| 807 | 846 | ||
| 847 | usbhs_pipe_running(pipe, 1); | ||
| 808 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); | 848 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); |
| 809 | usbhs_pipe_enable(pipe); | 849 | usbhs_pipe_enable(pipe); |
| 810 | usbhsf_dma_start(pipe, fifo); | 850 | usbhsf_dma_start(pipe, fifo); |
| @@ -836,6 +876,10 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
| 836 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 876 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
| 837 | goto usbhsf_pio_prepare_push; | 877 | goto usbhsf_pio_prepare_push; |
| 838 | 878 | ||
| 879 | /* return at this time if the pipe is running */ | ||
| 880 | if (usbhs_pipe_is_running(pipe)) | ||
| 881 | return 0; | ||
| 882 | |||
| 839 | /* get enable DMA fifo */ | 883 | /* get enable DMA fifo */ |
| 840 | fifo = usbhsf_get_dma_fifo(priv, pkt); | 884 | fifo = usbhsf_get_dma_fifo(priv, pkt); |
| 841 | if (!fifo) | 885 | if (!fifo) |
| @@ -869,15 +913,29 @@ usbhsf_pio_prepare_push: | |||
| 869 | static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done) | 913 | static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done) |
| 870 | { | 914 | { |
| 871 | struct usbhs_pipe *pipe = pkt->pipe; | 915 | struct usbhs_pipe *pipe = pkt->pipe; |
| 916 | int is_short = pkt->trans % usbhs_pipe_get_maxpacket(pipe); | ||
| 917 | |||
| 918 | pkt->actual += pkt->trans; | ||
| 872 | 919 | ||
| 873 | pkt->actual = pkt->trans; | 920 | if (pkt->actual < pkt->length) |
| 921 | *is_done = 0; /* there are remainder data */ | ||
| 922 | else if (is_short) | ||
| 923 | *is_done = 1; /* short packet */ | ||
| 924 | else | ||
| 925 | *is_done = !pkt->zero; /* send zero packet? */ | ||
| 874 | 926 | ||
| 875 | *is_done = !pkt->zero; /* send zero packet ? */ | 927 | usbhs_pipe_running(pipe, !*is_done); |
| 876 | 928 | ||
| 877 | usbhsf_dma_stop(pipe, pipe->fifo); | 929 | usbhsf_dma_stop(pipe, pipe->fifo); |
| 878 | usbhsf_dma_unmap(pkt); | 930 | usbhsf_dma_unmap(pkt); |
| 879 | usbhsf_fifo_unselect(pipe, pipe->fifo); | 931 | usbhsf_fifo_unselect(pipe, pipe->fifo); |
| 880 | 932 | ||
| 933 | if (!*is_done) { | ||
| 934 | /* change handler to PIO */ | ||
| 935 | pkt->handler = &usbhs_fifo_pio_push_handler; | ||
| 936 | return pkt->handler->try_run(pkt, is_done); | ||
| 937 | } | ||
| 938 | |||
| 881 | return 0; | 939 | return 0; |
| 882 | } | 940 | } |
| 883 | 941 | ||
| @@ -972,8 +1030,10 @@ static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done) | |||
| 972 | if ((pkt->actual == pkt->length) || /* receive all data */ | 1030 | if ((pkt->actual == pkt->length) || /* receive all data */ |
| 973 | (pkt->trans < maxp)) { /* short packet */ | 1031 | (pkt->trans < maxp)) { /* short packet */ |
| 974 | *is_done = 1; | 1032 | *is_done = 1; |
| 1033 | usbhs_pipe_running(pipe, 0); | ||
| 975 | } else { | 1034 | } else { |
| 976 | /* re-enable */ | 1035 | /* re-enable */ |
| 1036 | usbhs_pipe_running(pipe, 0); | ||
| 977 | usbhsf_prepare_pop(pkt, is_done); | 1037 | usbhsf_prepare_pop(pkt, is_done); |
| 978 | } | 1038 | } |
| 979 | 1039 | ||
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 6a030b931a3b..9a705b15b3a1 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
| @@ -213,7 +213,10 @@ static int usbhs_status_get_each_irq(struct usbhs_priv *priv, | |||
| 213 | { | 213 | { |
| 214 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | 214 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
| 215 | u16 intenb0, intenb1; | 215 | u16 intenb0, intenb1; |
| 216 | unsigned long flags; | ||
| 216 | 217 | ||
| 218 | /******************** spin lock ********************/ | ||
| 219 | usbhs_lock(priv, flags); | ||
| 217 | state->intsts0 = usbhs_read(priv, INTSTS0); | 220 | state->intsts0 = usbhs_read(priv, INTSTS0); |
| 218 | state->intsts1 = usbhs_read(priv, INTSTS1); | 221 | state->intsts1 = usbhs_read(priv, INTSTS1); |
| 219 | 222 | ||
| @@ -229,6 +232,8 @@ static int usbhs_status_get_each_irq(struct usbhs_priv *priv, | |||
| 229 | state->bempsts &= mod->irq_bempsts; | 232 | state->bempsts &= mod->irq_bempsts; |
| 230 | state->brdysts &= mod->irq_brdysts; | 233 | state->brdysts &= mod->irq_brdysts; |
| 231 | } | 234 | } |
| 235 | usbhs_unlock(priv, flags); | ||
| 236 | /******************** spin unlock ******************/ | ||
| 232 | 237 | ||
| 233 | /* | 238 | /* |
| 234 | * Check whether the irq enable registers and the irq status are set | 239 | * Check whether the irq enable registers and the irq status are set |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 75fbcf6b102e..040bcefcb040 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
| @@ -578,6 +578,19 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe) | |||
| 578 | return usbhsp_flags_has(pipe, IS_DIR_HOST); | 578 | return usbhsp_flags_has(pipe, IS_DIR_HOST); |
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | int usbhs_pipe_is_running(struct usbhs_pipe *pipe) | ||
| 582 | { | ||
| 583 | return usbhsp_flags_has(pipe, IS_RUNNING); | ||
| 584 | } | ||
| 585 | |||
| 586 | void usbhs_pipe_running(struct usbhs_pipe *pipe, int running) | ||
| 587 | { | ||
| 588 | if (running) | ||
| 589 | usbhsp_flags_set(pipe, IS_RUNNING); | ||
| 590 | else | ||
| 591 | usbhsp_flags_clr(pipe, IS_RUNNING); | ||
| 592 | } | ||
| 593 | |||
| 581 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence) | 594 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence) |
| 582 | { | 595 | { |
| 583 | u16 mask = (SQCLR | SQSET); | 596 | u16 mask = (SQCLR | SQSET); |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 406f36d050e4..d24a05972370 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
| @@ -36,6 +36,7 @@ struct usbhs_pipe { | |||
| 36 | #define USBHS_PIPE_FLAGS_IS_USED (1 << 0) | 36 | #define USBHS_PIPE_FLAGS_IS_USED (1 << 0) |
| 37 | #define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1) | 37 | #define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1) |
| 38 | #define USBHS_PIPE_FLAGS_IS_DIR_HOST (1 << 2) | 38 | #define USBHS_PIPE_FLAGS_IS_DIR_HOST (1 << 2) |
| 39 | #define USBHS_PIPE_FLAGS_IS_RUNNING (1 << 3) | ||
| 39 | 40 | ||
| 40 | struct usbhs_pkt_handle *handler; | 41 | struct usbhs_pkt_handle *handler; |
| 41 | 42 | ||
| @@ -80,6 +81,9 @@ int usbhs_pipe_probe(struct usbhs_priv *priv); | |||
| 80 | void usbhs_pipe_remove(struct usbhs_priv *priv); | 81 | void usbhs_pipe_remove(struct usbhs_priv *priv); |
| 81 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); | 82 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); |
| 82 | int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); | 83 | int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); |
| 84 | int usbhs_pipe_is_running(struct usbhs_pipe *pipe); | ||
| 85 | void usbhs_pipe_running(struct usbhs_pipe *pipe, int running); | ||
| 86 | |||
| 83 | void usbhs_pipe_init(struct usbhs_priv *priv, | 87 | void usbhs_pipe_init(struct usbhs_priv *priv, |
| 84 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)); | 88 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)); |
| 85 | int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); | 89 | int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 216ce3078270..dc72b924c399 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -146,6 +146,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 146 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 146 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
| 147 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 147 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
| 148 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 148 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
| 149 | { USB_DEVICE(FTDI_VID, FTDI_BM_ATOM_NANO_PID) }, | ||
| 149 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | 150 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, |
| 150 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, | 151 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, |
| 151 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 152 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
| @@ -727,6 +728,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 727 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), | 728 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), |
| 728 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | 729 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, |
| 729 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 730 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
| 731 | { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) }, | ||
| 730 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, | 732 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, |
| 731 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, | 733 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, |
| 732 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, | 734 | { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, |
| @@ -934,8 +936,12 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 934 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, | 936 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, |
| 935 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, | 937 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, |
| 936 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, | 938 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, |
| 939 | /* ekey Devices */ | ||
| 940 | { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) }, | ||
| 937 | /* Infineon Devices */ | 941 | /* Infineon Devices */ |
| 938 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, | 942 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, |
| 943 | /* GE Healthcare devices */ | ||
| 944 | { USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) }, | ||
| 939 | { } /* Terminating entry */ | 945 | { } /* Terminating entry */ |
| 940 | }; | 946 | }; |
| 941 | 947 | ||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1e58d90a0b6c..5937b2d242f2 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | /* www.candapter.com Ewert Energy Systems CANdapter device */ | 42 | /* www.candapter.com Ewert Energy Systems CANdapter device */ |
| 43 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | 43 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ |
| 44 | 44 | ||
| 45 | #define FTDI_BM_ATOM_NANO_PID 0xa559 /* Basic Micro ATOM Nano USB2Serial */ | ||
| 46 | |||
| 45 | /* | 47 | /* |
| 46 | * Texas Instruments XDS100v2 JTAG / BeagleBone A3 | 48 | * Texas Instruments XDS100v2 JTAG / BeagleBone A3 |
| 47 | * http://processors.wiki.ti.com/index.php/XDS100 | 49 | * http://processors.wiki.ti.com/index.php/XDS100 |
| @@ -835,6 +837,12 @@ | |||
| 835 | #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ | 837 | #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ |
| 836 | 838 | ||
| 837 | /* | 839 | /* |
| 840 | * NOVITUS printers | ||
| 841 | */ | ||
| 842 | #define NOVITUS_VID 0x1a28 | ||
| 843 | #define NOVITUS_BONO_E_PID 0x6010 | ||
| 844 | |||
| 845 | /* | ||
| 838 | * RT Systems programming cables for various ham radios | 846 | * RT Systems programming cables for various ham radios |
| 839 | */ | 847 | */ |
| 840 | #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ | 848 | #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ |
| @@ -1378,3 +1386,14 @@ | |||
| 1378 | #define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ | 1386 | #define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ |
| 1379 | #define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ | 1387 | #define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ |
| 1380 | #define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ | 1388 | #define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ |
| 1389 | |||
| 1390 | /* | ||
| 1391 | * ekey biometric systems GmbH (http://ekey.net/) | ||
| 1392 | */ | ||
| 1393 | #define FTDI_EKEY_CONV_USB_PID 0xCB08 /* Converter USB */ | ||
| 1394 | |||
| 1395 | /* | ||
| 1396 | * GE Healthcare devices | ||
| 1397 | */ | ||
| 1398 | #define GE_HEALTHCARE_VID 0x1901 | ||
| 1399 | #define GE_HEALTHCARE_NEMO_TRACKER_PID 0x0015 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a9688940543d..54a8120897a6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -275,8 +275,12 @@ static void option_instat_callback(struct urb *urb); | |||
| 275 | #define ZTE_PRODUCT_MF622 0x0001 | 275 | #define ZTE_PRODUCT_MF622 0x0001 |
| 276 | #define ZTE_PRODUCT_MF628 0x0015 | 276 | #define ZTE_PRODUCT_MF628 0x0015 |
| 277 | #define ZTE_PRODUCT_MF626 0x0031 | 277 | #define ZTE_PRODUCT_MF626 0x0031 |
| 278 | #define ZTE_PRODUCT_MC2718 0xffe8 | ||
| 279 | #define ZTE_PRODUCT_AC2726 0xfff1 | 278 | #define ZTE_PRODUCT_AC2726 0xfff1 |
| 279 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | ||
| 280 | #define ZTE_PRODUCT_AC8710T 0xffff | ||
| 281 | #define ZTE_PRODUCT_MC2718 0xffe8 | ||
| 282 | #define ZTE_PRODUCT_AD3812 0xffeb | ||
| 283 | #define ZTE_PRODUCT_MC2716 0xffed | ||
| 280 | 284 | ||
| 281 | #define BENQ_VENDOR_ID 0x04a5 | 285 | #define BENQ_VENDOR_ID 0x04a5 |
| 282 | #define BENQ_PRODUCT_H10 0x4068 | 286 | #define BENQ_PRODUCT_H10 0x4068 |
| @@ -494,6 +498,10 @@ static void option_instat_callback(struct urb *urb); | |||
| 494 | #define INOVIA_VENDOR_ID 0x20a6 | 498 | #define INOVIA_VENDOR_ID 0x20a6 |
| 495 | #define INOVIA_SEW858 0x1105 | 499 | #define INOVIA_SEW858 0x1105 |
| 496 | 500 | ||
| 501 | /* VIA Telecom */ | ||
| 502 | #define VIATELECOM_VENDOR_ID 0x15eb | ||
| 503 | #define VIATELECOM_PRODUCT_CDS7 0x0001 | ||
| 504 | |||
| 497 | /* some devices interfaces need special handling due to a number of reasons */ | 505 | /* some devices interfaces need special handling due to a number of reasons */ |
| 498 | enum option_blacklist_reason { | 506 | enum option_blacklist_reason { |
| 499 | OPTION_BLACKLIST_NONE = 0, | 507 | OPTION_BLACKLIST_NONE = 0, |
| @@ -527,10 +535,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { | |||
| 527 | .reserved = BIT(4), | 535 | .reserved = BIT(4), |
| 528 | }; | 536 | }; |
| 529 | 537 | ||
| 538 | static const struct option_blacklist_info zte_ad3812_z_blacklist = { | ||
| 539 | .sendsetup = BIT(0) | BIT(1) | BIT(2), | ||
| 540 | }; | ||
| 541 | |||
| 530 | static const struct option_blacklist_info zte_mc2718_z_blacklist = { | 542 | static const struct option_blacklist_info zte_mc2718_z_blacklist = { |
| 531 | .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), | 543 | .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), |
| 532 | }; | 544 | }; |
| 533 | 545 | ||
| 546 | static const struct option_blacklist_info zte_mc2716_z_blacklist = { | ||
| 547 | .sendsetup = BIT(1) | BIT(2) | BIT(3), | ||
| 548 | }; | ||
| 549 | |||
| 534 | static const struct option_blacklist_info huawei_cdc12_blacklist = { | 550 | static const struct option_blacklist_info huawei_cdc12_blacklist = { |
| 535 | .reserved = BIT(1) | BIT(2), | 551 | .reserved = BIT(1) | BIT(2), |
| 536 | }; | 552 | }; |
| @@ -1070,6 +1086,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 1070 | { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, | 1086 | { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, |
| 1071 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, | 1087 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, |
| 1072 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 1088 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
| 1089 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | ||
| 1073 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 1090 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
| 1074 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ | 1091 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ |
| 1075 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | 1092 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ |
| @@ -1544,13 +1561,18 @@ static const struct usb_device_id option_ids[] = { | |||
| 1544 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, | 1561 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, |
| 1545 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, | 1562 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, |
| 1546 | 1563 | ||
| 1547 | /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */ | 1564 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
| 1565 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
| 1566 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, | ||
| 1548 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), | 1567 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), |
| 1549 | .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, | 1568 | .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, |
| 1569 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), | ||
| 1570 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | ||
| 1571 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | ||
| 1572 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | ||
| 1550 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, | 1573 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, |
| 1551 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, | 1574 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, |
| 1552 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, | 1575 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, |
| 1553 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
| 1554 | 1576 | ||
| 1555 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1577 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
| 1556 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1578 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
| @@ -1724,6 +1746,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 1724 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ | 1746 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ |
| 1725 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ | 1747 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ |
| 1726 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, | 1748 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, |
| 1749 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, | ||
| 1727 | { } /* Terminating entry */ | 1750 | { } /* Terminating entry */ |
| 1728 | }; | 1751 | }; |
| 1729 | MODULE_DEVICE_TABLE(usb, option_ids); | 1752 | MODULE_DEVICE_TABLE(usb, option_ids); |
| @@ -1916,6 +1939,8 @@ static void option_instat_callback(struct urb *urb) | |||
| 1916 | dev_dbg(dev, "%s: type %x req %x\n", __func__, | 1939 | dev_dbg(dev, "%s: type %x req %x\n", __func__, |
| 1917 | req_pkt->bRequestType, req_pkt->bRequest); | 1940 | req_pkt->bRequestType, req_pkt->bRequest); |
| 1918 | } | 1941 | } |
| 1942 | } else if (status == -ENOENT || status == -ESHUTDOWN) { | ||
| 1943 | dev_dbg(dev, "%s: urb stopped: %d\n", __func__, status); | ||
| 1919 | } else | 1944 | } else |
| 1920 | dev_err(dev, "%s: error %d\n", __func__, status); | 1945 | dev_err(dev, "%s: error %d\n", __func__, status); |
| 1921 | 1946 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b3d5a35c0d4b..e9bad928039f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -45,6 +45,7 @@ static const struct usb_device_id id_table[] = { | |||
| 45 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, | 45 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, |
| 46 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, | 46 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, |
| 47 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, | 47 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, |
| 48 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, | ||
| 48 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, | 49 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, |
| 49 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, | 50 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, |
| 50 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, | 51 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 42bc082896ac..71fd9da1d6e7 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #define PL2303_PRODUCT_ID_GPRS 0x0609 | 22 | #define PL2303_PRODUCT_ID_GPRS 0x0609 |
| 23 | #define PL2303_PRODUCT_ID_HCR331 0x331a | 23 | #define PL2303_PRODUCT_ID_HCR331 0x331a |
| 24 | #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 | 24 | #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 |
| 25 | #define PL2303_PRODUCT_ID_ZTEK 0xe1f1 | ||
| 25 | 26 | ||
| 26 | #define ATEN_VENDOR_ID 0x0557 | 27 | #define ATEN_VENDOR_ID 0x0557 |
| 27 | #define ATEN_VENDOR_ID2 0x0547 | 28 | #define ATEN_VENDOR_ID2 0x0547 |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 6f7f01eb556a..46179a0828eb 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -282,14 +282,19 @@ static const struct usb_device_id id_table[] = { | |||
| 282 | /* Sierra Wireless HSPA Non-Composite Device */ | 282 | /* Sierra Wireless HSPA Non-Composite Device */ |
| 283 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, | 283 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, |
| 284 | { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ | 284 | { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ |
| 285 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | 285 | /* Sierra Wireless Direct IP modems */ |
| 286 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68A3, 0xFF, 0xFF, 0xFF), | ||
| 287 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | ||
| 288 | }, | ||
| 289 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), | ||
| 286 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 290 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
| 287 | }, | 291 | }, |
| 288 | /* AT&T Direct IP LTE modems */ | 292 | /* AT&T Direct IP LTE modems */ |
| 289 | { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), | 293 | { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), |
| 290 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 294 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
| 291 | }, | 295 | }, |
| 292 | { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ | 296 | /* Airprime/Sierra Wireless Direct IP modems */ |
| 297 | { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68A3, 0xFF, 0xFF, 0xFF), | ||
| 293 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 298 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
| 294 | }, | 299 | }, |
| 295 | 300 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 02de3110fe94..475723c006f9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -764,29 +764,39 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
| 764 | if (usb_endpoint_is_bulk_in(endpoint)) { | 764 | if (usb_endpoint_is_bulk_in(endpoint)) { |
| 765 | /* we found a bulk in endpoint */ | 765 | /* we found a bulk in endpoint */ |
| 766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); | 766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); |
| 767 | bulk_in_endpoint[num_bulk_in] = endpoint; | 767 | if (num_bulk_in < MAX_NUM_PORTS) { |
| 768 | ++num_bulk_in; | 768 | bulk_in_endpoint[num_bulk_in] = endpoint; |
| 769 | ++num_bulk_in; | ||
| 770 | } | ||
| 769 | } | 771 | } |
| 770 | 772 | ||
| 771 | if (usb_endpoint_is_bulk_out(endpoint)) { | 773 | if (usb_endpoint_is_bulk_out(endpoint)) { |
| 772 | /* we found a bulk out endpoint */ | 774 | /* we found a bulk out endpoint */ |
| 773 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); | 775 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); |
| 774 | bulk_out_endpoint[num_bulk_out] = endpoint; | 776 | if (num_bulk_out < MAX_NUM_PORTS) { |
| 775 | ++num_bulk_out; | 777 | bulk_out_endpoint[num_bulk_out] = endpoint; |
| 778 | ++num_bulk_out; | ||
| 779 | } | ||
| 776 | } | 780 | } |
| 777 | 781 | ||
| 778 | if (usb_endpoint_is_int_in(endpoint)) { | 782 | if (usb_endpoint_is_int_in(endpoint)) { |
| 779 | /* we found a interrupt in endpoint */ | 783 | /* we found a interrupt in endpoint */ |
| 780 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); | 784 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); |
| 781 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 785 | if (num_interrupt_in < MAX_NUM_PORTS) { |
| 782 | ++num_interrupt_in; | 786 | interrupt_in_endpoint[num_interrupt_in] = |
| 787 | endpoint; | ||
| 788 | ++num_interrupt_in; | ||
| 789 | } | ||
| 783 | } | 790 | } |
| 784 | 791 | ||
| 785 | if (usb_endpoint_is_int_out(endpoint)) { | 792 | if (usb_endpoint_is_int_out(endpoint)) { |
| 786 | /* we found an interrupt out endpoint */ | 793 | /* we found an interrupt out endpoint */ |
| 787 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); | 794 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); |
| 788 | interrupt_out_endpoint[num_interrupt_out] = endpoint; | 795 | if (num_interrupt_out < MAX_NUM_PORTS) { |
| 789 | ++num_interrupt_out; | 796 | interrupt_out_endpoint[num_interrupt_out] = |
| 797 | endpoint; | ||
| 798 | ++num_interrupt_out; | ||
| 799 | } | ||
| 790 | } | 800 | } |
| 791 | } | 801 | } |
| 792 | 802 | ||
| @@ -809,8 +819,10 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
| 809 | if (usb_endpoint_is_int_in(endpoint)) { | 819 | if (usb_endpoint_is_int_in(endpoint)) { |
| 810 | /* we found a interrupt in endpoint */ | 820 | /* we found a interrupt in endpoint */ |
| 811 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); | 821 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); |
| 812 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 822 | if (num_interrupt_in < MAX_NUM_PORTS) { |
| 813 | ++num_interrupt_in; | 823 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
| 824 | ++num_interrupt_in; | ||
| 825 | } | ||
| 814 | } | 826 | } |
| 815 | } | 827 | } |
| 816 | } | 828 | } |
| @@ -850,6 +862,11 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
| 850 | num_ports = type->num_ports; | 862 | num_ports = type->num_ports; |
| 851 | } | 863 | } |
| 852 | 864 | ||
| 865 | if (num_ports > MAX_NUM_PORTS) { | ||
| 866 | dev_warn(ddev, "too many ports requested: %d\n", num_ports); | ||
| 867 | num_ports = MAX_NUM_PORTS; | ||
| 868 | } | ||
| 869 | |||
| 853 | serial->num_ports = num_ports; | 870 | serial->num_ports = num_ports; |
| 854 | serial->num_bulk_in = num_bulk_in; | 871 | serial->num_bulk_in = num_bulk_in; |
| 855 | serial->num_bulk_out = num_bulk_out; | 872 | serial->num_bulk_out = num_bulk_out; |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index e62f2dff8b7d..6c3734d2b45a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
| @@ -514,6 +514,10 @@ static void command_port_read_callback(struct urb *urb) | |||
| 514 | dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); | 514 | dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); |
| 515 | return; | 515 | return; |
| 516 | } | 516 | } |
| 517 | if (!urb->actual_length) { | ||
| 518 | dev_dbg(&urb->dev->dev, "%s - empty response, exiting.\n", __func__); | ||
| 519 | return; | ||
| 520 | } | ||
| 517 | if (status) { | 521 | if (status) { |
| 518 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); | 522 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); |
| 519 | if (status != -ENOENT) | 523 | if (status != -ENOENT) |
| @@ -534,7 +538,8 @@ static void command_port_read_callback(struct urb *urb) | |||
| 534 | /* These are unsolicited reports from the firmware, hence no | 538 | /* These are unsolicited reports from the firmware, hence no |
| 535 | waiting command to wakeup */ | 539 | waiting command to wakeup */ |
| 536 | dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); | 540 | dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); |
| 537 | } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { | 541 | } else if ((data[0] == WHITEHEAT_GET_DTR_RTS) && |
| 542 | (urb->actual_length - 1 <= sizeof(command_info->result_buffer))) { | ||
| 538 | memcpy(command_info->result_buffer, &data[1], | 543 | memcpy(command_info->result_buffer, &data[1], |
| 539 | urb->actual_length - 1); | 544 | urb->actual_length - 1); |
| 540 | command_info->command_finished = WHITEHEAT_CMD_COMPLETE; | 545 | command_info->command_finished = WHITEHEAT_CMD_COMPLETE; |
diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index e40ab739c4a6..c9bb107d5e5c 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c | |||
| @@ -272,28 +272,16 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | static const struct usb_device_id id_table[] = { | 274 | static const struct usb_device_id id_table[] = { |
| 275 | /* AC8710, AC8710T */ | 275 | { USB_DEVICE(0x19d2, 0xffec) }, |
| 276 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) }, | 276 | { USB_DEVICE(0x19d2, 0xffee) }, |
| 277 | /* AC8700 */ | ||
| 278 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) }, | ||
| 279 | /* MG880 */ | ||
| 280 | { USB_DEVICE(0x19d2, 0xfffd) }, | ||
| 281 | { USB_DEVICE(0x19d2, 0xfffc) }, | ||
| 282 | { USB_DEVICE(0x19d2, 0xfffb) }, | ||
| 283 | /* AC8710_V3 */ | ||
| 284 | { USB_DEVICE(0x19d2, 0xfff6) }, | 277 | { USB_DEVICE(0x19d2, 0xfff6) }, |
| 285 | { USB_DEVICE(0x19d2, 0xfff7) }, | 278 | { USB_DEVICE(0x19d2, 0xfff7) }, |
| 286 | { USB_DEVICE(0x19d2, 0xfff8) }, | 279 | { USB_DEVICE(0x19d2, 0xfff8) }, |
| 287 | { USB_DEVICE(0x19d2, 0xfff9) }, | 280 | { USB_DEVICE(0x19d2, 0xfff9) }, |
| 288 | { USB_DEVICE(0x19d2, 0xffee) }, | 281 | { USB_DEVICE(0x19d2, 0xfffb) }, |
| 289 | /* AC2716, MC2716 */ | 282 | { USB_DEVICE(0x19d2, 0xfffc) }, |
| 290 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) }, | 283 | /* MG880 */ |
| 291 | /* AD3812 */ | 284 | { USB_DEVICE(0x19d2, 0xfffd) }, |
| 292 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) }, | ||
| 293 | { USB_DEVICE(0x19d2, 0xffec) }, | ||
| 294 | { USB_DEVICE(0x05C6, 0x3197) }, | ||
| 295 | { USB_DEVICE(0x05C6, 0x6000) }, | ||
| 296 | { USB_DEVICE(0x05C6, 0x9008) }, | ||
| 297 | { }, | 285 | { }, |
| 298 | }; | 286 | }; |
| 299 | MODULE_DEVICE_TABLE(usb, id_table); | 287 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 503ac5c8d80f..8a6f371ed6e7 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h | |||
| @@ -59,10 +59,6 @@ static int uas_use_uas_driver(struct usb_interface *intf, | |||
| 59 | unsigned long flags = id->driver_info; | 59 | unsigned long flags = id->driver_info; |
| 60 | int r, alt; | 60 | int r, alt; |
| 61 | 61 | ||
| 62 | usb_stor_adjust_quirks(udev, &flags); | ||
| 63 | |||
| 64 | if (flags & US_FL_IGNORE_UAS) | ||
| 65 | return 0; | ||
| 66 | 62 | ||
| 67 | alt = uas_find_uas_alt_setting(intf); | 63 | alt = uas_find_uas_alt_setting(intf); |
| 68 | if (alt < 0) | 64 | if (alt < 0) |
| @@ -72,6 +68,29 @@ static int uas_use_uas_driver(struct usb_interface *intf, | |||
| 72 | if (r < 0) | 68 | if (r < 0) |
| 73 | return 0; | 69 | return 0; |
| 74 | 70 | ||
| 71 | /* | ||
| 72 | * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is | ||
| 73 | * broken on the ASM1051, use the number of streams to differentiate. | ||
| 74 | * New ASM1053-s also support 32 streams, but have a different prod-id. | ||
| 75 | */ | ||
| 76 | if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && | ||
| 77 | le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) { | ||
| 78 | if (udev->speed < USB_SPEED_SUPER) { | ||
| 79 | /* No streams info, assume ASM1051 */ | ||
| 80 | flags |= US_FL_IGNORE_UAS; | ||
| 81 | } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { | ||
| 82 | flags |= US_FL_IGNORE_UAS; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | usb_stor_adjust_quirks(udev, &flags); | ||
| 87 | |||
| 88 | if (flags & US_FL_IGNORE_UAS) { | ||
| 89 | dev_warn(&udev->dev, | ||
| 90 | "UAS is blacklisted for this device, using usb-storage instead\n"); | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 75 | if (udev->bus->sg_tablesize == 0) { | 94 | if (udev->bus->sg_tablesize == 0) { |
| 76 | dev_warn(&udev->dev, | 95 | dev_warn(&udev->dev, |
| 77 | "The driver for the USB controller %s does not support scatter-gather which is\n", | 96 | "The driver for the USB controller %s does not support scatter-gather which is\n", |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 80a5b366255f..60cfcbc78552 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -741,6 +741,12 @@ UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100, | |||
| 741 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 741 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 742 | US_FL_SINGLE_LUN ), | 742 | US_FL_SINGLE_LUN ), |
| 743 | 743 | ||
| 744 | UNUSUAL_DEV( 0x059b, 0x0040, 0x0100, 0x0100, | ||
| 745 | "Iomega", | ||
| 746 | "Jaz USB Adapter", | ||
| 747 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 748 | US_FL_SINGLE_LUN ), | ||
| 749 | |||
| 744 | /* Reported by <Hendryk.Pfeiffer@gmx.de> */ | 750 | /* Reported by <Hendryk.Pfeiffer@gmx.de> */ |
| 745 | UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, | 751 | UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, |
| 746 | "LaCie", | 752 | "LaCie", |
| @@ -922,6 +928,12 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, | |||
| 922 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 928 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 923 | US_FL_FIX_CAPACITY ), | 929 | US_FL_FIX_CAPACITY ), |
| 924 | 930 | ||
| 931 | UNUSUAL_DEV( 0x06ca, 0x2003, 0x0100, 0x0100, | ||
| 932 | "Newer Technology", | ||
| 933 | "uSCSI", | ||
| 934 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, | ||
| 935 | US_FL_SCM_MULT_TARG ), | ||
| 936 | |||
| 925 | /* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ | 937 | /* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ |
| 926 | UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, | 938 | UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, |
| 927 | "RockChip", | 939 | "RockChip", |
diff --git a/drivers/staging/usbip/Kconfig b/drivers/usb/usbip/Kconfig index bd99e9e47e50..bd99e9e47e50 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig | |||
diff --git a/drivers/staging/usbip/Makefile b/drivers/usb/usbip/Makefile index 9ecd61545be1..9ecd61545be1 100644 --- a/drivers/staging/usbip/Makefile +++ b/drivers/usb/usbip/Makefile | |||
diff --git a/drivers/staging/usbip/README b/drivers/usb/usbip/README index 41a2cf2e77a6..41a2cf2e77a6 100644 --- a/drivers/staging/usbip/README +++ b/drivers/usb/usbip/README | |||
diff --git a/drivers/staging/usbip/stub.h b/drivers/usb/usbip/stub.h index 266e2b0ce9a8..266e2b0ce9a8 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/usb/usbip/stub.h | |||
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 51d0c7188738..fac20e0434c0 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c | |||
| @@ -26,33 +26,6 @@ | |||
| 26 | #include "stub.h" | 26 | #include "stub.h" |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * Define device IDs here if you want to explicitly limit exportable devices. | ||
| 30 | * In most cases, wildcard matching will be okay because driver binding can be | ||
| 31 | * changed dynamically by a userland program. | ||
| 32 | */ | ||
| 33 | static struct usb_device_id stub_table[] = { | ||
| 34 | #if 0 | ||
| 35 | /* just an example */ | ||
| 36 | { USB_DEVICE(0x05ac, 0x0301) }, /* Mac 1 button mouse */ | ||
| 37 | { USB_DEVICE(0x0430, 0x0009) }, /* Plat Home Keyboard */ | ||
| 38 | { USB_DEVICE(0x059b, 0x0001) }, /* Iomega USB Zip 100 */ | ||
| 39 | { USB_DEVICE(0x04b3, 0x4427) }, /* IBM USB CD-ROM */ | ||
| 40 | { USB_DEVICE(0x05a9, 0xa511) }, /* LifeView USB cam */ | ||
| 41 | { USB_DEVICE(0x55aa, 0x0201) }, /* Imation card reader */ | ||
| 42 | { USB_DEVICE(0x046d, 0x0870) }, /* Qcam Express(QV-30) */ | ||
| 43 | { USB_DEVICE(0x04bb, 0x0101) }, /* IO-DATA HD 120GB */ | ||
| 44 | { USB_DEVICE(0x04bb, 0x0904) }, /* IO-DATA USB-ET/TX */ | ||
| 45 | { USB_DEVICE(0x04bb, 0x0201) }, /* IO-DATA USB-ET/TX */ | ||
| 46 | { USB_DEVICE(0x08bb, 0x2702) }, /* ONKYO USB Speaker */ | ||
| 47 | { USB_DEVICE(0x046d, 0x08b2) }, /* Logicool Qcam 4000 Pro */ | ||
| 48 | #endif | ||
| 49 | /* magic for wild card */ | ||
| 50 | { .driver_info = 1 }, | ||
| 51 | { 0, } /* Terminating entry */ | ||
| 52 | }; | ||
| 53 | MODULE_DEVICE_TABLE(usb, stub_table); | ||
| 54 | |||
| 55 | /* | ||
| 56 | * usbip_status shows the status of usbip-host as long as this driver is bound | 29 | * usbip_status shows the status of usbip-host as long as this driver is bound |
| 57 | * to the target device. | 30 | * to the target device. |
| 58 | */ | 31 | */ |
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 44ab43fc4fcc..44ab43fc4fcc 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c | |||
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 00e475c51a12..00e475c51a12 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c | |||
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index dbcabc9dbe0d..dbcabc9dbe0d 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c | |||
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index facaaf003f19..facaaf003f19 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c | |||
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index 4da3866a037d..86b08475c254 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| 30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
| 31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
| 32 | #include "uapi/usbip.h" | 32 | #include <uapi/linux/usbip.h> |
| 33 | 33 | ||
| 34 | #define USBIP_VERSION "1.0.0" | 34 | #define USBIP_VERSION "1.0.0" |
| 35 | 35 | ||
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c index 64933b993d7a..64933b993d7a 100644 --- a/drivers/staging/usbip/usbip_event.c +++ b/drivers/usb/usbip/usbip_event.c | |||
diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/usb/usbip/usbip_protocol.txt index 16b6fe27284c..16b6fe27284c 100644 --- a/drivers/staging/usbip/usbip_protocol.txt +++ b/drivers/usb/usbip/usbip_protocol.txt | |||
diff --git a/drivers/staging/usbip/vhci.h b/drivers/usb/usbip/vhci.h index a863a98a91ce..a863a98a91ce 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h | |||
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c02374b6049c..c02374b6049c 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index 00e4a54308e4..00e4a54308e4 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c | |||
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 211f43f67ea2..211f43f67ea2 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c | |||
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index 409fd99f3257..409fd99f3257 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c | |||
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 3e2e4ed20157..e279015be466 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
| @@ -2602,6 +2602,7 @@ static void wa_buf_in_cb(struct urb *urb) | |||
| 2602 | dev = &wa->usb_iface->dev; | 2602 | dev = &wa->usb_iface->dev; |
| 2603 | --(wa->active_buf_in_urbs); | 2603 | --(wa->active_buf_in_urbs); |
| 2604 | active_buf_in_urbs = wa->active_buf_in_urbs; | 2604 | active_buf_in_urbs = wa->active_buf_in_urbs; |
| 2605 | rpipe = xfer->ep->hcpriv; | ||
| 2605 | 2606 | ||
| 2606 | if (usb_pipeisoc(xfer->urb->pipe)) { | 2607 | if (usb_pipeisoc(xfer->urb->pipe)) { |
| 2607 | struct usb_iso_packet_descriptor *iso_frame_desc = | 2608 | struct usb_iso_packet_descriptor *iso_frame_desc = |
| @@ -2659,7 +2660,6 @@ static void wa_buf_in_cb(struct urb *urb) | |||
| 2659 | resubmit_dti = (isoc_data_frame_count == | 2660 | resubmit_dti = (isoc_data_frame_count == |
| 2660 | urb_frame_count); | 2661 | urb_frame_count); |
| 2661 | } else if (active_buf_in_urbs == 0) { | 2662 | } else if (active_buf_in_urbs == 0) { |
| 2662 | rpipe = xfer->ep->hcpriv; | ||
| 2663 | dev_dbg(dev, | 2663 | dev_dbg(dev, |
| 2664 | "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", | 2664 | "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", |
| 2665 | xfer, wa_xfer_id(xfer), seg->index, | 2665 | xfer, wa_xfer_id(xfer), seg->index, |
| @@ -2685,7 +2685,6 @@ static void wa_buf_in_cb(struct urb *urb) | |||
| 2685 | */ | 2685 | */ |
| 2686 | resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; | 2686 | resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; |
| 2687 | spin_lock_irqsave(&xfer->lock, flags); | 2687 | spin_lock_irqsave(&xfer->lock, flags); |
| 2688 | rpipe = xfer->ep->hcpriv; | ||
| 2689 | if (printk_ratelimit()) | 2688 | if (printk_ratelimit()) |
| 2690 | dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", | 2689 | dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", |
| 2691 | xfer, wa_xfer_id(xfer), seg->index, | 2690 | xfer, wa_xfer_id(xfer), seg->index, |
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c index 80079b8fed15..d0303f0dbe15 100644 --- a/drivers/uwb/lc-dev.c +++ b/drivers/uwb/lc-dev.c | |||
| @@ -431,16 +431,19 @@ void uwbd_dev_onair(struct uwb_rc *rc, struct uwb_beca_e *bce) | |||
| 431 | uwb_dev->mac_addr = *bce->mac_addr; | 431 | uwb_dev->mac_addr = *bce->mac_addr; |
| 432 | uwb_dev->dev_addr = bce->dev_addr; | 432 | uwb_dev->dev_addr = bce->dev_addr; |
| 433 | dev_set_name(&uwb_dev->dev, "%s", macbuf); | 433 | dev_set_name(&uwb_dev->dev, "%s", macbuf); |
| 434 | |||
| 435 | /* plug the beacon cache */ | ||
| 436 | bce->uwb_dev = uwb_dev; | ||
| 437 | uwb_dev->bce = bce; | ||
| 438 | uwb_bce_get(bce); /* released in uwb_dev_sys_release() */ | ||
| 439 | |||
| 434 | result = uwb_dev_add(uwb_dev, &rc->uwb_dev.dev, rc); | 440 | result = uwb_dev_add(uwb_dev, &rc->uwb_dev.dev, rc); |
| 435 | if (result < 0) { | 441 | if (result < 0) { |
| 436 | dev_err(dev, "new device %s: cannot instantiate device\n", | 442 | dev_err(dev, "new device %s: cannot instantiate device\n", |
| 437 | macbuf); | 443 | macbuf); |
| 438 | goto error_dev_add; | 444 | goto error_dev_add; |
| 439 | } | 445 | } |
| 440 | /* plug the beacon cache */ | 446 | |
| 441 | bce->uwb_dev = uwb_dev; | ||
| 442 | uwb_dev->bce = bce; | ||
| 443 | uwb_bce_get(bce); /* released in uwb_dev_sys_release() */ | ||
| 444 | dev_info(dev, "uwb device (mac %s dev %s) connected to %s %s\n", | 447 | dev_info(dev, "uwb device (mac %s dev %s) connected to %s %s\n", |
| 445 | macbuf, devbuf, rc->uwb_dev.dev.parent->bus->name, | 448 | macbuf, devbuf, rc->uwb_dev.dev.parent->bus->name, |
| 446 | dev_name(rc->uwb_dev.dev.parent)); | 449 | dev_name(rc->uwb_dev.dev.parent)); |
| @@ -448,6 +451,8 @@ void uwbd_dev_onair(struct uwb_rc *rc, struct uwb_beca_e *bce) | |||
| 448 | return; | 451 | return; |
| 449 | 452 | ||
| 450 | error_dev_add: | 453 | error_dev_add: |
| 454 | bce->uwb_dev = NULL; | ||
| 455 | uwb_bce_put(bce); | ||
| 451 | kfree(uwb_dev); | 456 | kfree(uwb_dev); |
| 452 | return; | 457 | return; |
| 453 | } | 458 | } |
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index d7a3d13e72ec..b85983e97f0a 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
| @@ -173,6 +173,7 @@ static int pwm_backlight_parse_dt(struct device *dev, | |||
| 173 | data->max_brightness--; | 173 | data->max_brightness--; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | data->enable_gpio = -EINVAL; | ||
| 176 | return 0; | 177 | return 0; |
| 177 | } | 178 | } |
| 178 | 179 | ||
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index beadd3edaa17..6ad23bd3523a 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/clcd.h> | 26 | #include <linux/amba/clcd.h> |
| 27 | #include <linux/bitops.h> | ||
| 27 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
| 28 | #include <linux/hardirq.h> | 29 | #include <linux/hardirq.h> |
| 29 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
| @@ -638,9 +639,7 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0) | |||
| 638 | if (g0 != panels[i].g0) | 639 | if (g0 != panels[i].g0) |
| 639 | continue; | 640 | continue; |
| 640 | if (r0 == panels[i].r0 && b0 == panels[i].b0) | 641 | if (r0 == panels[i].r0 && b0 == panels[i].b0) |
| 641 | fb->panel->caps = panels[i].caps & CLCD_CAP_RGB; | 642 | fb->panel->caps = panels[i].caps; |
| 642 | if (r0 == panels[i].b0 && b0 == panels[i].r0) | ||
| 643 | fb->panel->caps = panels[i].caps & CLCD_CAP_BGR; | ||
| 644 | } | 643 | } |
| 645 | 644 | ||
| 646 | return fb->panel->caps ? 0 : -EINVAL; | 645 | return fb->panel->caps ? 0 : -EINVAL; |
| @@ -650,6 +649,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) | |||
| 650 | { | 649 | { |
| 651 | struct device_node *endpoint; | 650 | struct device_node *endpoint; |
| 652 | int err; | 651 | int err; |
| 652 | unsigned int bpp; | ||
| 653 | u32 max_bandwidth; | 653 | u32 max_bandwidth; |
| 654 | u32 tft_r0b0g0[3]; | 654 | u32 tft_r0b0g0[3]; |
| 655 | 655 | ||
| @@ -667,11 +667,22 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) | |||
| 667 | 667 | ||
| 668 | err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", | 668 | err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", |
| 669 | &max_bandwidth); | 669 | &max_bandwidth); |
| 670 | if (!err) | 670 | if (!err) { |
| 671 | fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres * | 671 | /* |
| 672 | fb->panel->mode.yres * fb->panel->mode.refresh); | 672 | * max_bandwidth is in bytes per second and pixclock in |
| 673 | else | 673 | * pico-seconds, so the maximum allowed bits per pixel is |
| 674 | fb->panel->bpp = 32; | 674 | * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000) |
| 675 | * Rearrange this calculation to avoid overflow and then ensure | ||
| 676 | * result is a valid format. | ||
| 677 | */ | ||
| 678 | bpp = max_bandwidth / (1000 / 8) | ||
| 679 | / PICOS2KHZ(fb->panel->mode.pixclock); | ||
| 680 | bpp = rounddown_pow_of_two(bpp); | ||
| 681 | if (bpp > 32) | ||
| 682 | bpp = 32; | ||
| 683 | } else | ||
| 684 | bpp = 32; | ||
| 685 | fb->panel->bpp = bpp; | ||
| 675 | 686 | ||
| 676 | #ifdef CONFIG_CPU_BIG_ENDIAN | 687 | #ifdef CONFIG_CPU_BIG_ENDIAN |
| 677 | fb->panel->cntl |= CNTL_BEBO; | 688 | fb->panel->cntl |= CNTL_BEBO; |
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 92640d46770a..1d8bdb92939b 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c | |||
| @@ -1102,12 +1102,14 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) | |||
| 1102 | timings = of_get_display_timings(display_np); | 1102 | timings = of_get_display_timings(display_np); |
| 1103 | if (!timings) { | 1103 | if (!timings) { |
| 1104 | dev_err(dev, "failed to get display timings\n"); | 1104 | dev_err(dev, "failed to get display timings\n"); |
| 1105 | ret = -EINVAL; | ||
| 1105 | goto put_display_node; | 1106 | goto put_display_node; |
| 1106 | } | 1107 | } |
| 1107 | 1108 | ||
| 1108 | timings_np = of_find_node_by_name(display_np, "display-timings"); | 1109 | timings_np = of_find_node_by_name(display_np, "display-timings"); |
| 1109 | if (!timings_np) { | 1110 | if (!timings_np) { |
| 1110 | dev_err(dev, "failed to find display-timings node\n"); | 1111 | dev_err(dev, "failed to find display-timings node\n"); |
| 1112 | ret = -ENODEV; | ||
| 1111 | goto put_display_node; | 1113 | goto put_display_node; |
| 1112 | } | 1114 | } |
| 1113 | 1115 | ||
diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 206a66b61072..59abdc6a97f6 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c | |||
| @@ -273,7 +273,7 @@ static struct chips_init_reg chips_init_xr[] = { | |||
| 273 | { 0xa8, 0x00 } | 273 | { 0xa8, 0x00 } |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | static void __init chips_hw_init(void) | 276 | static void chips_hw_init(void) |
| 277 | { | 277 | { |
| 278 | int i; | 278 | int i; |
| 279 | 279 | ||
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index 788f6b37fce7..10c876c95772 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c | |||
| @@ -419,7 +419,7 @@ static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, | |||
| 419 | { | 419 | { |
| 420 | u32 reg; | 420 | u32 reg; |
| 421 | 421 | ||
| 422 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; | 422 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0x3ff; |
| 423 | reg |= (((back_porch-1) & 0xff) << 24) | 423 | reg |= (((back_porch-1) & 0xff) << 24) |
| 424 | | (((front_porch-1) & 0xff) << 16) | 424 | | (((front_porch-1) & 0xff) << 16) |
| 425 | | (((pulse_width-1) & 0x3f) << 10); | 425 | | (((pulse_width-1) & 0x3f) << 10); |
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 987edf110038..5c098d5b4043 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c | |||
| @@ -236,6 +236,7 @@ timingfail: | |||
| 236 | if (native_mode) | 236 | if (native_mode) |
| 237 | of_node_put(native_mode); | 237 | of_node_put(native_mode); |
| 238 | display_timings_release(disp); | 238 | display_timings_release(disp); |
| 239 | disp = NULL; | ||
| 239 | entryfail: | 240 | entryfail: |
| 240 | kfree(disp); | 241 | kfree(disp); |
| 241 | dispfail: | 242 | dispfail: |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 5c660c77f03b..1e0a317d3dcd 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -230,8 +230,8 @@ static enum bp_state reserve_additional_memory(long credit) | |||
| 230 | rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT); | 230 | rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT); |
| 231 | 231 | ||
| 232 | if (rc) { | 232 | if (rc) { |
| 233 | pr_info("%s: add_memory() failed: %i\n", __func__, rc); | 233 | pr_warn("Cannot add additional memory (%i)\n", rc); |
| 234 | return BP_EAGAIN; | 234 | return BP_ECANCELED; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | balloon_hotplug -= credit; | 237 | balloon_hotplug -= credit; |
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index 787d17945418..e53fe191738c 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c | |||
| @@ -124,7 +124,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, | |||
| 124 | int i, rc, readonly; | 124 | int i, rc, readonly; |
| 125 | LIST_HEAD(queue_gref); | 125 | LIST_HEAD(queue_gref); |
| 126 | LIST_HEAD(queue_file); | 126 | LIST_HEAD(queue_file); |
| 127 | struct gntalloc_gref *gref; | 127 | struct gntalloc_gref *gref, *next; |
| 128 | 128 | ||
| 129 | readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE); | 129 | readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE); |
| 130 | rc = -ENOMEM; | 130 | rc = -ENOMEM; |
| @@ -141,13 +141,11 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, | |||
| 141 | goto undo; | 141 | goto undo; |
| 142 | 142 | ||
| 143 | /* Grant foreign access to the page. */ | 143 | /* Grant foreign access to the page. */ |
| 144 | gref->gref_id = gnttab_grant_foreign_access(op->domid, | 144 | rc = gnttab_grant_foreign_access(op->domid, |
| 145 | pfn_to_mfn(page_to_pfn(gref->page)), readonly); | 145 | pfn_to_mfn(page_to_pfn(gref->page)), readonly); |
| 146 | if ((int)gref->gref_id < 0) { | 146 | if (rc < 0) |
| 147 | rc = gref->gref_id; | ||
| 148 | goto undo; | 147 | goto undo; |
| 149 | } | 148 | gref_ids[i] = gref->gref_id = rc; |
| 150 | gref_ids[i] = gref->gref_id; | ||
| 151 | } | 149 | } |
| 152 | 150 | ||
| 153 | /* Add to gref lists. */ | 151 | /* Add to gref lists. */ |
| @@ -162,8 +160,8 @@ undo: | |||
| 162 | mutex_lock(&gref_mutex); | 160 | mutex_lock(&gref_mutex); |
| 163 | gref_size -= (op->count - i); | 161 | gref_size -= (op->count - i); |
| 164 | 162 | ||
| 165 | list_for_each_entry(gref, &queue_file, next_file) { | 163 | list_for_each_entry_safe(gref, next, &queue_file, next_file) { |
| 166 | /* __del_gref does not remove from queue_file */ | 164 | list_del(&gref->next_file); |
| 167 | __del_gref(gref); | 165 | __del_gref(gref); |
| 168 | } | 166 | } |
| 169 | 167 | ||
| @@ -193,7 +191,7 @@ static void __del_gref(struct gntalloc_gref *gref) | |||
| 193 | 191 | ||
| 194 | gref->notify.flags = 0; | 192 | gref->notify.flags = 0; |
| 195 | 193 | ||
| 196 | if (gref->gref_id > 0) { | 194 | if (gref->gref_id) { |
| 197 | if (gnttab_query_foreign_access(gref->gref_id)) | 195 | if (gnttab_query_foreign_access(gref->gref_id)) |
| 198 | return; | 196 | return; |
| 199 | 197 | ||
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5f1e1f3cd186..f8bb36f9d9ce 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
| @@ -103,16 +103,11 @@ static void do_suspend(void) | |||
| 103 | 103 | ||
| 104 | shutting_down = SHUTDOWN_SUSPEND; | 104 | shutting_down = SHUTDOWN_SUSPEND; |
| 105 | 105 | ||
| 106 | #ifdef CONFIG_PREEMPT | ||
| 107 | /* If the kernel is preemptible, we need to freeze all the processes | ||
| 108 | to prevent them from being in the middle of a pagetable update | ||
| 109 | during suspend. */ | ||
| 110 | err = freeze_processes(); | 106 | err = freeze_processes(); |
| 111 | if (err) { | 107 | if (err) { |
| 112 | pr_err("%s: freeze failed %d\n", __func__, err); | 108 | pr_err("%s: freeze failed %d\n", __func__, err); |
| 113 | goto out; | 109 | goto out; |
| 114 | } | 110 | } |
| 115 | #endif | ||
| 116 | 111 | ||
| 117 | err = dpm_suspend_start(PMSG_FREEZE); | 112 | err = dpm_suspend_start(PMSG_FREEZE); |
| 118 | if (err) { | 113 | if (err) { |
| @@ -157,10 +152,8 @@ out_resume: | |||
| 157 | dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); | 152 | dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); |
| 158 | 153 | ||
| 159 | out_thaw: | 154 | out_thaw: |
| 160 | #ifdef CONFIG_PREEMPT | ||
| 161 | thaw_processes(); | 155 | thaw_processes(); |
| 162 | out: | 156 | out: |
| 163 | #endif | ||
| 164 | shutting_down = SHUTDOWN_INVALID; | 157 | shutting_down = SHUTDOWN_INVALID; |
| 165 | } | 158 | } |
| 166 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ | 159 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
